summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kbuild17
-rw-r--r--core/cds/inc/cds_api.h40
-rw-r--r--core/cds/inc/cds_config.h8
-rw-r--r--core/cds/src/cds_concurrency.c11
-rw-r--r--core/dp/htt/htt_rx.c8
-rw-r--r--core/dp/txrx/ol_txrx_peer_find.c3
-rw-r--r--core/hdd/inc/wlan_hdd_assoc.h10
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h74
-rw-r--r--core/hdd/inc/wlan_hdd_main.h18
-rw-r--r--core/hdd/inc/wlan_hdd_power.h68
-rw-r--r--core/hdd/src/wlan_hdd_apf.c3
-rw-r--r--core/hdd/src/wlan_hdd_assoc.c39
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c50
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c20
-rw-r--r--core/hdd/src/wlan_hdd_driver_ops.c57
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c13
-rw-r--r--core/hdd/src/wlan_hdd_ioctl.c12
-rw-r--r--core/hdd/src/wlan_hdd_main.c118
-rw-r--r--core/hdd/src/wlan_hdd_power.c141
-rw-r--r--core/hdd/src/wlan_hdd_regulatory.c19
-rw-r--r--core/mac/inc/qwlan_version.h6
-rw-r--r--core/mac/inc/sir_api.h1
-rw-r--r--core/mac/src/pe/include/lim_session.h3
-rw-r--r--core/mac/src/pe/lim/lim_api.c3
-rw-r--r--core/mac/src/pe/lim/lim_process_sme_req_messages.c5
-rw-r--r--core/mac/src/pe/lim/lim_send_messages.c4
-rw-r--r--core/mac/src/pe/lim/lim_send_sme_rsp_messages.c3
-rw-r--r--core/mac/src/pe/lim/lim_session.c5
-rw-r--r--core/pld/inc/pld_common.h35
-rw-r--r--core/pld/src/pld_common.c38
-rw-r--r--core/pld/src/pld_snoc.c34
-rw-r--r--core/sme/inc/csr_api.h2
-rw-r--r--core/sme/inc/csr_internal.h1
-rw-r--r--core/sme/inc/csr_neighbor_roam.h44
-rw-r--r--core/sme/src/common/sme_api.c1
-rw-r--r--core/sme/src/csr/csr_api_roam.c73
-rw-r--r--core/sme/src/csr/csr_util.c3
-rw-r--r--core/wma/inc/wma.h9
-rw-r--r--core/wma/inc/wma_api.h16
-rw-r--r--core/wma/inc/wma_if.h17
-rw-r--r--core/wma/inc/wma_internal.h36
-rw-r--r--core/wma/inc/wma_types.h8
-rw-r--r--core/wma/src/wma_dev_if.c29
-rw-r--r--core/wma/src/wma_features.c14
-rw-r--r--core/wma/src/wma_main.c28
-rw-r--r--core/wma/src/wma_mgmt.c7
-rw-r--r--core/wma/src/wma_scan_roam.c104
-rw-r--r--core/wma/src/wma_thermal.c85
-rw-r--r--core/wma/src/wma_utils.c3
49 files changed, 1272 insertions, 74 deletions
diff --git a/Kbuild b/Kbuild
index 39f0e177480b..14a960c24aa4 100644
--- a/Kbuild
+++ b/Kbuild
@@ -116,6 +116,8 @@ ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SDM660), y)
CONFIG_QCACLD_FEATURE_METERING := y
+ #Flag to enable FIPS
+ CONFIG_WLAN_FEATURE_FIPS := y
endif
ifeq ($(CONFIG_ARCH_SDM630), y)
@@ -297,6 +299,9 @@ endif
#Enable beacon reporting feature
CONFIG_WLAN_BEACON_REPORTING := y
+#Enable/Disable FW thermal mitigation feature
+CONFIG_WLAN_FW_THERMAL_MITIGATION := n
+
# Feature flags which are not (currently) configurable via Kconfig
#Whether to build debug version
@@ -1159,6 +1164,10 @@ ifeq ($(CONFIG_MPC_UT_FRAMEWORK),y)
WMA_OBJS += $(WMA_SRC_DIR)/wma_utils_ut.o
endif
+ifeq ($(CONFIG_WLAN_FW_THERMAL_MITIGATION), y)
+WMA_OBJS += $(WMA_SRC_DIR)/wma_thermal.o
+endif
+
############## PLD ##########
PLD_DIR := core/pld
PLD_INC_DIR := $(PLD_DIR)/inc
@@ -1311,6 +1320,10 @@ CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \
-DCONFIG_HDD_INIT_WITH_RTNL_LOCK \
-DMWS_COEX
+ifeq ($(CONFIG_WLAN_FEATURE_FIPS), y)
+CDEFINES += -DWLAN_FEATURE_FIPS
+endif
+
ifneq ($(CONFIG_HIF_USB), 1)
CDEFINES += -DWLAN_LOGGING_SOCK_SVC_ENABLE
endif
@@ -1469,6 +1482,10 @@ ifeq ($(CONFIG_WLAN_BEACON_REPORTING),y)
CDEFINES += -DNTH_BEACON_OFFLOAD
endif
+ifeq ($(CONFIG_WLAN_FW_THERMAL_MITIGATION),y)
+CDEFINES += -DFW_THERMAL_THROTTLE_SUPPORT
+endif
+
ifeq ($(BUILD_DIAG_VERSION),1)
CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT
CDEFINES += -DFEATURE_WLAN_DIAG_SUPPORT_CSR
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
index a83ead34cf01..76ce3953abfe 100644
--- a/core/cds/inc/cds_api.h
+++ b/core/cds/inc/cds_api.h
@@ -57,6 +57,7 @@
* CDS_DRIVER_STATE_BAD: Driver in bad state.
* CDS_DRIVER_STATE_FW_READY:
* CDS_DRIVER_STATE_MODULE_STOPPING: Module stop in progress.
+* CDS_DRIVER_STATE_THERMAL_STATE: Driver in thermal mitigated state
*/
enum cds_driver_state {
CDS_DRIVER_STATE_UNINITIALIZED = 0,
@@ -67,6 +68,7 @@ CDS_DRIVER_STATE_RECOVERING = BIT(3),
CDS_DRIVER_STATE_BAD = BIT(4),
CDS_DRIVER_STATE_FW_READY = BIT(5),
CDS_DRIVER_STATE_MODULE_STOPPING = BIT(6),
+CDS_DRIVER_STATE_THERMAL_STATE = BIT(7),
};
#define __CDS_IS_DRIVER_STATE(_state, _mask) (((_state) & (_mask)) == (_mask))
@@ -371,6 +373,44 @@ enum cds_driver_state state = cds_get_driver_state();
return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_LOADED);
}
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * cds_set_driver_thermal_mitigated() - Setting the flag to indicate that driver
+ * is in thermal mitigation state.
+ *
+ * @value: A boolean value to indicate to set or reset
+ *
+ * Return: None
+ */
+static inline void cds_set_driver_thermal_mitigated(bool value)
+{
+ if (value)
+ cds_set_driver_state(CDS_DRIVER_STATE_THERMAL_STATE);
+ else
+ cds_clear_driver_state(CDS_DRIVER_STATE_THERMAL_STATE);
+}
+
+/**
+ * cds_is_driver_thermal_mitigated() - Check if driver is in power save state
+ *
+ * Return: True if in power save state, false otherwise
+ */
+static inline bool cds_is_driver_thermal_mitigated(void)
+{
+ enum cds_driver_state state = cds_get_driver_state();
+
+ return __CDS_IS_DRIVER_STATE(state, CDS_DRIVER_STATE_THERMAL_STATE);
+}
+#else
+static inline void cds_set_driver_thermal_mitigated(bool value)
+{
+}
+
+static inline bool cds_is_driver_thermal_mitigated(void)
+{
+ return false;
+}
+#endif
v_CONTEXT_t cds_init(void);
void cds_deinit(void);
diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h
index e311a2d32b22..9530deef7c7e 100644
--- a/core/cds/inc/cds_config.h
+++ b/core/cds/inc/cds_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -156,6 +156,8 @@ enum cds_auto_pwr_detect_failure_mode_t {
* @etsi_srd_chan_in_master_mode: Use of ETSI SRD chan in SAP/P2P-GO ACS/PCL
* @dot11p_mode: dot11p user configuration
* @dfs_master_enable: DFS master capability
+ * @thermal_sampling_time: Thermal throttling sampling time in ms
+ * @thermal_throt_dc: Thermal throttling duty cycle to be enforced
* Structure for holding cds ini parameters.
*/
@@ -223,6 +225,10 @@ struct cds_config_info {
bool etsi_srd_chan_in_master_mode;
uint8_t dot11p_mode;
bool dfs_master_enable;
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+ uint16_t thermal_sampling_time;
+ uint16_t thermal_throt_dc;
+#endif
};
#ifdef WLAN_FEATURE_FILS_SK
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index 7d2420158ef0..b3b500b38692 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -11372,7 +11372,6 @@ bool cds_is_valid_channel_for_channel_switch(uint8_t channel)
uint32_t sap_count;
enum channel_state state;
hdd_context_t *hdd_ctx;
- bool is_safe;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
@@ -11384,14 +11383,12 @@ bool cds_is_valid_channel_for_channel_switch(uint8_t channel)
sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel();
sap_count = cds_mode_specific_connection_count(CDS_SAP_MODE, NULL);
state = cds_get_channel_state(channel);
- is_safe = cds_is_safe_channel(channel);
- cds_debug("is_safe %u, sta_sap_scc_on_dfs_chan %u, sap_count %u, channel %u, state %u",
- is_safe, sta_sap_scc_on_dfs_chan, sap_count, channel,
- state);
+ cds_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u, channel %u, state %u",
+ sta_sap_scc_on_dfs_chan, sap_count, channel, state);
- if (is_safe && ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) ||
- ((state == CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan))) {
+ if ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) ||
+ ((state == CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan)) {
cds_debug("Valid channel for channel switch");
return true;
}
diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c
index f82e7cc157f8..db6abef3b026 100644
--- a/core/dp/htt/htt_rx.c
+++ b/core/dp/htt/htt_rx.c
@@ -1237,7 +1237,6 @@ htt_rx_amsdu_pop_ll(htt_pdev_handle pdev,
+ HTT_RX_PPDU_DESC_SIZE32));
}
msdu = *head_msdu = htt_rx_netbuf_pop(pdev);
- *head_mon_msdu = NULL;
while (1) {
int last_msdu, msdu_len_invalid, msdu_chained;
int byte_offset;
@@ -1515,7 +1514,6 @@ htt_rx_amsdu_pop_hl(
(qdf_nbuf_data(rx_ind_msg)));
qdf_nbuf_set_next(*tail_msdu, NULL);
- *head_mon_msdu = NULL;
return 0;
}
@@ -1540,7 +1538,6 @@ htt_rx_frag_pop_hl(
*head_msdu = *tail_msdu = frag_msg;
qdf_nbuf_set_next(*tail_msdu, NULL);
- *mon_head_msdu = NULL;
return 0;
}
@@ -2193,7 +2190,6 @@ static int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
HTT_RX_IN_ORD_PADDR_IND_HDR_BYTES);
paddr = htt_rx_in_ord_paddr_get(msg_word);
msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
- *head_mon_msdu = NULL;
if (qdf_unlikely(NULL == msdu)) {
qdf_print("%s: netbuf pop failed!\n", __func__);
@@ -2439,8 +2435,6 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
paddr = htt_rx_in_ord_paddr_get(msg_word);
(*head_msdu) = msdu = htt_rx_in_order_netbuf_pop(pdev, paddr);
- (*head_mon_msdu) = NULL;
-
if (qdf_unlikely(NULL == msdu)) {
qdf_print("%s: netbuf pop failed!\n", __func__);
*tail_msdu = NULL;
@@ -2505,7 +2499,7 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev,
msdu_count--;
- if (cds_get_pktcap_mode_enable() &&
+ if (head_mon_msdu && cds_get_pktcap_mode_enable() &&
(ol_cfg_pktcapture_mode(pdev->ctrl_pdev) &
PKT_CAPTURE_MODE_DATA_ONLY) &&
pdev->txrx_pdev->mon_cb && !frag_ind) {
diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c
index d417e9f6e8c3..fa1b7d5599b1 100644
--- a/core/dp/txrx/ol_txrx_peer_find.c
+++ b/core/dp/txrx/ol_txrx_peer_find.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -759,7 +759,6 @@ void ol_txrx_peer_remove_obj_map_entries(ol_txrx_pdev_handle pdev,
peer_id_ref_cnt);
num_deleted_maps += peer_id_ref_cnt;
pdev->peer_id_to_obj_map[peer_id].peer = NULL;
- peer->peer_ids[i] = HTT_INVALID_PEER;
if (peer_id_ref_cnt)
pdev->peer_id_to_obj_map[peer_id].peer_ref = peer;
diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h
index 4de9e2fda672..a5414a537160 100644
--- a/core/hdd/inc/wlan_hdd_assoc.h
+++ b/core/hdd/inc/wlan_hdd_assoc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -225,6 +225,14 @@ typedef struct hdd_ap_ctx_s hdd_ap_ctx_t;
*/
bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx);
+/**
+ * hdd_is_disconnecting() - Function to check disconnection progress
+ * @hdd_sta_ctx: pointer to global HDD Station context
+ *
+ * Return: true if disconnecting, false otherwise
+ */
+bool hdd_is_disconnecting(hdd_station_ctx_t *hdd_sta_ctx);
+
/*
* hdd_is_fils_connection: API to determine if connection is FILS
* @adapter: hdd adapter
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index edcd032402da..09b887cdb178 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -15465,6 +15465,74 @@ enum hw_filter_mode {
#define CFG_PKTCAPTURE_MODE_MAX (3)
#define CFG_PKTCAPTURE_MODE_DEFAULT (0)
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/*
+ * thermal_sampling_time - Configure the thermal mitigation sampling time in ms.
+ *
+ * @Min: 10
+ * @Max: 100
+ * @Default: 100
+ *
+ * This ini will control the sampling time that the thermal mitigation in FW
+ * will consider while applying the duty cycle.
+ *
+ * Usage: External
+ *
+ * Supported features: Thermal Mitigation
+ *
+ * </ini>
+ */
+#define CFG_THERMAL_SAMPLING_TIME_NAME "thermal_sampling_time"
+#define CFG_THERMAL_SAMPLING_TIME_MIN (10)
+#define CFG_THERMAL_SAMPLING_TIME_MAX (100)
+#define CFG_THERMAL_SAMPLING_TIME_DEFAULT (100)
+
+/*
+ * thermal_throt_dc - Configure the thermal mitigation duty cycling percentage
+ *
+ * @Min: 0
+ * @Max: 100
+ * @Default: 50
+ *
+ * This ini will control the duty cycle that will be enforced by the firmware.
+ * If for example the duty cycle is 50 percent and the sampling time
+ * (thermal_sampling_time) is 100ms then the FW will constrain rx/tx for 50ms
+ * out of the 100ms.
+ *
+ * Usage: External
+ *
+ * Supported features: Thermal Mitigation
+ *
+ * </ini>
+ */
+#define CFG_THERMAL_THROT_DC_NAME "thermal_throt_dc"
+#define CFG_THERMAL_THROT_DC_MIN (10)
+#define CFG_THERMAL_THROT_DC_MAX (100)
+#define CFG_THERMAL_THROT_DC_DEFAULT (50)
+#endif
+/*
+ * <ini>
+ * disable_4way_hs_offload - Enable/Disable 4 way handshake offload to firmware
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * 0 4-way HS to be handled in firmware
+ * 1 4-way HS to be handled in supplicant
+ *
+ * Related: None
+ *
+ * Supported Feature: STA Roaming
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_DISABLE_4WAY_HS_OFFLOAD "disable_4way_hs_offload"
+#define CFG_DISABLE_4WAY_HS_OFFLOAD_MIN (0)
+#define CFG_DISABLE_4WAY_HS_OFFLOAD_MAX (1)
+#define CFG_DISABLE_4WAY_HS_OFFLOAD_DEFAULT (0)
+
/*
* Type declarations
*/
@@ -16425,6 +16493,12 @@ struct hdd_config {
bool pktcap_mode_enable;
uint8_t pktcapture_mode;
+
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+ uint16_t thermal_sampling_time;
+ uint16_t thermal_throt_dc;
+#endif
+ bool disable_4way_hs_offload;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 0b3e8790a629..373bdd16fb17 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -339,6 +339,8 @@ static inline bool in_compat_syscall(void) { return is_compat_task(); }
#define WLAN_NUD_STATS_ARP_PKT_TYPE 1
/* Assigned size of driver memory dump is 4096 bytes */
#define DRIVER_MEM_DUMP_SIZE 4096
+/* Max number of states supported by the driver for thermal mitigation */
+#define HDD_THERMAL_MAX_STATE 2
/*
* @eHDD_DRV_OP_PROBE: Refers to .probe operation
@@ -1940,6 +1942,21 @@ struct hdd_cache_channels {
};
/**
+ * enum hdd_thermal_states - The various thermal states as supported by WLAN
+ * @HDD_THERMAL_STATE_NORMAL - The normal working state
+ * @HDD_THERMAL_STATE_MEDIUM - The intermediate state, WLAN must perform partial
+ * mitigation
+ * @HDD_THERMAL_STATE_HIGH - The highest state, WLAN must enter forced IMPS and
+ * will disconnect any active STA connection
+ */
+enum hdd_thermal_states {
+ HDD_THERMAL_STATE_NORMAL = 0,
+ HDD_THERMAL_STATE_MEDIUM = 1,
+ HDD_THERMAL_STATE_HIGH = 2,
+ HDD_THERMAL_STATE_INVAL = 0xFF,
+};
+
+/**
* struct hdd_context_s
* @adapter_nodes: an array of adapter nodes for keeping track of hdd adapters
*/
@@ -2266,6 +2283,7 @@ struct hdd_context_s {
bool is_ssr_in_progress;
uint8_t pktcapture_mode;
+ bool is_thermal_system_registered;
};
int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter,
diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h
index 7d3293850444..00dfab5d9df6 100644
--- a/core/hdd/inc/wlan_hdd_power.h
+++ b/core/hdd/inc/wlan_hdd_power.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012, 2014-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -294,4 +294,70 @@ hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev)
* If the interface went down close the session.
*/
void hdd_is_interface_down_during_ssr(hdd_context_t *hdd_ctx);
+
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * hdd_send_thermal_notification() - Send the thermal state to the FW
+ * @hdd_ctx: The HDD context
+ * @thermal_state: The thermal state that is to be sent to the firmware
+ *
+ * Return: None
+ */
+void hdd_send_thermal_notification(hdd_context_t *hdd_ctx,
+ enum hdd_thermal_states thermal_state);
+/**
+ * hdd_thermal_mitigation_disable() - Disable thermal mitigation
+ * @hdd_ctx: The HDD context
+ *
+ * This function verifies whether driver is already performing any sort of
+ * thermal mitigation in connected STA scenario. If that is the case, then it
+ * disables the thermal mitigation by sending command to FW.
+ *
+ * Return: None
+ */
+void hdd_thermal_mitigation_disable(hdd_context_t *hdd_ctx);
+
+/**
+ * hdd_thermal_mitigation_enable() - Enable thermal mitigation
+ * @hdd_ctx: The HDD context
+ *
+ * This function verifies whether driver is connected in STA with no concurrent
+ * sessions active. If yes then it sends the current thermal state notification
+ * to the firmware.
+ *
+ * Return: None
+ */
+void hdd_thermal_mitigation_enable(hdd_context_t *hdd_ctx);
+
+/**
+ * hdd_map_thermal_states() - Return thermal state enum from int value
+ * @state: The state that is to be mapped
+ *
+ * Return: enum hdd_thermal_states value for the corresponding state
+ */
+enum hdd_thermal_states hdd_map_thermal_states(uint16_t state);
+#else
+static inline
+void hdd_send_thermal_notification(hdd_context_t *hdd_ctx,
+ uint8_t thermal_state)
+{
+}
+
+static inline
+void hdd_thermal_mitigation_disable(hdd_context_t *hdd_ctx)
+{
+}
+
+static inline
+void hdd_thermal_mitigation_enable(hdd_context_t *hdd_ctx)
+{
+}
+
+static inline
+enum hdd_thermal_states hdd_map_thermal_states(uint16_t state)
+{
+ return HDD_THERMAL_STATE_INVAL;
+}
+
+#endif
#endif /* __WLAN_HDD_POWER_H */
diff --git a/core/hdd/src/wlan_hdd_apf.c b/core/hdd/src/wlan_hdd_apf.c
index cefec834d167..ae059dc604cc 100644
--- a/core/hdd/src/wlan_hdd_apf.c
+++ b/core/hdd/src/wlan_hdd_apf.c
@@ -469,7 +469,8 @@ hdd_apf_read_memory_callback(void *hdd_context,
*/
pkt_offset = read_mem_evt->offset - context->offset;
- if (context->buf_len < pkt_offset + read_mem_evt->length) {
+ if ((pkt_offset > context->buf_len) ||
+ (context->buf_len - pkt_offset < read_mem_evt->length)) {
hdd_err("Read chunk exceeding allocated space");
return;
}
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 519eecc1a0d1..6bb9f473aafe 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -316,6 +316,18 @@ bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
}
/**
+ * hdd_is_disconnecting() - Function to check disconnection progress
+ * @hdd_sta_ctx: pointer to global HDD Station context
+ *
+ * Return: true if disconnecting, false otherwise
+ */
+bool hdd_is_disconnecting(hdd_station_ctx_t *hdd_sta_ctx)
+{
+ return hdd_sta_ctx->conn_info.connState ==
+ eConnectionState_Disconnecting;
+}
+
+/**
* hdd_conn_is_connected() - Function to check connection status
* @pHddStaCtx: pointer to global HDD Station context
*
@@ -1657,6 +1669,15 @@ static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
hdd_err("net_dev is released return");
return QDF_STATUS_E_FAILURE;
}
+
+ if (!pHddCtx) {
+ hdd_err("HDD context is null");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ /* Disable mitigation in FW if STA gets disconnected */
+ hdd_send_thermal_notification(pHddCtx, HDD_THERMAL_STATE_NORMAL);
+
/* notify apps that we can't pass traffic anymore */
hdd_info("Disabling queues");
wlan_hdd_netif_queue_control(pAdapter,
@@ -2609,6 +2630,7 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
bool hddDisconInProgress = false;
unsigned long rc;
tSirResultCodes timeout_reason = 0;
+ uint16_t thermal_state = HDD_THERMAL_STATE_NORMAL;
if (!pHddCtx) {
hdd_err("HDD context is NULL");
@@ -2703,6 +2725,13 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
hdd_err("Failed to set nth beacon reporting");
}
+ /* Send the thermal mitigation status to FW */
+ if (pHddCtx->is_thermal_system_registered &&
+ !pld_get_thermal_state(pHddCtx->parent_dev, &thermal_state))
+ hdd_send_thermal_notification(pHddCtx,
+ hdd_map_thermal_states(
+ thermal_state));
+
if (cds_is_mcc_in_24G()) {
if (pHddCtx->miracast_value)
cds_set_mas(pAdapter, pHddCtx->miracast_value);
@@ -5470,7 +5499,11 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
if (pRoamInfo)
wlan_hdd_sae_callback(pAdapter, pRoamInfo);
break;
-
+ case eCSR_ROAM_FIPS_PMK_REQUEST:
+ /* notify the supplicant of a new candidate */
+ qdf_ret_status = wlan_hdd_cfg80211_pmksa_candidate_notify(
+ pAdapter, pRoamInfo, 1, false);
+ break;
default:
break;
}
@@ -6139,6 +6172,10 @@ int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
RSNAuthType;
hdd_debug("updated profile authtype as %d",
RSNAuthType);
+ } else if (RSNAuthType == eCSR_AUTH_TYPE_SAE) {
+ /* SAE with open authentication case */
+ pRoamProfile->AuthType.authType[0] =
+ eCSR_AUTH_TYPE_SAE;
} else if ((RSNAuthType ==
eCSR_AUTH_TYPE_SUITEB_EAP_SHA256) &&
((pWextState->
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 9102bc7bac2b..2f32051f1764 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -5825,6 +5825,29 @@ struct reg_table_entry g_registry_table[] = {
CFG_PKTCAPTURE_MODE_DEFAULT,
CFG_PKTCAPTURE_MODE_MIN,
CFG_PKTCAPTURE_MODE_MAX),
+
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+ REG_VARIABLE(CFG_THERMAL_SAMPLING_TIME_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, thermal_sampling_time,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_THERMAL_SAMPLING_TIME_DEFAULT,
+ CFG_THERMAL_SAMPLING_TIME_MIN,
+ CFG_THERMAL_SAMPLING_TIME_MAX),
+
+ REG_VARIABLE(CFG_THERMAL_THROT_DC_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, thermal_throt_dc,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_THERMAL_THROT_DC_DEFAULT,
+ CFG_THERMAL_THROT_DC_MIN,
+ CFG_THERMAL_THROT_DC_MAX),
+#endif
+
+ REG_VARIABLE(CFG_DISABLE_4WAY_HS_OFFLOAD, WLAN_PARAM_Integer,
+ struct hdd_config, disable_4way_hs_offload,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_DISABLE_4WAY_HS_OFFLOAD_DEFAULT,
+ CFG_DISABLE_4WAY_HS_OFFLOAD_MIN,
+ CFG_DISABLE_4WAY_HS_OFFLOAD_MAX),
};
/**
@@ -6878,6 +6901,28 @@ static void hdd_cfg_print_btc_params(hdd_context_t *hdd_ctx)
hdd_ctx->config->set_bt_interference_high_ul);
}
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * hdd_cfg_print_thermal_config - Print thermal config inis
+ * @hdd_ctx: HDD context structure
+ *
+ * Return: None
+ */
+static inline void hdd_cfg_print_thermal_config(hdd_context_t *hdd_ctx)
+{
+ hdd_debug("Name = [%s] value = [%d]",
+ CFG_THERMAL_SAMPLING_TIME_NAME,
+ hdd_ctx->config->thermal_sampling_time);
+ hdd_debug("Name = [%s] value = [%d]",
+ CFG_THERMAL_THROT_DC_NAME,
+ hdd_ctx->config->thermal_throt_dc);
+}
+#else
+static inline void hdd_cfg_print_thermal_config(hdd_context_t *hdd_ctx)
+{
+}
+#endif
+
/**
* hdd_cfg_print() - print the hdd configuration
* @iniTable: pointer to hdd context
@@ -7875,6 +7920,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
CFG_PKTCAP_MODE_ENABLE_NAME, pHddCtx->config->pktcap_mode_enable);
hdd_debug("Name = [%s] value = [%d]",
CFG_PKTCAPTURE_MODE_NAME, pHddCtx->config->pktcapture_mode);
+ hdd_cfg_print_thermal_config(pHddCtx);
+ hdd_debug("Name = [%s] value = [%d]",
+ CFG_DISABLE_4WAY_HS_OFFLOAD, pHddCtx->config->disable_4way_hs_offload);
}
/**
@@ -10597,6 +10645,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
pHddCtx->config->btm_sticky_time;
smeConfig->csrConfig.btm_query_bitmask =
pHddCtx->config->btm_query_bitmask;
+ smeConfig->csrConfig.disable_4way_hs_offload =
+ pHddCtx->config->disable_4way_hs_offload;
hdd_update_bss_score_params(pHddCtx->config,
&smeConfig->csrConfig.bss_score_params);
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 44e6d3f24c1b..4fe13ea02348 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -14852,6 +14852,8 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
pRoamProfile = &pWextState->roamProfile;
LastBSSType = pRoamProfile->BSSType;
+ hdd_thermal_mitigation_disable(pHddCtx);
+
switch (type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
@@ -14988,6 +14990,7 @@ done:
if (pAdapter->device_mode == QDF_STA_MODE) {
hdd_debug("Sending Lpass mode change notification");
hdd_lpass_notify_mode_change(pAdapter);
+ hdd_thermal_mitigation_enable(pHddCtx);
}
EXIT();
@@ -16523,8 +16526,6 @@ int wlan_hdd_cfg80211_pmksa_candidate_notify(hdd_adapter_t *adapter,
int index, bool preauth)
{
struct net_device *dev = adapter->dev;
- hdd_context_t *hdd_ctx = (hdd_context_t *) adapter->pHddCtx;
- struct pmkid_mode_bits pmkid_modes;
ENTER();
hdd_debug("is going to notify supplicant of:");
@@ -16534,14 +16535,13 @@ int wlan_hdd_cfg80211_pmksa_candidate_notify(hdd_adapter_t *adapter,
return -EINVAL;
}
- hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
- if (pmkid_modes.fw_okc) {
- hdd_debug(MAC_ADDRESS_STR,
- MAC_ADDR_ARRAY(roam_info->bssid.bytes));
- cfg80211_pmksa_candidate_notify(dev, index,
- roam_info->bssid.bytes,
- preauth, GFP_KERNEL);
- }
+ /*
+ * Supplicant should be notified regardless the PMK caching or OKC
+ * is enabled in firmware or not
+ */
+ hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(roam_info->bssid.bytes));
+ cfg80211_pmksa_candidate_notify(dev, index, roam_info->bssid.bytes,
+ preauth, GFP_KERNEL);
return 0;
}
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index 72e2ebbb7b2e..8c4d993b62cb 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -1491,6 +1491,60 @@ static int wlan_hdd_pld_runtime_resume(struct device *dev,
}
#endif
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * wlan_hdd_pld_set_therm_state() - Notify the thermal state
+ * @dev: device
+ * @state: the thermal state
+ *
+ * This callback is registered with PLD to send thermal state change
+ * notification to the WLAN host. When the thermal subsystem triggers a state
+ * change notification to the PLD, the PLD uses this callback to forward the
+ * notification.
+ *
+ * Return: 0 on success, error code otherwise
+ */
+static int wlan_hdd_pld_set_therm_state(struct device *dev, int state)
+{
+ hdd_context_t *hdd_ctx;
+
+ if (cds_is_driver_in_bad_state() && cds_is_driver_recovering() &&
+ cds_is_fw_down()) {
+ hdd_err("Rejecting thermal notif during FW down/bad state");
+ return -EBUSY;
+ }
+
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ if (!hdd_ctx) {
+ hdd_err("hdd_ctx is NULL return");
+ return -EINVAL;
+ }
+
+ hdd_debug("thermal state: %d notification", state);
+ if (state != HDD_THERMAL_STATE_HIGH)
+ cds_set_driver_thermal_mitigated(false);
+
+ switch (state) {
+ case HDD_THERMAL_STATE_HIGH:
+ hdd_send_thermal_notification(hdd_ctx,
+ HDD_THERMAL_STATE_HIGH);
+ break;
+ case HDD_THERMAL_STATE_MEDIUM:
+ hdd_send_thermal_notification(hdd_ctx,
+ HDD_THERMAL_STATE_MEDIUM);
+ break;
+ case HDD_THERMAL_STATE_NORMAL:
+ hdd_send_thermal_notification(hdd_ctx,
+ HDD_THERMAL_STATE_NORMAL);
+ break;
+ default:
+ hdd_debug("Invalid thermal state");
+ }
+
+ return 0;
+}
+#endif
+
struct pld_driver_ops wlan_drv_ops = {
.probe = wlan_hdd_pld_probe,
.remove = wlan_hdd_pld_remove,
@@ -1508,6 +1562,9 @@ struct pld_driver_ops wlan_drv_ops = {
.runtime_suspend = wlan_hdd_pld_runtime_suspend,
.runtime_resume = wlan_hdd_pld_runtime_resume,
#endif
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+ .set_curr_therm_state = wlan_hdd_pld_set_therm_state,
+#endif
};
int wlan_hdd_register_driver(void)
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 2ecf57684c63..fad7bb785f10 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -55,6 +55,7 @@
#include <cds_utils.h>
#include "pld_common.h"
#include "wlan_hdd_regulatory.h"
+#include "wlan_hdd_power.h"
#include "wma.h"
#ifdef WLAN_DEBUG
@@ -7882,6 +7883,12 @@ int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
status = sme_update_channel_list(hdd_ctx->hHal);
if (status)
hdd_err("Can't Restore channel list");
+ else
+ /*
+ * Free the cache channels when the
+ * disabled channels are restored
+ */
+ wlan_hdd_free_cache_channels(hdd_ctx);
EXIT();
return 0;
@@ -8587,6 +8594,8 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
}
}
+ hdd_thermal_mitigation_disable(pHddCtx);
+
if (!cds_set_connection_in_progress(true)) {
hdd_err("Can't start BSS: set connnection in progress failed");
ret = -EINVAL;
@@ -8682,6 +8691,8 @@ error:
&pHostapdAdapter->sessionCtx.ap.acs_in_progress, 0);
wlan_hdd_undo_acs(pHostapdAdapter);
+ hdd_thermal_mitigation_enable(pHddCtx);
+
enable_roaming:
/* Enable Roaming after start bss in case of failure */
wlan_hdd_enable_roaming(pHostapdAdapter);
@@ -8920,6 +8931,8 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
}
#endif
wlan_hdd_check_conc_and_update_tdls_state(pHddCtx, false);
+ hdd_thermal_mitigation_enable(pHddCtx);
+
EXIT();
return ret;
}
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index d4e019f5bb0d..207d48b91468 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -7259,13 +7259,11 @@ static int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, uint8_t *ptr)
hdd_debug("Number of channel to disable are: %d", temp_int);
if (!temp_int) {
- if (!wlan_hdd_restore_channels(hdd_ctx)) {
- /*
- * Free the cache channels only when the command is
- * received with num channels as 0
- */
- wlan_hdd_free_cache_channels(hdd_ctx);
- }
+ /*
+ * Restore and Free the cache channels when the command is
+ * received with num channels as 0
+ */
+ wlan_hdd_restore_channels(hdd_ctx);
return 0;
}
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 181b5f17799a..671abd702889 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -770,6 +770,12 @@ int wlan_hdd_validate_context(hdd_context_t *hdd_ctx)
return -EAGAIN;
}
+ if (cds_is_driver_thermal_mitigated()) {
+ hdd_debug("Driver in thermal mitigated state: 0x%x Block!!!",
+ cds_get_driver_state());
+ return -EAGAIN;
+ }
+
return 0;
}
@@ -2252,6 +2258,37 @@ static void hdd_check_for_leaks(void)
qdf_mem_check_for_leaks();
}
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * hdd_configure_thermal_mitigation() - Register/unregister thermal mitigation
+ * @dev: The device structure
+ * @state: true for register; false for unregister
+ *
+ * This API triggers regiters/unregisters thermal mitigation feature with the
+ * thermal subsystem.
+ *
+ * Return: None
+ */
+static void hdd_configure_thermal_mitigation(hdd_context_t *hdd_ctx,
+ struct device *dev, bool state)
+{
+ if (state) {
+ if (!pld_thermal_register(dev, HDD_THERMAL_MAX_STATE))
+ hdd_ctx->is_thermal_system_registered = true;
+ } else {
+ if (hdd_ctx->is_thermal_system_registered) {
+ pld_thermal_unregister(dev);
+ hdd_ctx->is_thermal_system_registered = false;
+ }
+ }
+}
+#else
+static void hdd_configure_thermal_mitigation(hdd_context_t *hdd_ctx,
+ struct device *dev, bool state)
+{
+}
+#endif
+
uint32_t hdd_wlan_get_version(hdd_context_t *hdd_ctx,
const size_t version_len, uint8_t *version)
{
@@ -2471,6 +2508,7 @@ int hdd_wlan_start_modules(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter,
}
hdd_enable_power_management();
+ hdd_configure_thermal_mitigation(hdd_ctx, qdf_dev->dev, 1);
hdd_info("Driver Modules Successfully Enabled");
hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
@@ -8191,6 +8229,32 @@ static void hdd_send_svc_coex_info(hdd_context_t *hdd_ctx,
}
/**
+ * hdd_store_sap_restart_channel() - store sap restart channel
+ * @restart_chan: restart channel
+ * @restart_chan_store: pointer to restart channel store
+ *
+ * The function will store new sap restart channel.
+ *
+ * Return - none
+ */
+static void
+hdd_store_sap_restart_channel(uint8_t restart_chan, uint8_t *restart_chan_store)
+{
+ uint8_t i;
+
+ for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+ if (*(restart_chan_store + i) == restart_chan)
+ return;
+
+ if (*(restart_chan_store + i))
+ continue;
+
+ *(restart_chan_store + i) = restart_chan;
+ return;
+ }
+}
+
+/**
* hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
* @hdd_ctx: hdd context pointer
*
@@ -8208,6 +8272,7 @@ void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctxt)
uint32_t i;
bool found = false;
uint8_t restart_chan;
+ uint8_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0};
status = hdd_get_front_adapter(hdd_ctxt, &adapter_node);
while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
@@ -8249,13 +8314,31 @@ void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctxt)
}
if (!found) {
+ hdd_store_sap_restart_channel(
+ adapter_temp->sessionCtx.ap.operatingChannel,
+ restart_chan_store);
hdd_debug("ch:%d is safe. no need to change channel",
adapter_temp->sessionCtx.ap.operatingChannel);
goto next_adapater;
}
- restart_chan =
- wlansap_get_safe_channel_from_pcl_and_acs_range(
+ restart_chan = 0;
+ for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
+ if (!restart_chan_store[i])
+ continue;
+
+ if (cds_is_force_scc() &&
+ CDS_IS_SAME_BAND_CHANNELS(
+ restart_chan_store[i],
+ adapter_temp->sessionCtx.ap.
+ operatingChannel)) {
+ restart_chan = restart_chan_store[i];
+ break;
+ }
+ }
+ if (!restart_chan)
+ restart_chan =
+ wlansap_get_safe_channel_from_pcl_and_acs_range(
adapter_temp->sessionCtx.ap.sapContext);
if (!restart_chan) {
hdd_err("fail to restart SAP");
@@ -8272,8 +8355,12 @@ void hdd_unsafe_channel_restart_sap(hdd_context_t *hdd_ctxt)
restart_chan);
hdd_debug("driver to start sap: %d",
hdd_ctxt->config->sap_internal_restart);
- if (hdd_ctxt->config->sap_internal_restart)
+ if (hdd_ctxt->config->sap_internal_restart) {
hdd_restart_sap(adapter_temp, restart_chan);
+ hdd_store_sap_restart_channel(
+ restart_chan,
+ restart_chan_store);
+ }
else
return;
}
@@ -9475,6 +9562,27 @@ static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
}
#endif
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * hdd_populate_thermal_cfg - Populate the thermal config ini values in CDS cfg
+ * @cds_cfg: CDS config structure
+ * @hdd_ctx: HDD context structure
+ *
+ * Return: None
+ */
+static inline void hdd_populate_thermal_cfg(struct cds_config_info *cds_cfg,
+ hdd_context_t *hdd_ctx)
+{
+ cds_cfg->thermal_sampling_time = hdd_ctx->config->thermal_sampling_time;
+ cds_cfg->thermal_throt_dc = hdd_ctx->config->thermal_throt_dc;
+}
+#else
+static inline void hdd_populate_thermal_cfg(struct cds_config_info *cds_cfg,
+ hdd_context_t *hdd_ctx)
+{
+}
+#endif
+
/**
* hdd_update_cds_config() - API to update cds configuration parameters
* @hdd_ctx: HDD Context
@@ -9624,6 +9732,7 @@ static int hdd_update_cds_config(hdd_context_t *hdd_ctx)
hdd_nan_populate_cds_config(cds_cfg, hdd_ctx);
hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
cds_init_ini_config(cds_cfg);
+ hdd_populate_thermal_cfg(cds_cfg, hdd_ctx);
return 0;
exit:
@@ -10389,8 +10498,6 @@ static int hdd_pre_enable_configure(hdd_context_t *hdd_ctx)
goto out;
}
- cds_fill_and_send_ctl_to_fw(&hdd_ctx->reg);
-
status = hdd_set_sme_chan_list(hdd_ctx);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("Failed to init channel list: %d", status);
@@ -11120,6 +11227,7 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool ftm_mode)
case DRIVER_MODULES_ENABLED:
hdd_info("Wlan transition (OPENED <- ENABLED)");
+ hdd_configure_thermal_mitigation(hdd_ctx, qdf_ctx->dev, 0);
hdd_disable_power_management();
if (hdd_deconfigure_cds(hdd_ctx)) {
hdd_err("Failed to de-configure CDS");
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 1d3e868c93e2..7a7bf9f72ac9 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -2800,3 +2800,144 @@ int hdd_wlan_fake_apps_resume(struct wiphy *wiphy, struct net_device *dev)
return 0;
}
#endif
+
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+void hdd_send_thermal_notification(hdd_context_t *hdd_ctx,
+ enum hdd_thermal_states thermal_state)
+{
+ QDF_STATUS status;
+ hdd_adapter_t *sta_adapter;
+ bool is_sta_connected, is_sta_connecting, is_sta_disconnecting;
+
+ if (!hdd_ctx) {
+ hdd_err("hdd context is null");
+ return;
+ }
+
+ if (!hdd_ctx->is_thermal_system_registered) {
+ hdd_debug("Thermal system not registered! Ignore");
+ return;
+ }
+
+ sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
+ if (!sta_adapter) {
+ hdd_err("STA adapter not present");
+ return;
+ }
+
+ is_sta_connected = hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(
+ sta_adapter));
+ is_sta_connecting = hdd_is_connecting(WLAN_HDD_GET_STATION_CTX_PTR(
+ sta_adapter));
+ is_sta_disconnecting =
+ hdd_is_disconnecting(WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter));
+
+ if (cds_get_connection_count() > 1) {
+ hdd_debug("Concurrent sessions present ignoring thermal notif");
+ return;
+ }
+
+ if (is_sta_disconnecting) {
+ hdd_debug("STA disconnecting; send disable thermal notif");
+ thermal_state = 0;
+ goto send;
+ }
+
+ if (!is_sta_connected || is_sta_connecting) {
+ hdd_debug("STA not connected/connecting, ignore thermal notif");
+ return;
+ }
+
+ switch (thermal_state) {
+ case HDD_THERMAL_STATE_HIGH:
+ cds_set_driver_thermal_mitigated(true);
+ hdd_debug("STA connected, issue disconnect");
+ wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
+
+ /*
+ * Sending the thermal notification after disconnection will be
+ * taken care in the disconnect path, so return from here and
+ * do not send the notification now.
+ */
+ return;
+ case HDD_THERMAL_STATE_MEDIUM:
+ case HDD_THERMAL_STATE_NORMAL:
+ cds_set_driver_thermal_mitigated(false);
+ break;
+ default:
+ hdd_err("Invalid thermal state: %d", thermal_state);
+ return;
+ }
+
+send:
+ status = wma_update_thermal_mitigation_to_fw(thermal_state);
+ if (QDF_IS_STATUS_ERROR(status))
+ hdd_err("Failed to send thermal mitigation to FW");
+}
+
+/**
+ * hdd_thermal_mitigation_disable() - Disable thermal mitigation
+ * @hdd_ctx: The HDD context
+ *
+ * This function verifies whether driver is already performing any sort of
+ * thermal mitigation in connected STA scenario. If that is the case, then it
+ * disables the thermal mitigation by sending command to FW.
+ *
+ * Return: None
+ */
+void hdd_thermal_mitigation_disable(hdd_context_t *hdd_ctx)
+{
+ if (cds_is_sta_active_connection_exists() &&
+ hdd_ctx->is_thermal_system_registered) {
+ hdd_debug("Disabling thermal mitigation; STA+ concr not supp");
+ hdd_send_thermal_notification(hdd_ctx,
+ HDD_THERMAL_STATE_NORMAL);
+ }
+}
+
+/**
+ * hdd_thermal_mitigation_enable() - Enable thermal mitigation
+ * @hdd_ctx: The HDD context
+ *
+ * This function verifies whether driver is connected in STA with no concurrent
+ * sessions active. If yes then it sends the current thermal state notification
+ * to the firmware.
+ *
+ * Return: None
+ */
+void hdd_thermal_mitigation_enable(hdd_context_t *hdd_ctx)
+{
+ uint16_t thermal_state = HDD_THERMAL_STATE_NORMAL;
+
+ if (cds_is_sta_active_connection_exists() &&
+ cds_get_connection_count() == 1 &&
+ hdd_ctx->is_thermal_system_registered) {
+ hdd_debug("Re-enabling thermal mitigation");
+ if (!pld_get_thermal_state(hdd_ctx->parent_dev, &thermal_state))
+ hdd_send_thermal_notification(hdd_ctx,
+ hdd_map_thermal_states(
+ thermal_state));
+ }
+}
+
+/**
+ * hdd_map_thermal_states() - Return thermal state enum from int value
+ * @state: The state that is to be mapped
+ *
+ * Return: enum hdd_thermal_states value for the corresponding state
+ */
+enum hdd_thermal_states hdd_map_thermal_states(uint16_t state)
+{
+ switch (state) {
+ case 0:
+ return HDD_THERMAL_STATE_NORMAL;
+ case 1:
+ return HDD_THERMAL_STATE_MEDIUM;
+ case 2:
+ return HDD_THERMAL_STATE_HIGH;
+ default:
+ hdd_err("Invalid thermal state");
+ return HDD_THERMAL_STATE_INVAL;
+ }
+}
+#endif
diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c
index 4015d855c7b1..6b0585db6f5b 100644
--- a/core/hdd/src/wlan_hdd_regulatory.c
+++ b/core/hdd/src/wlan_hdd_regulatory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, 2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -187,7 +187,6 @@ static int hdd_update_regulatory_info(hdd_context_t *hdd_ctx)
hdd_ctx->reg.reg_domain |= country_code;
return cds_fill_some_regulatory_info(&hdd_ctx->reg);
-
}
/**
@@ -521,6 +520,18 @@ static void hdd_process_regulatory_data(hdd_context_t *hdd_ctx,
} else {
cds_chan->state = CHANNEL_STATE_ENABLE;
}
+
+ /* This check is to mark SRD as passive if ini is 0 */
+ if (!hdd_ctx->config->etsi_srd_chan_in_master_mode &&
+ cds_is_etsi13_regdmn_srd_chan(
+ wiphy_chan->center_freq)) {
+ hdd_debug("freq %d is SRD, marked as passive",
+ wiphy_chan->center_freq);
+ wiphy_chan->flags |=
+ IEEE80211_CHAN_PASSIVE_SCAN;
+ cds_chan->flags = wiphy_chan->flags;
+ cds_chan->state = CHANNEL_STATE_DFS;
+ }
cds_chan->pwr_limit = wiphy_chan->max_power;
cds_chan->flags = wiphy_chan->flags;
@@ -710,6 +721,8 @@ int hdd_apply_cached_country_info(hdd_context_t *hdd_ctx)
if (ret_val)
return ret_val;
+ cds_fill_and_send_ctl_to_fw(&hdd_ctx->reg);
+
hdd_process_regulatory_data(hdd_ctx, hdd_ctx->wiphy,
hdd_ctx->reg.reset);
@@ -838,8 +851,6 @@ void hdd_reg_notifier(struct wiphy *wiphy,
sme_generic_change_country_code(hdd_ctx->hHal,
hdd_ctx->reg.alpha2);
- cds_fill_and_send_ctl_to_fw(&hdd_ctx->reg);
-
cds_get_dfs_region(&dfs_reg);
cds_set_wma_dfs_region(dfs_reg);
break;
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index d1cb7e4a54d5..31b7712f6ba9 100644
--- a/core/mac/inc/qwlan_version.h
+++ b/core/mac/inc/qwlan_version.h
@@ -32,9 +32,9 @@
#define QWLAN_VERSION_MAJOR 5
#define QWLAN_VERSION_MINOR 1
#define QWLAN_VERSION_PATCH 1
-#define QWLAN_VERSION_EXTRA "W"
-#define QWLAN_VERSION_BUILD 73
+#define QWLAN_VERSION_EXTRA "N"
+#define QWLAN_VERSION_BUILD 74
-#define QWLAN_VERSIONSTR "5.1.1.73W"
+#define QWLAN_VERSIONSTR "5.1.1.74N"
#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 470b4459bfb4..d9022b6ef82a 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -519,6 +519,7 @@ typedef struct sSirSmeReadyReq {
void *pe_roam_synch_cb;
void *sme_msg_cb;
void *stop_roaming_cb;
+ void *csr_roam_pmkid_req_cb;
} tSirSmeReadyReq, *tpSirSmeReadyReq;
/**
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index 74188d03867d..4287b55930b9 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -94,7 +94,8 @@ typedef struct sPESession /* Added to Support BT-AMP */
uint16_t peSessionId;
uint8_t smeSessionId;
uint16_t transactionId;
-
+ qdf_wake_lock_t ap_ecsa_wakelock;
+ qdf_runtime_lock_t ap_ecsa_runtime_lock;
/* In AP role: BSSID and selfMacAddr will be the same. */
/* In STA role: they will be different */
tSirMacAddr bssId;
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index 29fab1e11f75..58f7190fb4ae 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -1181,7 +1181,8 @@ void pe_register_callbacks_with_wma(tpAniSirGlobal pMac,
retStatus = wma_register_roaming_callbacks(p_cds_gctx,
ready_req->csr_roam_synch_cb,
- ready_req->pe_roam_synch_cb);
+ ready_req->pe_roam_synch_cb,
+ ready_req->csr_roam_pmkid_req_cb);
if (retStatus != QDF_STATUS_SUCCESS)
pe_err("Registering roaming callbacks with WMA failed");
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 37f0f62ab5c5..1aebd0ac2253 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -6011,6 +6011,8 @@ void lim_send_chan_switch_action_frame(tpAniSirGlobal mac_ctx,
}
+#define MAX_WAKELOCK_FOR_CSA 5000
+
/**
* lim_process_sme_dfs_csa_ie_request() - process sme dfs csa ie req
*
@@ -6130,6 +6132,9 @@ static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal mac_ctx,
dfs_csa_ie_req->ch_params.center_freq_seg0;
skip_vht:
/* Send CSA IE request from here */
+ qdf_wake_lock_timeout_acquire(&session_entry->ap_ecsa_wakelock,
+ MAX_WAKELOCK_FOR_CSA);
+ qdf_runtime_pm_prevent_suspend(&session_entry->ap_ecsa_runtime_lock);
lim_send_dfs_chan_sw_ie_update(mac_ctx, session_entry);
if (dfs_csa_ie_req->ch_params.ch_width == CH_WIDTH_80MHZ)
diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c
index 665a30a72c76..129903eb137e 100644
--- a/core/mac/src/pe/lim/lim_send_messages.c
+++ b/core/mac/src/pe/lim/lim_send_messages.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -197,6 +197,8 @@ tSirRetStatus lim_send_switch_chnl_params(tpAniSirGlobal pMac,
pChnlParams->reduced_beacon_interval =
pMac->sap.SapDfsInfo.reduced_beacon_interval;
+ pChnlParams->ssid_hidden = pSessionEntry->ssidHidden;
+ pChnlParams->ssid = pSessionEntry->ssId;
if (cds_is_5_mhz_enabled())
pChnlParams->ch_width = CH_WIDTH_5MHZ;
else if (cds_is_10_mhz_enabled())
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index 3daffcbd866f..7958083003ea 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -2519,6 +2519,9 @@ lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac,
enum phy_ch_width ch_width;
uint8_t ch_center_freq_seg1;
+ qdf_runtime_pm_allow_suspend(&psessionEntry->ap_ecsa_runtime_lock);
+ qdf_wake_lock_release(&psessionEntry->ap_ecsa_wakelock, 0);
+
pSmeSwithChnlParams = (tSwitchChannelParams *)
qdf_mem_malloc(sizeof(tSwitchChannelParams));
if (NULL == pSmeSwithChnlParams) {
diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c
index 7f9e83624d68..2d8309be693f 100644
--- a/core/mac/src/pe/lim/lim_session.c
+++ b/core/mac/src/pe/lim/lim_session.c
@@ -509,6 +509,9 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId,
}
if (status != QDF_STATUS_SUCCESS)
pe_err("cannot create or start protectionFieldsResetTimer");
+ qdf_wake_lock_create(&session_ptr->ap_ecsa_wakelock,
+ "ap_ecsa_wakelock");
+ qdf_runtime_lock_init(&session_ptr->ap_ecsa_runtime_lock);
status = qdf_mc_timer_init(&session_ptr->ap_ecsa_timer,
QDF_TIMER_TYPE_WAKE_APPS, lim_process_ap_ecsa_timeout,
(void *)&pMac->lim.gpSession[i]);
@@ -686,6 +689,8 @@ void pe_delete_session(tpAniSirGlobal mac_ctx, tpPESession session)
session->dfsIncludeChanSwIe = 0;
qdf_mc_timer_stop(&session->ap_ecsa_timer);
qdf_mc_timer_destroy(&session->ap_ecsa_timer);
+ qdf_runtime_lock_deinit(&session->ap_ecsa_runtime_lock);
+ qdf_wake_lock_destroy(&session->ap_ecsa_wakelock);
lim_del_pmf_sa_query_timer(mac_ctx, session);
}
diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h
index aef1aaecc70c..7cfc2c8c8f84 100644
--- a/core/pld/inc/pld_common.h
+++ b/core/pld/inc/pld_common.h
@@ -292,7 +292,7 @@ struct pld_soc_info {
* @modem_status: optional operation, will be called when platform driver
* sending modem power status to WLAN FW
* @uevent: optional operation, will be called when platform driver
- * updating driver status
+ * updating driver status
* @runtime_suspend: optional operation, prepare the device for a condition
* in which it won't be able to communicate with the CPU(s)
* and RAM due to power management.
@@ -301,6 +301,11 @@ struct pld_soc_info {
* hardware or at the request of software.
* @suspend_noirq: optional operation, complete the actions started by suspend()
* @resume_noirq: optional operation, prepare for the execution of resume()
+ * @set_curr_therm_state: optional operation, will be called when there is a
+ * change in the thermal level triggered by the thermal
+ * subsystem thus requiring mitigation actions. This will
+ * be called every time there is a change in the state
+ * and after driver load.
*/
struct pld_driver_ops {
int (*probe)(struct device *dev,
@@ -334,6 +339,7 @@ struct pld_driver_ops {
enum pld_bus_type bus_type);
int (*resume_noirq)(struct device *dev,
enum pld_bus_type bus_type);
+ int (*set_curr_therm_state)(struct device *dev, int state);
};
int pld_init(void);
@@ -616,4 +622,31 @@ static inline int pld_nbuf_pre_alloc_free(struct sk_buff *skb)
return 0;
}
#endif
+
+/**
+ * pld_thermal_register() - Register the thermal device with the thermal system
+ * @dev: The device structure
+ * @state: The max state to be configured on registration
+ *
+ * Return: Error code on error
+ */
+int pld_thermal_register(struct device *dev, int state);
+
+/**
+ * pld_thermal_unregister() - Unregister the device with the thermal system
+ * @dev: The device structure
+ *
+ * Return: None
+ */
+void pld_thermal_unregister(struct device *dev);
+
+/**
+ * pld_get_thermal_state() - Get the current thermal state from the PLD
+ * @dev: The device structure
+ * @thermal_state: param to store the current thermal state
+ *
+ * Return: Non-zero code for error; zero for success
+ */
+int pld_get_thermal_state(struct device *dev, uint16_t *thermal_state);
+
#endif
diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c
index d278a004b3b2..b683b9988367 100644
--- a/core/pld/src/pld_common.c
+++ b/core/pld/src/pld_common.c
@@ -1575,3 +1575,41 @@ void pld_block_shutdown(struct device *dev, bool status)
break;
}
}
+
+#if defined(CONFIG_PLD_SNOC_ICNSS) && defined(CONFIG_WLAN_FW_THERMAL_MITIGATION)
+int pld_thermal_register(struct device *dev, int max_state)
+{
+ return icnss_thermal_register(dev, max_state);
+}
+
+void pld_thermal_unregister(struct device *dev)
+{
+ icnss_thermal_unregister(dev);
+}
+
+int pld_get_thermal_state(struct device *dev, uint16_t *thermal_state)
+{
+ int ret;
+ unsigned long thermal_state_t;
+
+ ret = icnss_get_curr_therm_state(dev, &thermal_state_t);
+ *thermal_state = (uint16_t)thermal_state_t;
+
+ return ret;
+}
+
+#else
+int pld_thermal_register(struct device *dev, int max_state)
+{
+ return -ENOTSUPP;
+}
+
+void pld_thermal_unregister(struct device *dev)
+{
+}
+
+int pld_get_thermal_state(struct device *dev, uint16_t *thermal_state)
+{
+ return -ENOTSUPP;
+}
+#endif
diff --git a/core/pld/src/pld_snoc.c b/core/pld/src/pld_snoc.c
index b1d1ed25b740..857224793e8f 100644
--- a/core/pld/src/pld_snoc.c
+++ b/core/pld/src/pld_snoc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -262,6 +262,35 @@ static int pld_snoc_uevent(struct device *dev,
return 0;
}
+#if defined(CONFIG_WLAN_FW_THERMAL_MITIGATION)
+/**
+ * pld_snoc_set_thermal_state() - Set thermal state for thermal mitigation
+ * @dev: device
+ * @thermal_state: Thermal state set by thermal subsystem
+ *
+ * This function will be called when thermal subsystem notifies platform
+ * driver about change in thermal state.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+static int pld_snoc_set_thermal_state(struct device *dev,
+ unsigned long thermal_state)
+{
+ struct pld_context *pld_context;
+
+ pld_context = pld_get_global_context();
+ if (!pld_context)
+ return -EINVAL;
+
+ if (pld_context->ops->set_curr_therm_state)
+ return pld_context->ops->set_curr_therm_state(dev,
+ thermal_state);
+
+ return -ENOTSUPP;
+}
+#endif
+
#ifdef MULTI_IF_NAME
#define PLD_SNOC_OPS_NAME "pld_snoc_" MULTI_IF_NAME
#else
@@ -280,6 +309,9 @@ struct icnss_driver_ops pld_snoc_ops = {
.suspend_noirq = pld_snoc_suspend_noirq,
.resume_noirq = pld_snoc_resume_noirq,
.uevent = pld_snoc_uevent,
+#if defined(CONFIG_WLAN_FW_THERMAL_MITIGATION)
+ .set_therm_state = pld_snoc_set_thermal_state,
+#endif
};
/**
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 0fdba87e92e9..92d67e8536bb 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -541,6 +541,7 @@ typedef enum {
eCSR_ROAM_SAE_COMPUTE,
/* LFR3 Roam sync complete */
eCSR_ROAM_SYNCH_COMPLETE,
+ eCSR_ROAM_FIPS_PMK_REQUEST,
} eRoamCmdStatus;
/* comment inside indicates what roaming callback gets */
@@ -1430,6 +1431,7 @@ typedef struct tagCsrConfigParam {
uint32_t btm_max_attempt_cnt;
uint32_t btm_sticky_time;
uint32_t btm_query_bitmask;
+ bool disable_4way_hs_offload;
} tCsrConfigParam;
/* Tush */
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index 2001a6824eae..8661f12f8330 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -699,6 +699,7 @@ typedef struct tagCsrConfig {
uint32_t btm_max_attempt_cnt;
uint32_t btm_sticky_time;
uint32_t btm_query_bitmask;
+ bool disable_4way_hs_offload;
} tCsrConfig;
typedef struct tagCsrChannelPowerInfo {
diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h
index 9c968e45c0e6..46e9811137d4 100644
--- a/core/sme/inc/csr_neighbor_roam.h
+++ b/core/sme/inc/csr_neighbor_roam.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -384,6 +384,41 @@ QDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp,
QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac,
roam_offload_synch_ind *roam_synch_data,
tpSirBssDescription bss_desc_ptr, enum sir_roam_op_code reason);
+
+#ifdef WLAN_FEATURE_FIPS
+/**
+ * csr_roam_pmkid_req_callback() - Registered CSR Callback function to handle
+ * roam event from firmware for pmkid generation fallback.
+ * @vdev_id: Vdev id
+ * @bss_list: candidate AP bssid list
+ */
+QDF_STATUS
+csr_roam_pmkid_req_callback(uint8_t vdev_id,
+ struct roam_pmkid_req_event *bss_list);
+
+/**
+ * csr_process_roam_pmkid_req_callback() - API to trigger the pmkid
+ * generation fallback event for candidate AP received from firmware.
+ * @mac_ctx: Global mac context pointer
+ * @vdev_id: Vdev id
+ * @roam_bsslist: roam candidate AP bssid list
+ *
+ * This function calls the hdd_sme_roam_callback with reason
+ * eCSR_ROAM_FIPS_PMK_REQUEST to trigger pmkid generation in supplicant.
+ */
+QDF_STATUS
+csr_process_roam_pmkid_req_callback(tpAniSirGlobal mac_ctx,
+ uint8_t vdev_id,
+ struct roam_pmkid_req_event *roam_bsslist);
+#else
+static inline QDF_STATUS
+csr_roam_pmkid_req_callback(uint8_t vdev_id,
+ struct roam_pmkid_req_event *bss_list)
+{
+ return QDF_STATUS_SUCCESS;
+}
+#endif /* WLAN_FEATURE_FIPS */
+
#else
static inline QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac,
roam_offload_synch_ind *roam_synch_data,
@@ -391,6 +426,13 @@ static inline QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac,
{
return QDF_STATUS_E_NOSUPPORT;
}
+
+static inline QDF_STATUS
+csr_roam_pmkid_req_callback(tpAniSirGlobal mac_ctx, uint8_t vdev_id,
+ struct roam_pmkid_req_event *bss_list)
+{
+ return QDF_STATUS_E_NOSUPPORT;
+}
#endif
void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx,
uint8_t newstate, uint8_t session);
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index f66c11a245b0..e51337c319af 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -1675,6 +1675,7 @@ QDF_STATUS sme_hdd_ready_ind(tHalHandle hHal)
msg->csr_roam_synch_cb = csr_roam_synch_callback;
msg->sme_msg_cb = sme_process_msg_callback;
msg->stop_roaming_cb = sme_stop_roaming;
+ msg->csr_roam_pmkid_req_cb = csr_roam_pmkid_req_callback;
if (eSIR_FAILURE != u_mac_post_ctrl_msg(hHal, (tSirMbMsg *)
msg))
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 86cb45b29ec9..4543f281f4dd 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -3099,6 +3099,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pParam->btm_sticky_time;
pMac->roam.configParam.btm_query_bitmask =
pParam->btm_query_bitmask;
+ pMac->roam.configParam.disable_4way_hs_offload =
+ pParam->disable_4way_hs_offload;
csr_set_11k_offload_config_param(&pMac->roam.configParam,
pParam);
@@ -3451,6 +3453,8 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->btm_sticky_time = pMac->roam.configParam.btm_sticky_time;
pParam->btm_query_bitmask =
pMac->roam.configParam.btm_query_bitmask;
+ pParam->disable_4way_hs_offload =
+ pMac->roam.configParam.disable_4way_hs_offload;
csr_get_11k_offload_config_param(&pMac->roam.configParam, pParam);
@@ -17710,6 +17714,8 @@ QDF_STATUS csr_process_add_sta_session_command(tpAniSirGlobal pMac,
pMac->roam.configParam.tx_aggr_sw_retry_threshold_vi;
add_sta_self_req->tx_aggr_sw_retry_threshold_vo =
pMac->roam.configParam.tx_aggr_sw_retry_threshold_vo;
+ add_sta_self_req->disable_4way_hs_offload =
+ pMac->roam.configParam.disable_4way_hs_offload;
msg.type = WMA_ADD_STA_SELF_REQ;
msg.reserved = 0;
msg.bodyptr = add_sta_self_req;
@@ -23157,4 +23163,71 @@ QDF_STATUS csr_roam_synch_callback(tpAniSirGlobal mac_ctx,
return status;
}
+
+#ifdef WLAN_FEATURE_FIPS
+QDF_STATUS
+csr_process_roam_pmkid_req_callback(tpAniSirGlobal mac_ctx,
+ uint8_t vdev_id,
+ struct roam_pmkid_req_event *src_lst)
+{
+ tCsrRoamInfo *roam_info;
+ tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, vdev_id);
+ struct qdf_mac_addr *dst_list;
+ QDF_STATUS status;
+ uint32_t num_entries, i;
+
+ if (!session)
+ return QDF_STATUS_E_NULL_VALUE;
+
+ roam_info = qdf_mem_malloc(sizeof(tCsrRoamInfo));
+ if (!roam_info)
+ return QDF_STATUS_E_NOMEM;
+
+ num_entries = src_lst->num_entries;
+ for (i = 0; i < num_entries; i++) {
+ dst_list = &src_lst->ap_bssid[i];
+ qdf_mem_copy(&roam_info->bssid, dst_list,
+ sizeof(struct qdf_mac_addr));
+
+ status = csr_roam_call_callback(mac_ctx, vdev_id, roam_info,
+ 0, eCSR_ROAM_FIPS_PMK_REQUEST,
+ eCSR_ROAM_RESULT_NONE);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ sme_err("%s: Trigger pmkid fallback failed", __func__);
+ qdf_mem_free(roam_info);
+ return status;
+ }
+ }
+ qdf_mem_free(roam_info);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+csr_roam_pmkid_req_callback(uint8_t vdev_id,
+ struct roam_pmkid_req_event *src_lst)
+{
+ QDF_STATUS status;
+ tpAniSirGlobal mac_ctx;
+
+ mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
+ if (!mac_ctx) {
+ WMA_LOGE("%s: NULL mac ptr", __func__);
+ QDF_ASSERT(0);
+ return -EINVAL;
+ }
+
+ status = sme_acquire_global_lock(&mac_ctx->sme);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ sme_err("%s: Locking failed, bailing out", __func__);
+ return status;
+ }
+
+ status = csr_process_roam_pmkid_req_callback(mac_ctx, vdev_id,
+ src_lst);
+ sme_release_global_lock(&mac_ctx->sme);
+
+ return status;
+}
+#endif /* WLAN_FEATURE_FIPS */
#endif
diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c
index 9f9be44a0c2f..7958cba2a5ea 100644
--- a/core/sme/src/csr/csr_util.c
+++ b/core/sme/src/csr/csr_util.c
@@ -288,6 +288,7 @@ const char *get_e_roam_cmd_status_str(eRoamCmdStatus val)
CASE_RETURN_STR(eCSR_ROAM_ABORT);
CASE_RETURN_STR(eCSR_ROAM_NAPI_OFF);
CASE_RETURN_STR(eCSR_ROAM_SAE_COMPUTE);
+ CASE_RETURN_STR(eCSR_ROAM_FIPS_PMK_REQUEST);
default:
return "unknown";
}
@@ -3083,6 +3084,8 @@ static void csr_check_sae_auth(tpAniSirGlobal mac_ctx,
c_auth_suites, authentication)) {
if (eCSR_AUTH_TYPE_SAE == auth_type->authType[index])
*neg_authtype = eCSR_AUTH_TYPE_SAE;
+ if (eCSR_AUTH_TYPE_OPEN_SYSTEM == auth_type->authType[index])
+ *neg_authtype = eCSR_AUTH_TYPE_OPEN_SYSTEM;
}
sme_debug("negotiated auth type is %d", *neg_authtype);
}
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 252de47335ca..611beb7711ab 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -1538,6 +1538,8 @@ struct peer_debug_info {
* @bandcapability: band capability configured through ini
* @ito_repeat_count: Indicates ito repeated count
* @critical_events_in_flight: number of suspend preventing events in flight
+ * @thermal_sampling_time: Thermal throttling sampling time in ms
+ * @thermal_throt_dc: Thermal throttling duty cycle that is to be enforced
*/
typedef struct {
void *wmi_handle;
@@ -1726,6 +1728,8 @@ typedef struct {
roam_offload_synch_ind *roam_synch_data,
tpSirBssDescription bss_desc_ptr,
enum sir_roam_op_code reason);
+ QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id,
+ struct roam_pmkid_req_event *bss_list);
qdf_wake_lock_t wmi_cmd_rsp_wake_lock;
qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock;
qdf_runtime_lock_t wma_runtime_resume_lock;
@@ -1763,6 +1767,11 @@ typedef struct {
atomic_t in_d0wow;
#endif
bool is_pktcapture_enabled;
+
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+ uint32_t thermal_sampling_time;
+ uint32_t thermal_throt_dc;
+#endif
} t_wma_handle, *tp_wma_handle;
/**
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index e8567492c40d..e80ce4703217 100644
--- a/core/wma/inc/wma_api.h
+++ b/core/wma/inc/wma_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -607,4 +607,18 @@ void wma_cleanup_vdev_resp_and_hold_req(void *priv);
*/
QDF_STATUS wma_send_dhcp_ind(uint16_t type, uint8_t device_mode,
uint8_t *mac_addr, uint8_t *sta_mac_addr);
+
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * wma_update_thermal_mitigation_to_fw() - update thermal mitigation to fw
+ * @wma: wma handle
+ * @thermal_level: thermal level
+ *
+ * This function sends down thermal mitigation params to the fw
+ *
+ * Returns: QDF_STATUS_SUCCESS for success otherwise failure
+ */
+QDF_STATUS wma_update_thermal_mitigation_to_fw(uint8_t thermal_level);
+#endif
+
#endif
diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h
index bda4ffc4cc81..d0b8607d4963 100644
--- a/core/wma/inc/wma_if.h
+++ b/core/wma/inc/wma_if.h
@@ -872,6 +872,9 @@ typedef struct {
* @isDfsChannel: is DFS channel
* @vhtCapable: VHT capable
* @dot11_mode: 802.11 mode
+ * @reduced_beacon_interval: reduced beacon interval value
+ * @ssid_hidden: the sap ssid is hidden
+ * @ssid: sap ssid
*/
typedef struct {
uint8_t channelNumber;
@@ -904,6 +907,8 @@ typedef struct {
uint8_t nss;
bool rx_ldpc;
uint16_t reduced_beacon_interval;
+ uint8_t ssid_hidden;
+ tSirMacSSid ssid;
} tSwitchChannelParams, *tpSwitchChannelParams;
typedef void (*tpSetLinkStateCallback)(tpAniSirGlobal pMac, void *msgParam,
@@ -1148,6 +1153,7 @@ typedef struct sMaxTxPowerPerBandParams {
* @tx_aggr_sw_retry_threshold_bk: sw retry threshold for bk
* @tx_aggr_sw_retry_threshold_vi: sw retry threshold for vi
* @tx_aggr_sw_retry_threshold_vo: sw retry threshold for vo
+ * @disable_4way_hs_offload: enable/disable 4 way handshake offload to firmware
*/
struct add_sta_self_params {
tSirMacAddr self_mac_addr;
@@ -1172,6 +1178,7 @@ struct add_sta_self_params {
uint32_t tx_aggr_sw_retry_threshold_bk;
uint32_t tx_aggr_sw_retry_threshold_vi;
uint32_t tx_aggr_sw_retry_threshold_vo;
+ bool disable_4way_hs_offload;
};
/**
@@ -1459,4 +1466,14 @@ typedef struct sNanRequest {
} tNanRequest, *tpNanRequest;
#endif /* WLAN_FEATURE_NAN */
+/*
+ * struct roam_pmkid_req_event - Pmkid event with entries destination structure
+ * @num_entries: total entries sent over the event
+ * @ap_bssid: bssid list
+ */
+struct roam_pmkid_req_event {
+ uint32_t num_entries;
+ struct qdf_mac_addr ap_bssid[];
+};
+
#endif /* _HALMSGAPI_H_ */
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index bc38ae1ee80a..2cb003eed6b9 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -213,6 +213,42 @@ void wma_process_roam_synch_fail(WMA_HANDLE handle,
int wma_roam_synch_event_handler(void *handle, uint8_t *event,
uint32_t len);
+#ifdef WLAN_FEATURE_FIPS
+/**
+ * wma_register_pmkid_req_event_handler() - Register pmkid request event handler
+ * @wma_handle: wma_handle
+ *
+ * This function register pmkid request event handler.
+ */
+void wma_register_pmkid_req_event_handler(tp_wma_handle wma_handle);
+
+/**
+ * wma_roam_pmkid_request_event_handler() - Handles roam pmkid request event
+ * @handle: wma_handle
+ * @event: pmkid request event data pointer
+ * @len: length of the data
+ *
+ * Handles pmkid request event from firmware which is triggered after roam
+ * candidate selection.
+ */
+int wma_roam_pmkid_request_event_handler(void *handle,
+ uint8_t *event,
+ uint32_t len);
+#else
+static inline void
+wma_register_pmkid_req_event_handler(tp_wma_handle wma_handle)
+{
+}
+
+static inline int
+wma_roam_pmkid_request_event_handler(void *handle,
+ uint8_t *event,
+ uint32_t len)
+{
+ return 0;
+}
+#endif /* WLAN_FEATURE_FIPS */
+
/**
* wma_roam_synch_frame_event_handler() - roam synch frame event handler
* @handle: wma handle
diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h
index 7ee3cb71e67c..19ed6203154e 100644
--- a/core/wma/inc/wma_types.h
+++ b/core/wma/inc/wma_types.h
@@ -790,7 +790,9 @@ QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx,
QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
roam_offload_synch_ind *roam_synch_data,
tpSirBssDescription bss_desc_ptr,
- enum sir_roam_op_code reason));
+ enum sir_roam_op_code reason),
+ QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id,
+ struct roam_pmkid_req_event *bss_list));
#else
static inline QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx,
QDF_STATUS (*csr_roam_synch_cb)(tpAniSirGlobal mac,
@@ -800,7 +802,9 @@ static inline QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx,
QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
roam_offload_synch_ind *roam_synch_data,
tpSirBssDescription bss_desc_ptr,
- enum sir_roam_op_code reason))
+ enum sir_roam_op_code reason),
+ QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id,
+ struct roam_pmkid_req_event *bss_list))
{
return QDF_STATUS_E_NOSUPPORT;
}
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index 894d30692d1f..21fe8e3ea403 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -2066,6 +2066,7 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
u_int8_t vdev_id;
struct sir_set_tx_rx_aggregation_size tx_rx_aggregation_size;
struct sir_set_tx_aggr_sw_retry_threshold tx_aggr_sw_retry_threshold;
+ uint32_t flags;
WMA_LOGD("mac %pM, vdev_id %hu, type %d, sub_type %d, nss 2g %d, 5g %d",
self_sta_req->self_mac_addr, self_sta_req->session_id,
@@ -2330,11 +2331,14 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
if ((self_sta_req->type == WMI_VDEV_TYPE_STA) &&
(self_sta_req->sub_type == 0)) {
wma_handle->roam_offload_enabled = true;
+ flags = (WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG |
+ WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG);
+ if (self_sta_req->disable_4way_hs_offload)
+ flags |= WMI_VDEV_PARAM_SKIP_ROAM_EAPOL_4WAY_HANDSHAKE;
ret = wma_vdev_set_param(wma_handle->wmi_handle,
self_sta_req->session_id,
WMI_VDEV_PARAM_ROAM_FW_OFFLOAD,
- (WMI_ROAM_FW_OFFLOAD_ENABLE_FLAG |
- WMI_ROAM_BMISS_FINAL_SCAN_ENABLE_FLAG));
+ flags);
if (QDF_IS_STATUS_ERROR(ret))
WMA_LOGE("Failed to set WMI_VDEV_PARAM_ROAM_FW_OFFLOAD");
@@ -2714,16 +2718,6 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma,
params.beacon_intval = req->beacon_intval;
params.dtim_period = req->dtim_period;
- /* Copy the SSID */
- if (req->ssid.length) {
- params.ssid.length = req->ssid.length;
- if (req->ssid.length < sizeof(cmd->ssid.ssid))
- temp_ssid_len = req->ssid.length;
- else
- temp_ssid_len = sizeof(cmd->ssid.ssid);
- qdf_mem_copy(params.ssid.mac_ssid, req->ssid.ssId,
- temp_ssid_len);
- }
params.pmf_enabled = req->pmf_enabled;
params.ldpc_rx_enabled = req->ldpc_rx_enabled;
@@ -2734,6 +2728,17 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma,
if (req->ldpc_rx_enabled)
temp_flags |= WMI_UNIFIED_VDEV_START_LDPC_RX_ENABLED;
}
+ /* Copy the SSID */
+ if (req->ssid.length) {
+ params.ssid.length = req->ssid.length;
+ if (req->ssid.length < sizeof(cmd->ssid.ssid))
+ temp_ssid_len = req->ssid.length;
+ else
+ temp_ssid_len = sizeof(cmd->ssid.ssid);
+ qdf_mem_copy(params.ssid.mac_ssid, req->ssid.ssId,
+ temp_ssid_len);
+ }
+
params.hidden_ssid = req->hidden_ssid;
if (req->hidden_ssid)
temp_flags |= WMI_UNIFIED_VDEV_START_HIDDEN_SSID;
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index a3a042689b6b..161609e3e178 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -3771,6 +3771,8 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason)
return "DEBUG_TEST";
case WOW_REASON_CHIP_POWER_FAILURE_DETECT:
return "CHIP_POWER_FAILURE_DETECT";
+ case WOW_REASON_ROAM_PMKID_REQUEST:
+ return "ROAM_PMKID_REQUEST";
default:
return "unknown";
}
@@ -4089,6 +4091,9 @@ static int wow_get_wmi_eventid(int32_t reason, uint32_t tag)
case WOW_REASON_ROAM_HO:
event_id = WMI_ROAM_EVENTID;
break;
+ case WOW_REASON_ROAM_PMKID_REQUEST:
+ event_id = WMI_ROAM_PMKID_REQUEST_EVENTID;
+ break;
default:
WMA_LOGD(FL("Unexpected WOW reason : %s(%d)"),
wma_wow_wake_reason_str(reason), reason);
@@ -4125,6 +4130,7 @@ static bool tlv_check_required(int32_t reason)
case WOW_REASON_NAN_EVENT:
case WOW_REASON_NAN_DATA:
case WOW_REASON_ROAM_HO:
+ case WOW_REASON_ROAM_PMKID_REQUEST:
return true;
default:
return false;
@@ -5052,6 +5058,14 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event,
wma_send_msg(wma, SIR_LIM_DELETE_STA_CONTEXT_IND,
(void *)del_sta_ctx, 0);
break;
+ case WOW_REASON_ROAM_PMKID_REQUEST:
+ WMA_LOGD("Host woken up because of PMKID request event");
+ if (param_buf->wow_packet_buffer)
+ wma_roam_pmkid_request_event_handler(handle,
+ wmi_cmd_struct_ptr, wow_buf_pkt_len);
+ else
+ WMA_LOGD("No wow_packet_buffer present");
+ break;
default:
break;
}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 693c1b531ea8..d7f0ecb62148 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -2387,6 +2387,29 @@ void wma_wmi_stop(void)
wmi_stop(wma_handle->wmi_handle);
}
+#ifdef FW_THERMAL_THROTTLE_SUPPORT
+/**
+ * wma_set_thermal_config_params() - Configure the thermal mitigation ini params
+ * @wma_handle: The wma_handle
+ * @cds_cfg: The CDS config structure
+ *
+ * Return: None
+ */
+static inline
+void wma_set_thermal_config_params(tp_wma_handle wma_handle,
+ struct cds_config_info *cds_cfg)
+{
+ wma_handle->thermal_sampling_time = cds_cfg->thermal_sampling_time;
+ wma_handle->thermal_throt_dc = cds_cfg->thermal_throt_dc;
+}
+#else
+static inline
+void wma_set_thermal_config_params(tp_wma_handle wma_handle,
+ struct cds_config_info *cds_cfg)
+{
+}
+#endif
+
/**
* wma_open() - Allocate wma context and initialize it.
* @cds_context: cds context
@@ -2620,6 +2643,7 @@ QDF_STATUS wma_open(void *cds_context,
wma_handle->is_lpass_enabled = cds_cfg->is_lpass_enabled;
#endif
wma_set_nan_enable(wma_handle, cds_cfg);
+ wma_set_thermal_config_params(wma_handle, cds_cfg);
/*
* Indicates if DFS Phyerr filtering offload
* is Enabled/Disabed from ini
@@ -2903,6 +2927,8 @@ QDF_STATUS wma_open(void *cds_context,
WMI_ROAM_SYNCH_FRAME_EVENTID,
wma_roam_synch_frame_event_handler,
WMA_RX_SERIALIZER_CTX);
+
+ wma_register_pmkid_req_event_handler(wma_handle);
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
wmi_unified_register_event_handler(wma_handle->wmi_handle,
WMI_RSSI_BREACH_EVENTID,
@@ -5274,7 +5300,7 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info,
wma_handle->wmi_handle,
WMI_VDEV_MGMT_OFFLOAD_EVENTID,
wma_mgmt_offload_data_event_handler,
- WMA_RX_SERIALIZER_CTX);
+ WMA_RX_WORK_CTX);
if (status) {
WMA_LOGE("Failed to register MGMT offload handler");
return -EINVAL;
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index 3ad0282ca1e7..2c5d519623e7 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -4302,6 +4302,7 @@ QDF_STATUS wma_de_register_mgmt_frm_client(void *cds_ctx)
* @cds_ctx: CDS Context
* @csr_roam_synch_cb: CSR roam synch callback routine pointer
* @pe_roam_synch_cb: PE roam synch callback routine pointer
+ * @csr_roam_pmkid_req_cb: CSR roam pmkid callback routine pointer
*
* Register the SME and PE callback routines with WMA for
* handling roaming
@@ -4316,7 +4317,9 @@ QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx,
QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac,
roam_offload_synch_ind *roam_synch_data,
tpSirBssDescription bss_desc_ptr,
- enum sir_roam_op_code reason))
+ enum sir_roam_op_code reason),
+ QDF_STATUS (*csr_roam_pmkid_req_cb)(uint8_t vdev_id,
+ struct roam_pmkid_req_event *bss_list))
{
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
@@ -4328,6 +4331,8 @@ QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx,
wma->csr_roam_synch_cb = csr_roam_synch_cb;
wma->pe_roam_synch_cb = pe_roam_synch_cb;
WMA_LOGD("Registered roam synch callbacks with WMA successfully");
+
+ wma->csr_roam_pmkid_req_cb = csr_roam_pmkid_req_cb;
return QDF_STATUS_SUCCESS;
}
#endif
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index a9a63f72d2d3..9d3909950965 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -3882,6 +3882,7 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
req.dtim_period = 1;
req.is_dfs = params->isDfsChannel;
req.ldpc_rx_enabled = params->rx_ldpc;
+ req.ssid = params->ssid;
/* In case of AP mode, once radar is detected, we need to
* issuse VDEV RESTART, so we making is_channel_switch as
@@ -3890,7 +3891,7 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
if ((wma_is_vdev_in_ap_mode(wma, req.vdev_id) == true) ||
(params->restart_on_chan_switch == true)) {
wma->interfaces[req.vdev_id].is_channel_switch = true;
- req.hidden_ssid = intr[vdev_id].vdev_restart_params.ssidHidden;
+ req.hidden_ssid = params->ssid_hidden;
}
if (params->restart_on_chan_switch == true &&
@@ -4587,6 +4588,21 @@ skip_pno_cmp_ind:
#endif
+#ifdef WLAN_FEATURE_FIPS
+void wma_register_pmkid_req_event_handler(tp_wma_handle wma_handle)
+{
+ if (!wma_handle) {
+ WMA_LOGE("%s: pmkid req wma_handle is NULL", __func__);
+ return;
+ }
+
+ wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_ROAM_PMKID_REQUEST_EVENTID,
+ wma_roam_pmkid_request_event_handler,
+ WMA_RX_SERIALIZER_CTX);
+}
+#endif /* WLAN_FEATURE_FIPS */
+
/**
* wma_register_extscan_event_handler() - register extscan event handler
* @wma_handle: wma handle
@@ -7328,3 +7344,89 @@ QDF_STATUS wma_send_ht40_obss_scanind(tp_wma_handle wma,
}
return QDF_STATUS_SUCCESS;
}
+
+#ifdef WLAN_FEATURE_FIPS
+int wma_roam_pmkid_request_event_handler(void *handle, uint8_t *event,
+ uint32_t len)
+{
+ WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *param_buf;
+ wmi_roam_pmkid_request_event_fixed_param *roam_pmkid_req_ev;
+ wmi_roam_pmkid_request_tlv_param *src_list;
+ tp_wma_handle wma = (tp_wma_handle)handle;
+ struct roam_pmkid_req_event *dst_list;
+ struct qdf_mac_addr *roam_bsslist;
+ uint32_t num_entries, i;
+ QDF_STATUS status;
+
+ if (!event) {
+ WMA_LOGE("%s: received null event from target", __func__);
+ return -EINVAL;
+ }
+
+ param_buf = (WMI_ROAM_PMKID_REQUEST_EVENTID_param_tlvs *)event;
+ if (!param_buf) {
+ WMA_LOGE("%s: received null buf from target", __func__);
+ return -EINVAL;
+ }
+
+ roam_pmkid_req_ev = param_buf->fixed_param;
+ if (!roam_pmkid_req_ev) {
+ WMA_LOGE("%s: received null event data from target", __func__);
+ return -EINVAL;
+ }
+
+ if (roam_pmkid_req_ev->vdev_id >= wma->max_bssid) {
+ WMA_LOGE("%s: received invalid vdev_id %d",
+ __func__, roam_pmkid_req_ev->vdev_id);
+ return -EINVAL;
+ }
+
+ num_entries = param_buf->num_pmkid_request;
+ if (num_entries > MAX_RSSI_AVOID_BSSID_LIST) {
+ WMA_LOGE("%s: num bssid entries:%d exceeds maximum value",
+ __func__, num_entries);
+ return -EINVAL;
+ }
+
+ src_list = param_buf->pmkid_request;
+ if (len < (sizeof(*roam_pmkid_req_ev) +
+ (num_entries * sizeof(*src_list)))) {
+ WMA_LOGE("%s: Invalid length:%d", __func__, len);
+ return -EINVAL;
+ }
+
+ dst_list = qdf_mem_malloc(sizeof(struct roam_pmkid_req_event) +
+ (sizeof(struct qdf_mac_addr) * num_entries));
+ if (!dst_list)
+ return -ENOMEM;
+
+ for (i = 0; i < num_entries; i++) {
+ roam_bsslist = &dst_list->ap_bssid[i];
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_list->bssid,
+ roam_bsslist->bytes);
+ if (qdf_is_macaddr_zero(roam_bsslist) ||
+ qdf_is_macaddr_broadcast(roam_bsslist) ||
+ qdf_is_macaddr_group(roam_bsslist)) {
+ WMA_LOGE("%s: Invalid bssid", __func__);
+ qdf_mem_free(dst_list);
+ return -EINVAL;
+ }
+ WMA_LOGD("%s:Received pmkid fallback for bssid: %pM vdev_id:%d",
+ __func__, roam_bsslist->bytes,
+ roam_pmkid_req_ev->vdev_id);
+ src_list++;
+ }
+ dst_list->num_entries = num_entries;
+
+ status = wma->csr_roam_pmkid_req_cb(roam_pmkid_req_ev->vdev_id,
+ dst_list);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ WMA_LOGE("%s: Pmkid request failed", __func__);
+ qdf_mem_free(dst_list);
+ return -EINVAL;
+ }
+
+ qdf_mem_free(dst_list);
+ return 0;
+}
+#endif /* WLAN_FEATURE_FIPS */
diff --git a/core/wma/src/wma_thermal.c b/core/wma/src/wma_thermal.c
new file mode 100644
index 000000000000..c793fd0ec9d4
--- /dev/null
+++ b/core/wma/src/wma_thermal.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wma_thermal.c
+ * This file contains thermal configurations and related functions.
+ */
+
+#include "wma.h"
+#include "wma_api.h"
+#include "cds_api.h"
+#include "wmi_unified_api.h"
+#include "wmi_unified.h"
+
+/**
+ * enum wma_thermal_states - The various thermal states as supported by WLAN
+ * @WMA_THERM_STATE_NORMAL - The normal working state
+ * @WMA_THERM_STATE_MEDIUM - The intermediate state, WLAN must perform partial
+ * mitigation
+ * @WMA_THERM_STATE_HIGH - The highest state, WLAN must enter forced IMPS
+ */
+enum wma_thermal_levels {
+ WMA_THERM_STATE_NORMAL = 0,
+ WMA_THERM_STATE_MEDIUM = 1,
+ WMA_THERM_STATE_HIGH = 2
+};
+
+/**
+ * wma_update_thermal_mitigation_to_fw - update thermal mitigation to fw
+ * @wma: wma handle
+ * @thermal_level: thermal level
+ *
+ * This function sends down thermal mitigation params to the fw
+ *
+ * Returns: QDF_STATUS_SUCCESS for success otherwise failure
+ */
+QDF_STATUS wma_update_thermal_mitigation_to_fw(uint8_t thermal_state)
+{
+ struct thermal_mitigation_params therm_data = {0};
+ tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+
+ if (!wma_handle) {
+ WMA_LOGE("%s : Failed to get wma_handle", __func__);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ switch (thermal_state) {
+ case WMA_THERM_STATE_NORMAL:
+ therm_data.enable = false;
+ break;
+ case WMA_THERM_STATE_MEDIUM:
+ therm_data.levelconf[0].dcoffpercent =
+ wma_handle->thermal_throt_dc;
+ therm_data.enable = true;
+ break;
+ default:
+ WMA_LOGE("Invalid thermal state: %d", thermal_state);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ therm_data.dc = wma_handle->thermal_sampling_time;
+ therm_data.num_thermal_conf = 1;
+ WMA_LOGD("Sending therm_throt with params enable:%d dc:%d dc_off:%d",
+ therm_data.enable, therm_data.dc,
+ therm_data.levelconf[0].dcoffpercent);
+
+ return wmi_unified_thermal_mitigation_param_cmd_send(
+ wma_handle->wmi_handle, &therm_data);
+}
+
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index aeca7afb4c78..6e254d1cb79f 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -6419,6 +6419,9 @@ void wma_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
wma_set_wow_event_bitmap(WOW_TDLS_CONN_TRACKER_EVENT,
WMI_WOW_MAX_EVENT_BM_LEN,
bitmask);
+ wma_set_wow_event_bitmap(WOW_ROAM_PMKID_REQUEST_EVENT,
+ WMI_WOW_MAX_EVENT_BM_LEN,
+ bitmask);
/* Add further STA wakeup events above this line. */
}