diff options
49 files changed, 1272 insertions, 74 deletions
@@ -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. */ } |
