diff options
| author | Vara Prasad A V S G <vavsg@codeaurora.org> | 2018-08-08 01:38:44 +0530 |
|---|---|---|
| committer | Vara Prasad A V S G <vavsg@codeaurora.org> | 2018-08-08 01:38:44 +0530 |
| commit | 20919639a1d2da32b29157278495ca1392e31fca (patch) | |
| tree | 73f87e58e639068eecf5a158eff3010b1d0554ba | |
| parent | 4a1d818a6b24f30807b654499fe4c81401b9296e (diff) | |
| parent | 3c67d964320c149eeb09c0e9f79d85869cac9db4 (diff) | |
Merge commit '3c67d964320c149eeb09c0e9f79d85869cac9db4' into HEAD
Conflicts:
core/dp/txrx/ol_txrx.c
Change-Id: I0e7731529d2cd16ee0f37136768667a8594e3a9e
93 files changed, 2763 insertions, 1250 deletions
@@ -1278,7 +1278,8 @@ CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \ -DCONFIG_160MHZ_SUPPORT \ -DCONFIG_MCL \ -DWMI_CMD_STRINGS \ - -DCONFIG_HDD_INIT_WITH_RTNL_LOCK + -DCONFIG_HDD_INIT_WITH_RTNL_LOCK \ + -DMWS_COEX ifneq ($(CONFIG_HIF_USB), 1) CDEFINES += -DWLAN_LOGGING_SOCK_SVC_ENABLE @@ -1862,6 +1863,10 @@ ifeq ($(CONFIG_WLAN_FEATURE_APF), y) CDEFINES += -DWLAN_FEATURE_APF endif +ifeq ($(CONFIG_WLAN_FEATURE_SARV1_TO_SARV2), y) +CDEFINES += -DWLAN_FEATURE_SARV1_TO_SARV2 +endif + #Flag to enable/disable WLAN D0-WOW ifeq ($(CONFIG_PCI_MSM), y) ifeq ($(CONFIG_ROME_IF),pci) @@ -135,4 +135,8 @@ config ICMP_DISABLE_PS config CONFIG_BUILD_TIMESTAMP bool "Embed timestamp in wlan version" default n + +config WLAN_FEATURE_SARV1_TO_SARV2 + bool "Enable conversion of SAR v1 to v2 feature" + default n endif # QCA_CLD_WLAN diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index c70764bbd86d..b81dc61d702f 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -751,6 +751,23 @@ bool cds_is_any_nondfs_chnl_present(uint8_t *channel); bool cds_is_any_dfs_beaconing_session_present(uint8_t *channel); bool cds_allow_concurrency(enum cds_con_mode mode, uint8_t channel, enum hw_mode_bandwidth bw); + +/** + * cds_check_privacy_with_concurrency() - privacy/concurrency checker + * + * This function checks the new device mode of the current adapter against its + * privacy settings and concurrency settings to see if there are any conflicts. + * + * Return: true if all checkings are passed, false if any conflict detected + */ +#ifdef FEATURE_WLAN_WAPI +bool cds_check_privacy_with_concurrency(void); +#else +static inline bool cds_check_privacy_with_concurrency(void) +{ + return true; +} +#endif enum cds_conc_priority_mode cds_get_first_connection_pcl_table_index(void); enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(void); enum cds_two_connection_mode cds_get_third_connection_pcl_table_index(void); @@ -1084,4 +1101,15 @@ bool cds_allow_sap_go_concurrency(enum cds_con_mode mode, uint8_t channel); * Return: true or false */ bool cds_is_sta_sap_scc(uint8_t sap_ch); + +/** + * cds_flush_sta_ap_intf_work - Flush the restart sap work + * @hdd_ctx: HDD context pointer + * + * Flush the restart sap work and also free the memory + * if not already freed. + * + * Restart: None + */ +void cds_flush_sta_ap_intf_work(hdd_context_t *hdd_ctx); #endif /* __CDS_CONCURRENCY_H */ diff --git a/core/cds/inc/cds_regdomain.h b/core/cds/inc/cds_regdomain.h index d97c734506a4..2d49c4d1efdd 100644 --- a/core/cds/inc/cds_regdomain.h +++ b/core/cds/inc/cds_regdomain.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2018 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 @@ -563,5 +563,11 @@ uint16_t cds_reg_dmn_get_chanwidth_from_opclass(uint8_t *country, uint8_t opclass); uint16_t cds_reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class); uint16_t cds_reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class); - +/** + * cds_is_etsi_europe_country - check ETSI Europe country or not + * @country: country string with two Characters + * + * Return: true if country in ETSI Europe country list + */ +bool cds_is_etsi_europe_country(uint8_t *country); #endif /* __CDS_REGDOMAIN_H */ diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 991a88a3bd21..bc9595bf7795 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -880,6 +880,9 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context) QDF_STATUS qdf_status; void *handle; + if (gp_cds_sched_context) + cds_sched_flush_mc_mqs(gp_cds_sched_context); + qdf_status = wma_stop(cds_context, HAL_STOP_TYPE_RF_KILL); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index caf037042acf..145b2607f114 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -2160,6 +2160,8 @@ static bool cds_current_concurrency_is_mcc(void) * @chain_mask: Chain mask * @vdev_id: vdev id * @in_use: Flag to indicate if the index is in use or not + * @update_conn: Flag to indicate if mode change event should + * be sent or not * * Updates the index value of the concurrent connection list * @@ -2173,7 +2175,8 @@ static void cds_update_conc_list(uint32_t conn_index, enum cds_chain_mode chain_mask, uint32_t original_nss, uint32_t vdev_id, - bool in_use) + bool in_use, + bool update_conn) { cds_context_type *cds_ctx; bool mcc_mode; @@ -2205,7 +2208,13 @@ static void cds_update_conc_list(uint32_t conn_index, if (cds_ctx->ol_txrx_update_mac_id_cb) cds_ctx->ol_txrx_update_mac_id_cb(vdev_id, mac); - if (cds_ctx->mode_change_cb) + /* + * For STA and P2P client mode, the mode change event sent as part + * of the callback causes delay in processing M1 frame at supplicant + * resulting in cert test case failure. The mode change event is sent + * as part of add key for STA and P2P client mode. + */ + if (cds_ctx->mode_change_cb && update_conn) cds_ctx->mode_change_cb(); /* IPA only cares about STA or SAP mode */ @@ -4642,6 +4651,7 @@ QDF_STATUS cds_incr_connection_count(uint32_t vdev_id) enum cds_con_mode mode; uint8_t chan; uint32_t nss = 0; + bool update_conn = true; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -4683,6 +4693,8 @@ QDF_STATUS cds_incr_connection_count(uint32_t vdev_id) cds_err("Error in getting nss"); } + if (mode == CDS_STA_MODE || mode == CDS_P2P_CLIENT_MODE) + update_conn = false; /* add the entry */ cds_update_conc_list(conn_index, @@ -4691,7 +4703,7 @@ QDF_STATUS cds_incr_connection_count(uint32_t vdev_id) cds_get_bw(wma_conn_table_entry->chan_width), wma_conn_table_entry->mac_id, chain_mask, - nss, vdev_id, true); + nss, vdev_id, true, update_conn); cds_debug("Add at idx:%d vdev %d mac=%d", conn_index, vdev_id, wma_conn_table_entry->mac_id); @@ -4777,7 +4789,7 @@ QDF_STATUS cds_update_connection_info(uint32_t vdev_id) cds_get_bw(wma_conn_table_entry->chan_width), wma_conn_table_entry->mac_id, chain_mask, - nss, vdev_id, true); + nss, vdev_id, true, true); return QDF_STATUS_SUCCESS; } @@ -5211,9 +5223,9 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, sta_sap_scc_on_dfs_chan = cds_is_sta_sap_scc_allowed_on_dfs_channel(); cds_debug("sta_sap_scc_on_dfs_chan %u", sta_sap_scc_on_dfs_chan); - if ((((mode == CDS_SAP_MODE) || (mode == CDS_P2P_GO_MODE)) && - (cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0)) || - !sta_sap_scc_on_dfs_chan) { + if (((mode == CDS_SAP_MODE) || (mode == CDS_P2P_GO_MODE)) && + (cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0) && + (!sta_sap_scc_on_dfs_chan)) { cds_debug("STA present, skip DFS channels from pcl for SAP/Go"); skip_dfs_channel = true; } @@ -5245,7 +5257,8 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, } while ((chan_index < num_channels) && - (chan_index_5 < QDF_MAX_NUM_CHAN)) { + (chan_index_5 < QDF_MAX_NUM_CHAN) && + (chan_index < QDF_MAX_NUM_CHAN)) { if ((true == skip_dfs_channel) && CDS_IS_DFS_CH(channel_list[chan_index])) { chan_index++; @@ -6272,6 +6285,11 @@ bool cds_allow_concurrency(enum cds_con_mode mode, goto done; } + if (!cds_check_privacy_with_concurrency()) { + hdd_err("Privacy setting not allowed with current concurrency setting!"); + goto done; + } + status = true; done: @@ -7957,6 +7975,26 @@ static bool cds_is_sap_restart_required_after_sta_disconnect( return true; } +void cds_flush_sta_ap_intf_work(hdd_context_t *hdd_ctx) +{ + ENTER(); + + if (hdd_ctx->sta_ap_intf_check_work_info) + cds_flush_work(&hdd_ctx->sta_ap_intf_check_work); + /* + * when sta_ap_intf_check_work is flushed above the work could already + * been running which will free the sta_ap_intf_check_work_info memory. + * So sanitize the sta_ap_intf_check_work_info and free the memory + * if not already freed. + */ + if (hdd_ctx->sta_ap_intf_check_work_info) { + qdf_mem_free(hdd_ctx->sta_ap_intf_check_work_info); + hdd_ctx->sta_ap_intf_check_work_info = NULL; + } + + EXIT(); +} + /** * __cds_check_sta_ap_concurrent_ch_intf() - Restart SAP in * STA-AP case @@ -8715,6 +8753,7 @@ void cds_restart_sap(hdd_adapter_t *ap_adapter) hdd_cleanup_actionframe(hdd_ctx, ap_adapter); hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter); qdf_event_reset(&hostapd_state->qdf_stop_bss_event); + hdd_ipa_ap_disconnect(ap_adapter); if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) { qdf_status = qdf_wait_for_event_completion(&hostapd_state-> @@ -8865,7 +8904,7 @@ QDF_STATUS cds_update_connection_info_utfw( cds_update_conc_list(conn_index, cds_get_mode(type, sub_type), channelid, HW_MODE_20_MHZ, - mac_id, chain_mask, 0, vdev_id, true); + mac_id, chain_mask, 0, vdev_id, true, true); return QDF_STATUS_SUCCESS; } @@ -8879,6 +8918,8 @@ QDF_STATUS cds_incr_connection_count_utfw( uint32_t conn_index = 0; hdd_context_t *hdd_ctx; cds_context_type *cds_ctx; + bool update_conn = true; + enum cds_con_mode mode; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -8901,10 +8942,15 @@ QDF_STATUS cds_incr_connection_count_utfw( } cds_debug("--> filling entry at index[%d]", conn_index); + mode = cds_get_mode(type, sub_type); + if (mode == CDS_STA_MODE || mode == CDS_P2P_CLIENT_MODE) + update_conn = false; + cds_update_conc_list(conn_index, - cds_get_mode(type, sub_type), + mode, channelid, HW_MODE_20_MHZ, - mac_id, chain_mask, 0, vdev_id, true); + mac_id, chain_mask, 0, vdev_id, true, + update_conn); return QDF_STATUS_SUCCESS; } @@ -10663,6 +10709,8 @@ void cds_checkn_update_hw_mode_single_mac_mode(uint8_t channel) cds_err("Invalid CDS Context"); return; } + if (QDF_TIMER_STATE_RUNNING == cds_ctx->dbs_opportunistic_timer.state) + qdf_mc_timer_stop(&cds_ctx->dbs_opportunistic_timer); qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { @@ -10675,11 +10723,6 @@ void cds_checkn_update_hw_mode_single_mac_mode(uint8_t channel) } } qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); - - if (QDF_TIMER_STATE_RUNNING == - cds_ctx->dbs_opportunistic_timer.state) - qdf_mc_timer_stop(&cds_ctx->dbs_opportunistic_timer); - cds_dbs_opportunistic_timer_handler((void *)cds_ctx); } @@ -11077,3 +11120,45 @@ bool cds_is_sta_sap_scc(uint8_t sap_ch) return is_scc; } +#ifdef FEATURE_WLAN_WAPI +bool cds_check_privacy_with_concurrency(void) +{ + bool ret = true; + uint32_t con_count; + hdd_adapter_t *adapter; + hdd_context_t *hdd_ctx; + hdd_adapter_list_node_t *adapter_node, *next; + QDF_STATUS status; + bool wapi_sta_present = false; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (NULL == hdd_ctx) { + cds_err("HDD context is NULL"); + return false; + } + + status = hdd_get_front_adapter(hdd_ctx, &adapter_node); + while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (adapter && + (QDF_STA_MODE == adapter->device_mode) && + adapter->wapi_info.nWapiMode && + (adapter->wapi_info.wapiAuthMode != WAPI_AUTH_MODE_OPEN)) { + wapi_sta_present = true; + break; + } + status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next); + adapter_node = next; + } + + con_count = cds_get_connection_count(); + cds_debug("No. of concurrent connections: %d", con_count); + + if (wapi_sta_present && con_count) { + cds_err("STA with WAPI not allowed when concurrent session(s) exist!"); + ret = false; + } + + return ret; +} +#endif diff --git a/core/cds/src/cds_regdomain.c b/core/cds/src/cds_regdomain.c index 9fa18ced76d6..c388b948ce24 100644 --- a/core/cds/src/cds_regdomain.c +++ b/core/cds/src/cds_regdomain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011,2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011,2013-2018 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 @@ -465,6 +465,63 @@ struct reg_dmn_tables g_reg_dmn_tbl = { QDF_ARRAY_SIZE(g_reg_dmns), }; +/* + * ETSI is updating EN 301 893, which specifies 5 GHz channel access + * in Europe + */ +static const char etsi_europe_country[][2] = { + {'A', 'T'}, + {'B', 'E'}, + {'B', 'G'}, + {'C', 'Z'}, + {'D', 'K'}, + {'E', 'E'}, + {'F', 'R'}, + + {'D', 'E'}, + {'I', 'S'}, + {'I', 'E'}, + {'I', 'T'}, + {'E', 'L'}, + {'E', 'S'}, + {'C', 'Y'}, + + {'L', 'V'}, + {'L', 'I'}, + {'L', 'T'}, + {'L', 'U'}, + {'H', 'U'}, + {'M', 'T'}, + {'N', 'L'}, + + {'N', 'O'}, + {'P', 'L'}, + {'P', 'T'}, + {'R', 'O'}, + {'S', 'I'}, + {'S', 'K'}, + {'T', 'R'}, + + {'F', 'I'}, + {'S', 'E'}, + {'C', 'H'}, + {'U', 'K'}, + {'H', 'R'}, +}; + +bool cds_is_etsi_europe_country(uint8_t *country) +{ + int32_t i; + + for (i = 0; i < QDF_ARRAY_SIZE(etsi_europe_country); i++) { + if (country[0] == etsi_europe_country[i][0] && + country[1] == etsi_europe_country[i][1]) + return true; + } + + return false; +} + /** * get_bdf_reg_dmn() - get regulatory domain from BDF * @reg_dmn: BDF regulatory domain diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c index 9a4f987af15d..06c9e2665752 100644 --- a/core/dp/htt/htt_rx.c +++ b/core/dp/htt/htt_rx.c @@ -2392,7 +2392,6 @@ htt_rx_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, ol_rx_offload_paddr_deliver_ind_handler(pdev, msdu_count, msg_word); *head_msdu = *tail_msdu = NULL; - ret = 0; goto end; } diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 3e15d69f4131..c8ce1ade03ed 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -4192,9 +4192,6 @@ int ol_txrx_fw_stats_desc_pool_init(struct ol_txrx_pdev_t *pdev, */ void ol_txrx_fw_stats_desc_pool_deinit(struct ol_txrx_pdev_t *pdev) { - struct ol_txrx_fw_stats_desc_elem_t *desc; - uint8_t i; - if (!pdev) { ol_txrx_err("%s: pdev is NULL", __func__); return; @@ -4210,11 +4207,6 @@ void ol_txrx_fw_stats_desc_pool_deinit(struct ol_txrx_pdev_t *pdev) qdf_spin_lock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock); qdf_atomic_set(&pdev->ol_txrx_fw_stats_desc_pool.initialized, 0); - for (i = 0; i < pdev->ol_txrx_fw_stats_desc_pool.pool_size; i++) { - desc = &pdev->ol_txrx_fw_stats_desc_pool.pool[i]; - if (desc && desc->desc.req) - qdf_mem_free(desc->desc.req); - } qdf_mem_free(pdev->ol_txrx_fw_stats_desc_pool.pool); pdev->ol_txrx_fw_stats_desc_pool.pool = NULL; diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h index 5ecc103ca449..bc65fa620d74 100644 --- a/core/hdd/inc/qc_sap_ioctl.h +++ b/core/hdd/inc/qc_sap_ioctl.h @@ -35,11 +35,6 @@ typedef uint8_t qcmacaddr[QCSAP_ADDR_LEN]; -struct qc_mac_acl_entry { - qcmacaddr addr; - int vlan_id; -}; - /* * Retrieve the WPA/RSN information element for an associated station. */ diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index f6d8b8e05111..4de9e2fda672 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/core/hdd/inc/wlan_hdd_assoc.h @@ -225,6 +225,15 @@ typedef struct hdd_ap_ctx_s hdd_ap_ctx_t; */ bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx); +/* + * hdd_is_fils_connection: API to determine if connection is FILS + * @adapter: hdd adapter + * + * Return: true if fils connection else false + */ +bool hdd_is_fils_connection(hdd_adapter_t *adapter); + + /** * hdd_conn_is_connected() - Function to check connection status * @pHddStaCtx: pointer to global HDD Station context @@ -358,7 +367,7 @@ int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, struct qdf_mac_addr *addr); QDF_STATUS hdd_roam_deregister_sta(hdd_adapter_t *adapter, uint8_t sta_id); #ifdef WLAN_FEATURE_ROAM_OFFLOAD -void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, +QDF_STATUS hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, const tSirMacAddr bssid, int channel); /** * hdd_save_gtk_params() - Save GTK offload params @@ -371,9 +380,10 @@ void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, void hdd_save_gtk_params(hdd_adapter_t *adapter, tCsrRoamInfo *csr_roam_info, bool is_reassoc); #else -static inline void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, +static inline QDF_STATUS hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, const tSirMacAddr bssid, int channel) { + return QDF_STATUS_SUCCESS; } static inline void hdd_save_gtk_params(hdd_adapter_t *adapter, tCsrRoamInfo *csr_roam_info, diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 82bb498d48c4..cf9182fc9c51 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -3741,7 +3741,7 @@ enum hdd_dot11_mode { #define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_NAME "gStaKeepAlivePeriod" #define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MIN (0) #define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_MAX (65535) -#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_DEFAULT (90) +#define CFG_INFRA_STA_KEEP_ALIVE_PERIOD_DEFAULT (60) /** * enum station_keepalive_method - available keepalive methods for stations @@ -12559,6 +12559,14 @@ enum hw_filter_mode { * This ini is used to specify which AP for which the connection has to be * made in 2x2 mode with HT capabilities only and not VHT. * + * Default OUIs: (All values in Hex) + * OUI 1 : 00904C + * OUI data Len : 03 + * OUI Data : 0418BF + * OUI data Mask: E0 - 11100000 + * Info Mask : 21 - Check for Band + * Capabilities: 40 - Band == 2G + * * Related: None * * Supported Feature: Action OUIs @@ -12568,7 +12576,51 @@ enum hw_filter_mode { * </ini> */ #define CFG_ACTION_OUI_SWITCH_TO_11N_MODE_NAME "gActionOUISwitchTo11nMode" -#define CFG_ACTION_OUI_SWITCH_TO_11N_MODE_DEFAULT "00904C 03 FFFFBF 20 21 40" +#define CFG_ACTION_OUI_SWITCH_TO_11N_MODE_DEFAULT "00904C 03 0418BF E0 21 40" + +/* + * <ini> + * gActionOUIConnect1x1with1TxRxChain - Used to specify action OUIs for + * 1x1 connection with one Tx/Rx Chain + * @Default: + * Note: User should strictly add new action OUIs at the end of this + * default value. + * + * Default OUIs: (All values in Hex) + * OUI 1 : 001018 + * OUI data Len : 06 + * OUI Data : 02FFF0040000 + * OUI data Mask: BC - 10111100 + * Info Mask : 21 - Check for Band + * Capabilities: 40 - Band == 2G + * + * OUI 2 : 001018 + * OUI data Len : 06 + * OUI Data : 02FFF0050000 + * OUI data Mask: BC - 10111100 + * Info Mask : 21 - Check for Band + * Capabilities: 40 - Band == 2G + * + * OUI 3 : 001018 + * OUI data Len : 06 + * OUI Data : 02FFF4050000 + * OUI data Mask: BC - 10111100 + * Info Mask : 21 - Check for Band + * Capabilities: 40 - Band == 2G + * + * This ini is used to specify the AP OUIs with which only 1x1 connection + * with one Tx/Rx Chain is allowed. + * + * Related: gEnableActionOUI + * + * Supported Feature: Action OUIs + * + * Usage: External + * + * </ini> + */ +#define CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_NAME "gActionOUIConnect1x1with1TxRxChain" +#define CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_DEFAULT "001018 06 02FFF0040000 BC 21 40 001018 06 02FFF0050000 BC 21 40 001018 06 02FFF4050000 BC 21 40" /* End of action oui inis */ @@ -14710,6 +14762,23 @@ enum hw_filter_mode { /* * <ini> + * gDisableChannel - Enable/Disable to disable channels specified + * + * @Min: 0 + * @Max: 1 + * Default: 0 + * + * Usage: Internal/External + * + * </ini> + */ +#define CFG_ENABLE_DISABLE_CHANNEL_NAME "gDisableChannel" +#define CFG_ENABLE_DISABLE_CHANNEL_MIN (0) +#define CFG_ENABLE_DISABLE_CHANNEL_MAX (1) +#define CFG_ENABLE_DISABLE_CHANNEL_DEFAULT (0) + +/* + * <ini> * channel_select_logic_conc - Set channel selection logic * for different concurrency combinations to DBS or inter band * MCC. Default is DBS for STA+STA and STA+P2P. @@ -14827,6 +14896,58 @@ enum hw_filter_mode { #define CFG_ENABLE_SECONDARY_RATE_MAX (0x3F) #define CFG_ENABLE_SECONDARY_RATE_DEFAULT (0x17) +#ifdef MWS_COEX +/* + * <ini> + * gMwsCoex4gQuickTdm - Bitmap to control MWS-COEX 4G quick FTDM policy + * @Min: 0x00000000 + * @Max: 0xFFFFFFFF + * @Default: 0x00000000 + * + * It is a 32 bit value such that the various bits represent as below: + * Bit-0 : 0 - Don't allow quick FTDM policy (Default) + * 1 - Allow quick FTDM policy + * Bit 1-31 : reserved for future use + * + * It is used to enable or disable MWS-COEX 4G (LTE) Quick FTDM + * + * Usage: Internal + * + * </ini> + */ + +#define CFG_MWS_COEX_4G_QUICK_FTDM_NAME "gMwsCoex4gQuickTdm" +#define CFG_MWS_COEX_4G_QUICK_FTDM_MIN (0x00000000) +#define CFG_MWS_COEX_4G_QUICK_FTDM_MAX (0xFFFFFFFF) +#define CFG_MWS_COEX_4G_QUICK_FTDM_DEFAULT (0x00000000) + +/* + * <ini> + * gMwsCoex5gnrPwrLimit - Bitmap to set MWS-COEX 5G-NR power limit + * @Min: 0x00000000 + * @Max: 0xFFFFFFFF + * @Default: 0x00000000 + * + * It is a 32 bit value such that the various bits represent as below: + * Bit-0 : Don't apply user specific power limit, + * use internal power limit (Default) + * Bit 1-2 : Invalid value (Ignored) + * Bit 3-21 : Apply the specified value as the external power limit, in dBm + * Bit 22-31 : Invalid value (Ignored) + * + * It is used to set MWS-COEX 5G-NR power limit + * + * Usage: Internal + * + * </ini> + */ + +#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_NAME "gMwsCoex5gnrPwrLimit" +#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_MIN (0x00000000) +#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_MAX (0xFFFFFFFF) +#define CFG_MWS_COEX_5G_NR_PWR_LIMIT_DEFAULT (0x00000000) +#endif + /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ @@ -14897,6 +15018,14 @@ struct hdd_config { /* Bitmap for operating voltage corner mode */ uint32_t vc_mode_cfg_bitmap; +#ifdef MWS_COEX + /* Bitmap for MWS-COEX 4G Quick FTDM */ + u32 g_mws_coex_4g_quick_tdm; + + /* Bitmap for MWS-COEX 5G-NR power limit */ + u32 g_mws_coex_5g_nr_pwr_limit; +#endif + uint16_t nNeighborScanPeriod; uint16_t neighbor_scan_min_period; uint8_t nNeighborLookupRssiThreshold; @@ -15684,6 +15813,7 @@ struct hdd_config { uint8_t action_oui_cckm_1x1[MAX_ACTION_OUI_STRING_LEN]; uint8_t action_oui_ito_alternate[MAX_ACTION_OUI_STRING_LEN]; uint8_t action_oui_switch_to_11n[MAX_ACTION_OUI_STRING_LEN]; + uint8_t action_oui_connect_1x1_with_1_chain[MAX_ACTION_OUI_STRING_LEN]; uint8_t rssi_weightage; uint8_t ht_caps_weightage; uint8_t vht_caps_weightage; @@ -15751,6 +15881,7 @@ struct hdd_config { bool enable_rtt_mac_randomization; bool enable_ftopen; bool is_unit_test_framework_enabled; + bool disable_channel; uint32_t enable_secondary_rate; bool roam_force_rssi_trigger; }; diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 288f06a5ef1e..360a073b3bb8 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -52,8 +52,8 @@ #include <cdp_txrx_peer_ops.h> #include "wlan_hdd_nan_datapath.h" #include "target_if_def_config.h" -#include "wlan_hdd_apf.h" #include <qdf_idr.h> +#include "wma_sar_public_structs.h" /** Number of Tx Queues */ #ifdef QCA_LL_TX_FLOW_CONTROL_V2 @@ -62,6 +62,16 @@ #define NUM_TX_QUEUES 4 #endif +/* + * API in_compat_syscall() is introduced in 4.6 kernel to check whether we're + * in a compat syscall or not. It is a new way to query the syscall type, which + * works properly on all architectures. + * + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) +static inline bool in_compat_syscall(void) { return is_compat_task(); } +#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) || \ defined(CFG80211_REMOVE_IEEE80211_BACKPORT) #define HDD_NL80211_BAND_2GHZ NL80211_BAND_2GHZ @@ -104,6 +114,8 @@ #define TDLS_INIT_DONE (6) #define ACS_PENDING (7) #define SOFTAP_INIT_DONE (8) +/* Interface went down during SSR*/ +#define DOWN_DURING_SSR (9) /* HDD global event flags */ #define ACS_IN_PROGRESS (0) @@ -1045,6 +1057,14 @@ enum dhcp_nego_status { * @vht_caps: VHT capabilities of current station * @reason_code: Disconnection reason code for current station * @rssi: RSSI of the current station reported from F/W + * @capability: Capability information of current station + * @rx_retry_cnt: Number of rx retries received from current station + * Currently this feature is not supported from FW + * @rx_mc_bc_cnt: Multicast broadcast packet count received from + * current station + * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt + * feature or not, if first bit is 1 it indictes that FW supports this + * feature, if it is 0 it indicates FW doesn't support this feature */ typedef struct { bool isUsed; @@ -1086,6 +1106,9 @@ typedef struct { int8_t rssi; enum dhcp_phase dhcp_phase; enum dhcp_nego_status dhcp_nego_status; + uint16_t capability; + uint32_t rx_mc_bc_cnt; + uint32_t rx_retry_cnt; } hdd_station_info_t; /** @@ -1636,6 +1659,7 @@ struct hdd_adapter_s { qdf_mutex_t ns_offload_info_lock; #endif struct hdd_apf_context apf_context; + bool send_mode_change; }; #define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station) @@ -1727,14 +1751,10 @@ enum smps_mode { }; /** - * struct hdd_chain_rssi_context - hdd chain rssi context - * @response_event: chain rssi request wait event - * @ignore_result: Flag to ignore the result or not - * @chain_rssi: chain rssi array + * struct hdd_chain_rssi_priv - hdd chain rssi private + * @result: chain rssi array */ -struct hdd_chain_rssi_context { - struct completion response_event; - bool ignore_result; +struct hdd_chain_rssi_priv { struct chain_rssi_result result; }; @@ -2016,6 +2036,7 @@ struct hdd_context_s { enum tdls_nss_transition_type tdls_nss_transition_mode; int32_t tdls_teardown_peers_cnt; struct tdls_set_state_info set_state_info; + bool enable_tdls_in_fw; #endif void *hdd_ipa; @@ -2034,10 +2055,7 @@ struct hdd_context_s { #ifdef MSM_PLATFORM /* DDR bus bandwidth compute timer */ - qdf_timer_t bus_bw_timer; - bool bus_bw_timer_running; - qdf_spinlock_t bus_bw_timer_lock; - struct work_struct bus_bw_work; + qdf_mc_timer_t bus_bw_timer; int cur_vote_level; spinlock_t bus_bw_lock; int cur_rx_level; @@ -2107,8 +2125,6 @@ struct hdd_context_s { #ifdef WLAN_FEATURE_EXTWOW_SUPPORT bool is_extwow_app_type1_param_set; bool is_extwow_app_type2_param_set; - bool ext_wow_should_suspend; - struct completion ready_to_extwow; #endif /* Time since boot up to extscan start (in micro seconds) */ @@ -2140,7 +2156,6 @@ struct hdd_context_s { struct hdd_offloaded_packets_ctx op_ctx; #endif bool mcc_mode; - struct hdd_chain_rssi_context chain_rssi_context; struct mutex memdump_lock; uint16_t driver_dump_size; @@ -2158,8 +2173,6 @@ struct hdd_context_s { */ uint32_t fine_time_meas_cap_target; uint32_t rx_high_ind_cnt; - /* completion variable to indicate set antenna mode complete*/ - struct completion set_antenna_mode_cmpl; /* Current number of TX X RX chains being used */ enum antenna_mode current_antenna_mode; bool apf_supported; @@ -2250,6 +2263,9 @@ struct hdd_context_s { /* defining the board related information */ uint32_t hw_bd_id; struct board_info hw_bd_info; + + enum sar_version sar_version; + }; int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter, @@ -2452,7 +2468,6 @@ int hdd_bus_bandwidth_init(hdd_context_t *hdd_ctx); */ void hdd_bus_bandwidth_destroy(hdd_context_t *hdd_ctx); #else - void hdd_bus_bw_compute_timer_start(hdd_context_t *hdd_ctx) { } @@ -2602,8 +2617,6 @@ QDF_STATUS wlan_hdd_check_custom_con_channel_rules(hdd_adapter_t *sta_adapter, void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter); void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter, bool reinit); -void wlan_hdd_soc_set_antenna_mode_cb(enum set_antenna_mode_status status); - #ifdef QCA_CONFIG_SMP int wlan_hdd_get_cpu(void); #else diff --git a/core/hdd/inc/wlan_hdd_napi.h b/core/hdd/inc/wlan_hdd_napi.h index d813a4388295..cdfc84771fc7 100644 --- a/core/hdd/inc/wlan_hdd_napi.h +++ b/core/hdd/inc/wlan_hdd_napi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018 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 @@ -49,7 +49,7 @@ int hdd_napi_poll(struct napi_struct *napi, int budget); struct qca_napi_data *hdd_napi_get_all(void); -#ifdef HELIUMPLUS +#if defined HELIUMPLUS && defined MSM_PLATFORM int hdd_napi_apply_throughput_policy(struct hdd_context_s *hddctx, uint64_t tx_packets, uint64_t rx_packets); @@ -65,7 +65,7 @@ static inline int hdd_napi_serialize(int is_on) { return -EINVAL; }; -#endif /* HELIUMPLUS */ +#endif /* HELIUMPLUS && MSM_PLATFORM */ #else /* ! defined(FEATURE_NAPI) */ #include "hif_napi.h" diff --git a/core/hdd/inc/wlan_hdd_power.h b/core/hdd/inc/wlan_hdd_power.h index f023536b9224..7d3293850444 100644 --- a/core/hdd/inc/wlan_hdd_power.h +++ b/core/hdd/inc/wlan_hdd_power.h @@ -285,5 +285,13 @@ hdd_wlan_fake_apps_suspend(struct wiphy *wiphy, struct net_device *dev) return 0; } #endif /* WLAN_SUSPEND_RESUME_TEST */ - +/** + * hdd_is_interface_down_during_ssr - Check if the interface went down during + * SSR + * @hdd_ctx: HDD context + * + * Check if any of the interface went down while the device is recovering. + * If the interface went down close the session. + */ +void hdd_is_interface_down_during_ssr(hdd_context_t *hdd_ctx); #endif /* __WLAN_HDD_POWER_H */ diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 8aa30132d3de..f607bd06b586 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -251,9 +251,8 @@ void hdd_conn_set_connection_state(hdd_adapter_t *adapter, uint32_t time_buffer_size; /* save the new connection state */ - hdd_debug("%pS Changed conn state from old:%d to new:%d for dev %s", - (void *)_RET_IP_, hdd_sta_ctx->conn_info.connState, - conn_state, adapter->dev->name); + hdd_debug("Changed conn state from old:%d to new:%d for dev %s", + hdd_sta_ctx->conn_info.connState, conn_state, adapter->dev->name); hdd_tsf_notify_wlan_state_change(adapter, hdd_sta_ctx->conn_info.connState, @@ -1841,6 +1840,7 @@ static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter, sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX (pAdapter), pAdapter->sessionId); + pAdapter->send_mode_change = true; } wlan_hdd_clear_link_layer_stats(pAdapter); @@ -1874,6 +1874,10 @@ static void hdd_set_peer_authorized_event(uint32_t vdev_id) hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); hdd_adapter_t *adapter = NULL; + if (!hdd_ctx) { + hdd_err("Invalid hdd context"); + return; + } adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); if (adapter == NULL) { hdd_err("Invalid vdev_id"); @@ -5315,16 +5319,19 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, roamResult); break; case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND: - wlan_hdd_tdls_mgmt_completion_callback(pAdapter, + if (pRoamInfo) + wlan_hdd_tdls_mgmt_completion_callback(pAdapter, pRoamInfo->reasonCode); break; case eCSR_ROAM_TDLS_SET_STATE_DISABLE: - hdd_tdls_notify_set_state_disable(pRoamInfo->sessionId); + if (pRoamInfo) + hdd_tdls_notify_set_state_disable(pRoamInfo->sessionId); break; #endif #ifdef WLAN_FEATURE_11W case eCSR_ROAM_UNPROT_MGMT_FRAME_IND: - hdd_indicate_unprot_mgmt_frame(pAdapter, + if (pRoamInfo) + hdd_indicate_unprot_mgmt_frame(pAdapter, pRoamInfo->nFrameLength, pRoamInfo->pbFrames, pRoamInfo->frameType); @@ -5332,7 +5339,8 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, #endif #ifdef FEATURE_WLAN_ESE case eCSR_ROAM_TSM_IE_IND: - hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid, + if (pRoamInfo) + hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid, pRoamInfo->tsmIe.state, pRoamInfo->tsmIe.msmt_interval); break; @@ -5625,13 +5633,7 @@ hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4]) } #ifdef WLAN_FEATURE_FILS_SK -/* - * hdd_is_fils_connection: API to determine if connection is FILS - * @adapter: hdd adapter - * - * Return: true if fils connection else false - */ -static inline bool hdd_is_fils_connection(hdd_adapter_t *adapter) +bool hdd_is_fils_connection(hdd_adapter_t *adapter) { hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter); @@ -5642,7 +5644,7 @@ static inline bool hdd_is_fils_connection(hdd_adapter_t *adapter) return false; } #else -static inline bool hdd_is_fils_connection(hdd_adapter_t *adapter) +bool hdd_is_fils_connection(hdd_adapter_t *adapter) { return false; } @@ -6266,7 +6268,14 @@ static int __iw_set_essid(struct net_device *dev, } #endif /* FEATURE_WLAN_WAPI */ /* if previous genIE is not NULL, update AssocIE */ - if (0 != pWextState->genIE.length) { + if (pWextState->genIE.length != 0) { + if (pWextState->genIE.length > + (SIR_MAC_MAX_ADD_IE_LENGTH + 2)) { + hdd_err("genIE length exceeds the maximum value: %d", + pWextState->genIE.length); + return -EINVAL; + } + memset(&pWextState->assocAddIE, 0, sizeof(pWextState->assocAddIE)); memcpy(pWextState->assocAddIE.addIEdata, diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 3dcc8fa68eb6..1ecf923053fc 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -5073,6 +5073,12 @@ struct reg_table_entry g_registry_table[] = { VAR_FLAGS_OPTIONAL, (void *)CFG_ACTION_OUI_SWITCH_TO_11N_MODE_DEFAULT), + REG_VARIABLE_STRING(CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_NAME, + WLAN_PARAM_String, + struct hdd_config, action_oui_connect_1x1_with_1_chain, + VAR_FLAGS_OPTIONAL, + (void *)CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_DEFAULT), + REG_VARIABLE(CFG_DTIM_1CHRX_ENABLE_NAME, WLAN_PARAM_Integer, struct hdd_config, enable_dtim_1chrx, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -5603,6 +5609,13 @@ struct reg_table_entry g_registry_table[] = { CFG_ENABLE_UNIT_TEST_FRAMEWORK_MIN, CFG_ENABLE_UNIT_TEST_FRAMEWORK_MAX), + REG_VARIABLE(CFG_ENABLE_DISABLE_CHANNEL_NAME, WLAN_PARAM_Integer, + struct hdd_config, disable_channel, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ENABLE_DISABLE_CHANNEL_DEFAULT, + CFG_ENABLE_DISABLE_CHANNEL_MIN, + CFG_ENABLE_DISABLE_CHANNEL_MAX), + REG_VARIABLE(CFG_ENABLE_SECONDARY_RATE_NAME, WLAN_PARAM_HexInteger, struct hdd_config, enable_secondary_rate, @@ -5619,6 +5632,20 @@ struct reg_table_entry g_registry_table[] = { CFG_ROAM_FORCE_RSSI_TRIGGER_MIN, CFG_ROAM_FORCE_RSSI_TRIGGER_MAX), +#ifdef MWS_COEX + REG_VARIABLE(CFG_MWS_COEX_4G_QUICK_FTDM_NAME, WLAN_PARAM_HexInteger, + struct hdd_config, g_mws_coex_4g_quick_tdm, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_4G_QUICK_FTDM_DEFAULT, + CFG_MWS_COEX_4G_QUICK_FTDM_MIN, + CFG_MWS_COEX_4G_QUICK_FTDM_MAX), + REG_VARIABLE(CFG_MWS_COEX_5G_NR_PWR_LIMIT_NAME, WLAN_PARAM_HexInteger, + struct hdd_config, g_mws_coex_5g_nr_pwr_limit, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MWS_COEX_5G_NR_PWR_LIMIT_DEFAULT, + CFG_MWS_COEX_5G_NR_PWR_LIMIT_MIN, + CFG_MWS_COEX_5G_NR_PWR_LIMIT_MAX), +#endif }; /** @@ -6561,6 +6588,69 @@ static void hdd_cfg_print_sae(hdd_context_t *hdd_ctx) } #endif +#ifdef MWS_COEX +/** + * hdd_cfg_print_mws_coex() - Print MWS-COEX parameters + * @hdd_ctx: Pointer to HDD context + * + * Return: None + */ +static void hdd_cfg_print_mws_coex(hdd_context_t *hdd_ctx) +{ + hdd_debug("Name = [%s] Value = [%u]", + CFG_MWS_COEX_4G_QUICK_FTDM_NAME, + hdd_ctx->config->g_mws_coex_4g_quick_tdm); + + hdd_debug("Name = [%s] Value = [%u]", + CFG_MWS_COEX_5G_NR_PWR_LIMIT_NAME, + hdd_ctx->config->g_mws_coex_5g_nr_pwr_limit); +} +#else +static void hdd_cfg_print_mws_coex(hdd_context_t *hdd_ctx) +{ +} +#endif + +/** + * hdd_cfg_print_action_oui() - print the action OUI configurations + * @hdd_ctx: pointer to the HDD context + * + * Return: None + */ +static void hdd_cfg_print_action_oui(hdd_context_t *hdd_ctx) +{ + struct hdd_config *config = hdd_ctx->config; + + hdd_debug("Name = [%s] value = [%u]", + CFG_ENABLE_ACTION_OUI, + config->enable_action_oui); + + hdd_debug("Name = [%s] value = [%s]", + CFG_ACTION_OUI_CONNECT_1X1_NAME, + config->action_oui_connect_1x1); + + hdd_debug("Name = [%s] value = [%s]", + CFG_ACTION_OUI_ITO_EXTENSION_NAME, + config->action_oui_ito_extension); + + hdd_debug("Name = [%s] value = [%s]", + CFG_ACTION_OUI_CCKM_1X1_NAME, + config->action_oui_cckm_1x1); + + hdd_debug("Name = [%s] value = [%s]", + CFG_ACTION_OUI_ITO_ALTERNATE_NAME, + config->action_oui_ito_alternate); + + hdd_debug("Name = [%s] value = [%s]", + CFG_ACTION_OUI_SWITCH_TO_11N_MODE_NAME, + config->action_oui_switch_to_11n); + + hdd_debug("Name = [%s] value = [%s]", + CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN_NAME, + config->action_oui_connect_1x1_with_1_chain); + +} + /** * hdd_cfg_print() - print the hdd configuration * @iniTable: pointer to hdd context @@ -7490,6 +7580,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_debug("Name = [%s] Value = [%u]", CFG_FORCE_RSNE_OVERRIDE_NAME, pHddCtx->config->force_rsne_override); + hdd_debug("Name = [%s] value = [%d]", + CFG_ENABLE_DISABLE_CHANNEL_NAME, + pHddCtx->config->disable_channel); hdd_debug("Name = [%s] value = [0x%x]", CFG_ENABLE_MAC_PROVISION_NAME, pHddCtx->config->mac_provision); @@ -7523,7 +7616,9 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_debug("Name = [%s] Value = [%u]", CFG_ROAM_FORCE_RSSI_TRIGGER_NAME, pHddCtx->config->roam_force_rssi_trigger); + hdd_cfg_print_mws_coex(pHddCtx); + hdd_cfg_print_action_oui(pHddCtx); } /** @@ -9529,6 +9624,11 @@ void hdd_set_all_sme_action_ouis(hdd_context_t *hdd_ctx) hdd_set_sme_action_oui(hdd_ctx, ini_string, WMI_ACTION_OUI_SWITCH_TO_11N_MODE); + ini_string = config->action_oui_connect_1x1_with_1_chain; + ini_string[MAX_ACTION_OUI_STRING_LEN - 1] = '\0'; + hdd_set_sme_action_oui(hdd_ctx, ini_string, + WMI_ACTION_OUI_CONNECT_1x1_WITH_1_CHAIN); + } /* End of action oui functions */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 9b99ed4c38ef..7fd32d6ac8ee 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -665,6 +665,8 @@ static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = { }; #endif +#define HDD_STATION_INFO_RX_MC_BC_COUNT (1 << 31) + bool hdd_is_ie_valid(const uint8_t *ie, size_t ie_len) { uint8_t elen; @@ -1596,12 +1598,13 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, hdd_context_t *hdd_ctx = wiphy_priv(wiphy); tsap_Config_t *sap_config; struct sk_buff *temp_skbuff; - int ret, i; + int ret, i, ch_cnt = 0; QDF_STATUS status; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1]; bool ht_enabled, ht40_enabled, vht_enabled; uint8_t ch_width; enum qca_wlan_vendor_acs_hw_mode hw_mode; + bool skip_etsi13_srd_chan; /* ***Note*** Donot set SME config related to ACS operation here because * ACS operation is not synchronouse and ACS for Second AP may come when @@ -1770,6 +1773,21 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, goto out; } + skip_etsi13_srd_chan = + !hdd_ctx->config->etsi_srd_chan_in_master_mode && + cds_is_5g_regdmn_etsi13(); + + if (skip_etsi13_srd_chan) { + for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) { + if (cds_is_etsi13_regdmn_srd_chan(sap_config->acs_cfg. + ch_list[i])) + continue; + sap_config->acs_cfg.ch_list[ch_cnt++] = + sap_config->acs_cfg.ch_list[i]; + } + sap_config->acs_cfg.ch_list_count = ch_cnt; + } + hdd_debug("get pcl for DO_ACS vendor command"); /* consult policy manager to get PCL */ @@ -1919,9 +1937,8 @@ void wlan_hdd_undo_acs(hdd_adapter_t *adapter) static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work) { hdd_adapter_t *adapter = container_of(work, hdd_adapter_t, - acs_pending_work.work); - if (!adapter) - return; + acs_pending_work.work); + clear_bit(ACS_PENDING, &adapter->event_flags); wlan_hdd_cfg80211_start_acs(adapter); } @@ -3549,10 +3566,12 @@ static int wlan_hdd_cfg80211_handle_wisa_cmd(struct wiphy *wiphy, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH #define REMOTE_SGI_ENABLE\ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) #define REMOTE_PAD\ - QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD -#endif + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD +#define REMOTE_RX_RETRY_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT +#define REMOTE_RX_BC_MC_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT static const struct nla_policy hdd_get_station_policy[STATION_MAX + 1] = { @@ -4247,6 +4266,11 @@ static uint32_t hdd_add_tx_bitrate_sap_get_len(void) return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN)); } +static uint32_t hdd_add_sta_capability_get_len(void) +{ + return ((NLA_HDRLEN) + (sizeof(uint16_t) + NLA_HDRLEN)); +} + /** * hdd_add_tx_bitrate_sap - add vhs nss info attribute * @skb: pointer to response skb buffer @@ -4289,7 +4313,8 @@ fail: static uint32_t hdd_add_sta_info_sap_get_len(void) { return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) + - hdd_add_tx_bitrate_sap_get_len()); + hdd_add_tx_bitrate_sap_get_len() + + hdd_add_sta_capability_get_len()); } /** @@ -4369,6 +4394,11 @@ static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi, goto fail; } + if (nla_put_u16(skb, NL80211_ATTR_STA_CAPABILITY, + stainfo->capability)) { + hdd_err("put fail"); + goto fail; + } nla_nest_end(skb, nla_attr); return 0; fail: @@ -4498,6 +4528,10 @@ static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx, (sizeof(stainfo->tx_rate) + NLA_HDRLEN) + (sizeof(stainfo->rx_rate) + + NLA_HDRLEN) + + (sizeof(stainfo->rx_mc_bc_cnt) + + NLA_HDRLEN) + + (sizeof(stainfo->rx_retry_cnt) + NLA_HDRLEN); skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); @@ -4536,6 +4570,30 @@ static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx, goto fail; } + /* + * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt + * feature or not, if first bit is 1 it indictes that FW supports this + * feature, if it is 0 it indicates FW doesn't support this feature + */ + if (!(stainfo->rx_mc_bc_cnt & HDD_STATION_INFO_RX_MC_BC_COUNT)) { + hdd_debug("rx mc bc count is not supported by FW"); + } + + else if (nla_put_u32(skb, REMOTE_RX_BC_MC_COUNT, + (stainfo->rx_mc_bc_cnt & + (~HDD_STATION_INFO_RX_MC_BC_COUNT)))) { + hdd_err("rx mc bc put fail"); + goto fail; + } + /* Currently rx_retry count is not supported */ + if (stainfo->rx_retry_cnt) { + if (nla_put_u32(skb, REMOTE_RX_RETRY_COUNT, + stainfo->rx_retry_cnt)) { + hdd_err("rx retry count put fail"); + goto fail; + } + } + qdf_mem_zero(stainfo, sizeof(*stainfo)); return cfg80211_vendor_cmd_reply(skb); @@ -5180,6 +5238,8 @@ void wlan_hdd_save_gtk_offload_params(hdd_adapter_t *adapter, uint8_t *kck_ptr, qdf_copy_macaddr(&hdd_sta_ctx->gtkOffloadReqParams.bssid, &hdd_sta_ctx->conn_info.bssId); hdd_sta_ctx->gtkOffloadReqParams.kek_len = kek_len; + hdd_sta_ctx->gtkOffloadReqParams.is_fils_connection = + hdd_is_fils_connection(adapter); /* * changing from big to little endian since driver * works on little endian format @@ -5733,6 +5793,12 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, override_li = nla_get_u32( tb[QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL]); + if (override_li > CFG_ENABLE_DYNAMIC_DTIM_MAX) { + hdd_err_ratelimited(HDD_NL_ERR_RATE_LIMIT, + "Invalid value for listen interval - %d", + override_li); + return -EINVAL; + } status = sme_override_listen_interval(hdd_ctx->hHal, adapter->sessionId, override_li); @@ -9245,6 +9311,7 @@ __wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy, uint16_t unsafe_channel_index, local_unsafe_list_count; tHddAvoidFreqList *channel_list; enum tQDF_GLOBAL_CON_MODE curr_mode; + uint8_t num_args = 0; ENTER_DEV(wdev->netdev); @@ -9262,11 +9329,27 @@ __wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy, ret = wlan_hdd_validate_context(hdd_ctx); if (0 != ret) return ret; + if (!data || data_len < (sizeof(channel_list->avoidFreqRangeCount) + + sizeof(tHddAvoidFreqRange))) { + hdd_err("Avoid frequency channel list empty"); + return -EINVAL; + } + num_args = (data_len - sizeof(channel_list->avoidFreqRangeCount)) / + sizeof(channel_list->avoidFreqRange[0].startFreq); + + if (num_args < 2 || num_args > HDD_MAX_AVOID_FREQ_RANGES * 2 || + num_args % 2 != 0) { + hdd_err("Invalid avoid frequency channel list"); + return -EINVAL; + } channel_list = (tHddAvoidFreqList *)data; - if (!channel_list) { - hdd_log(QDF_TRACE_LEVEL_ERROR, - "Avoid frequency channel list empty"); + + if (channel_list->avoidFreqRangeCount == 0 || + channel_list->avoidFreqRangeCount > HDD_MAX_AVOID_FREQ_RANGES || + 2 * channel_list->avoidFreqRangeCount != num_args) { + hdd_err("Invalid frequency range count %d", + channel_list->avoidFreqRangeCount); return -EINVAL; } @@ -9929,6 +10012,96 @@ static int wlan_hdd_cfg80211_sar_convert_limit_set(u32 nl80211_value, return ret; } +#ifdef WLAN_FEATURE_SARV1_TO_SARV2 +/** + * hdd_convert_sarv1_to_sarv2() - convert SAR V1 BDF reference to SAR V2 + * @hdd_ctx: The HDD global context + * @tb: The parsed array of netlink attributes + * @sar_limit_cmd: The WMI command to be filled + * + * This feature/function is designed to solve the following problem: + * 1) Userspace application was written to use SARv1 BDF entries + * 2) Product is configured with SAR V2 BDF entries + * + * So if this feature is enabled, and if the firmware is configured + * with SAR V2 support, and if the incoming request is to enable a SAR + * V1 BDF entry, then the WMI command is generated to actually + * configure a SAR V2 BDF entry. + * + * Return: true if conversion was performed and @sar_limit_cmd is + * ready to be sent to firmware. Otherwise false in which case the + * normal parsing logic should be applied. + */ + +static bool +hdd_convert_sarv1_to_sarv2(hdd_context_t *hdd_ctx, + struct nlattr *tb[], + struct sar_limit_cmd_params *sar_limit_cmd) +{ + struct nlattr *attr; + uint32_t bdf_index, set; + struct sar_limit_cmd_row *row; + + if (hdd_ctx->sar_version != SAR_VERSION_2) { + hdd_debug("SAR version: %d", hdd_ctx->sar_version); + return false; + } + + attr = tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE]; + if (!attr) + return false; + + bdf_index = nla_get_u32(attr); + + if ((bdf_index >= QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0) && + (bdf_index <= QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4)) { + set = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0; + } else if (bdf_index == QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE) { + set = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE; + bdf_index = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0; + } else { + return false; + } + + /* Need two rows to hold the per-chain V2 power index + * To disable SARv2 limit, send chain, num_limits_row and + * power limit set to 0 (except power index 0xff) + */ + row = qdf_mem_malloc(2 * sizeof(*row)); + if (!row) + return false; + + if (wlan_hdd_cfg80211_sar_convert_limit_set( + set, &sar_limit_cmd->sar_enable)) { + hdd_err("Failed to convert SAR limit to WMI value"); + return false; + } + + sar_limit_cmd->commit_limits = 1; + sar_limit_cmd->num_limit_rows = 2; + sar_limit_cmd->sar_limit_row_list = row; + row[0].limit_value = bdf_index; + row[1].limit_value = row[0].limit_value; + row[0].chain_id = 0; + row[1].chain_id = 1; + row[0].validity_bitmap = WMI_SAR_CHAIN_ID_VALID_MASK; + row[1].validity_bitmap = WMI_SAR_CHAIN_ID_VALID_MASK; + + return true; +} + +#else /* WLAN_FEATURE_SARV1_TO_SARV2 */ + +static bool +hdd_convert_sarv1_to_sarv2(hdd_context_t *hdd_ctx, + struct nlattr *tb[], + struct sar_limit_cmd_params *sar_limit_cmd) +{ + return false; +} + +#endif /* WLAN_FEATURE_SARV1_TO_SARV2 */ + /** * wlan_hdd_cfg80211_sar_convert_band() - Convert WLAN band value * @nl80211_value: Vendor command attribute value @@ -10326,6 +10499,10 @@ static int __wlan_hdd_set_sar_power_limits(struct wiphy *wiphy, return -EINVAL; } + /* is special SAR V1 => SAR V2 logic enabled and applicable? */ + if (hdd_convert_sarv1_to_sarv2(hdd_ctx, tb, &sar_limit_cmd)) + goto send_sar_limits; + /* Vendor command manadates all SAR Specs in single call */ sar_limit_cmd.commit_limits = 1; sar_limit_cmd.sar_enable = WMI_SAR_FEATURE_NO_CHANGE; @@ -10885,11 +11062,12 @@ end: * * Return: 0 for success, non-zero for failure */ -static int hdd_post_get_chain_rssi_rsp(hdd_context_t *hdd_ctx) +static int hdd_post_get_chain_rssi_rsp(hdd_context_t *hdd_ctx, + struct hdd_chain_rssi_priv *priv) { struct sk_buff *skb = NULL; - struct chain_rssi_result *result = - &hdd_ctx->chain_rssi_context.result; + struct chain_rssi_result *result = &priv->result; + int rc = 0; skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, (sizeof(result->chain_rssi) + NLA_HDRLEN) + @@ -10897,7 +11075,7 @@ static int hdd_post_get_chain_rssi_rsp(hdd_context_t *hdd_ctx) NLMSG_HDRLEN); if (!skb) { - hdd_err(FL("cfg80211_vendor_event_alloc failed")); + hdd_err("cfg80211_vendor_event_alloc failed"); return -ENOMEM; } @@ -10908,19 +11086,19 @@ static int hdd_post_get_chain_rssi_rsp(hdd_context_t *hdd_ctx) goto nla_put_failure; } - if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO, - sizeof(result->ant_id), - result->ant_id)) { - hdd_err(FL("put fail")); + rc = nla_put(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO, + sizeof(result->ant_id), result->ant_id); + if (rc) { + hdd_err("put fail"); goto nla_put_failure; } cfg80211_vendor_cmd_reply(skb); - return 0; + return rc; nla_put_failure: kfree_skb(skb); - return -EINVAL; + return rc; } /** @@ -10940,13 +11118,18 @@ static int __wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy, hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev); struct get_chain_rssi_req_params req_msg; hdd_context_t *hdd_ctx = wiphy_priv(wiphy); - struct hdd_chain_rssi_context *context; + struct hdd_chain_rssi_priv *priv; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1]; QDF_STATUS status; int retval; - unsigned long rc; const int mac_len = sizeof(req_msg.peer_macaddr); int msg_len; + struct hdd_request *request; + void *cookie; + static struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_CHAIN_RSSI, + }; ENTER(); @@ -10978,33 +11161,42 @@ static int __wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]), mac_len); req_msg.session_id = pAdapter->sessionId; - spin_lock(&hdd_context_lock); - context = &hdd_ctx->chain_rssi_context; - INIT_COMPLETION(context->response_event); - context->ignore_result = false; - spin_unlock(&hdd_context_lock); + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request Allocation Failure"); + return -ENOMEM; + } + + cookie = hdd_request_cookie(request); + + priv = hdd_request_priv(request); + + sme_chain_rssi_register_callback(hdd_ctx->hHal, + wlan_hdd_cfg80211_chainrssi_callback, + cookie); status = sme_get_chain_rssi(hdd_ctx->hHal, &req_msg); if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err(FL("sme_get_chain_rssi failed(err=%d)"), status); - return -EINVAL; + hdd_err("sme_get_chain_rssi failed(err=%d)", status); + retval = -EINVAL; + goto exit; } - rc = wait_for_completion_timeout(&context->response_event, - msecs_to_jiffies(WLAN_WAIT_TIME_CHAIN_RSSI)); - if (!rc) { - hdd_err(FL("Target response timed out")); - spin_lock(&hdd_context_lock); - context->ignore_result = true; - spin_unlock(&hdd_context_lock); - return -ETIMEDOUT; + retval = hdd_request_wait_for_response(request); + if (retval) { + hdd_err("Target response timed out for get chain rssi"); + retval = -ETIMEDOUT; + goto exit; } - retval = hdd_post_get_chain_rssi_rsp(hdd_ctx); + retval = hdd_post_get_chain_rssi_rsp(hdd_ctx, priv); if (retval) - hdd_err(FL("Failed to send chain rssi to user space")); + hdd_err("Failed to send chain rssi to user space"); EXIT(); +exit: + sme_chain_rssi_deregister_callback(hdd_ctx->hHal); + hdd_request_put(request); return retval; } @@ -11030,32 +11222,27 @@ static int wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy, return ret; } -void wlan_hdd_cfg80211_chainrssi_callback(void *ctx, void *pmsg) +void wlan_hdd_cfg80211_chainrssi_callback(void *ctx, void *pmsg, void *cookie) { - hdd_context_t *hdd_ctx = (hdd_context_t *)ctx; struct chain_rssi_result *data = (struct chain_rssi_result *)pmsg; - struct hdd_chain_rssi_context *context; - bool ignore_result; + struct hdd_chain_rssi_priv *priv = NULL; + struct hdd_request *request = NULL; ENTER(); - if (wlan_hdd_validate_context(hdd_ctx)) - return; - - spin_lock(&hdd_context_lock); - context = &hdd_ctx->chain_rssi_context; - ignore_result = context->ignore_result; - - if (ignore_result) { - hdd_err(FL("Ignore the result received after timeout")); - spin_unlock(&hdd_context_lock); + request = hdd_request_get(cookie); + if (!request) { + hdd_err("Obselete request"); return; } - memcpy(&context->result, data, sizeof(*data)); + priv = hdd_request_priv(request); + + memcpy(&priv->result, data, sizeof(*data)); - complete(&context->response_event); - spin_unlock(&hdd_context_lock); + hdd_request_complete(request); + hdd_request_put(request); + EXIT(); } /** @@ -14491,6 +14678,7 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, eCsrRoamBssType LastBSSType; struct hdd_config *pConfig = NULL; int status; + bool dev_flags = (ndev->flags & IFF_UP); ENTER(); @@ -14562,10 +14750,13 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, type, status); return status; } - if (hdd_start_adapter(pAdapter)) { - hdd_err("Failed to start adapter :%d", + + if (dev_flags) { + if (hdd_start_adapter(pAdapter)) { + hdd_err("Failed to start adapter :%d", pAdapter->device_mode); - return -EINVAL; + return -EINVAL; + } } goto done; case NL80211_IFTYPE_AP: @@ -14615,9 +14806,12 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, hdd_set_ap_ops(pAdapter->dev); - if (hdd_start_adapter(pAdapter)) { - hdd_err("Error initializing the ap mode"); - return -EINVAL; + if (dev_flags) { + if (hdd_start_adapter(pAdapter)) { + hdd_err("Failed to start adapter :%d", + pAdapter->device_mode); + return -EINVAL; + } } /* Interface type changed update in wiphy structure */ if (wdev) { @@ -14643,11 +14837,14 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, type); if (status != QDF_STATUS_SUCCESS) return status; - if (hdd_start_adapter(pAdapter)) { - hdd_err("Failed to start adapter: %d", + if (dev_flags) { + if (hdd_start_adapter(pAdapter)) { + hdd_err("Failed to start adapter :%d", pAdapter->device_mode); - return -EINVAL; + return -EINVAL; + } } + goto done; case NL80211_IFTYPE_AP: @@ -14813,6 +15010,7 @@ static int __wlan_hdd_change_station(struct wiphy *wiphy, hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *pHddCtx; hdd_station_ctx_t *pHddStaCtx; + hdd_ap_ctx_t *hdd_ap_ctx; struct qdf_mac_addr STAMacAddress; #ifdef FEATURE_WLAN_TDLS tCsrStaParams StaParams = { 0 }; @@ -14850,20 +15048,23 @@ static int __wlan_hdd_change_station(struct wiphy *wiphy, if ((pAdapter->device_mode == QDF_SAP_MODE) || (pAdapter->device_mode == QDF_P2P_GO_MODE)) { if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) { - status = - hdd_softap_change_sta_state(pAdapter, - &STAMacAddress, - OL_TXRX_PEER_STATE_AUTH); - - if (status != QDF_STATUS_SUCCESS) { - hdd_debug("Not able to change TL state to AUTHENTICATED"); - return -EINVAL; + hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter); + /* + * For Encrypted SAP session, this will be done as + * part of eSAP_STA_SET_KEY_EVENT + */ + if (hdd_ap_ctx->ucEncryptType != + eCSR_ENCRYPT_TYPE_NONE) { + hdd_debug("Encrypt type %d, not setting peer authorized now", + hdd_ap_ctx->ucEncryptType); + return 0; } - status = wlan_hdd_send_sta_authorized_event( - pAdapter, - pHddCtx, - &STAMacAddress); - if (status != QDF_STATUS_SUCCESS) { + + status = hdd_softap_set_peer_authorized(pAdapter, + &STAMacAddress); + + if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("Failed to authorize peer"); return -EINVAL; } } @@ -15385,6 +15586,11 @@ static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy, return -EINVAL; } + if (pAdapter->send_mode_change) { + wlan_hdd_send_mode_change_event(); + pAdapter->send_mode_change = false; + } + /* in case of IBSS as there was no information available about WEP keys during * IBSS join, group key intialized with NULL key, so re-initialize group key * with correct value*/ @@ -18071,6 +18277,60 @@ static int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter, return status; } +/** + * wlan_hdd_clear_wapi_privacy() - reset WAPI settings in HDD layer + * @adapter: pointer to HDD adapter object + * + * This function resets all WAPI related parameters imposed before STA + * connection starts. It's invoked when privacy checking against concurrency + * fails, to make sure no improper WAPI settings are still populated before + * returning an error to the upper layer requester. + * + * Return: none + */ +#ifdef FEATURE_WLAN_WAPI +static inline void wlan_hdd_clear_wapi_privacy(hdd_adapter_t *adapter) +{ + adapter->wapi_info.nWapiMode = 0; + adapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN; +} +#else +static inline void wlan_hdd_clear_wapi_privacy(hdd_adapter_t *adapter) +{ +} +#endif + +/** + * wlan_hdd_cfg80211_clear_privacy() - reset STA security parameters + * @adapter: pointer to HDD adapter object + * + * This function resets all privacy related parameters imposed + * before STA connection starts. It's invoked when privacy checking + * against concurrency fails, to make sure no improper settings are + * still populated before returning an error to the upper layer requester. + * + * Return: none + */ +static void wlan_hdd_cfg80211_clear_privacy(hdd_adapter_t *adapter) +{ + hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter); + hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + hdd_debug("reseting all privacy configurations"); + + wext_state->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED; + + hdd_sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_NONE; + wext_state->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_NONE; + + hdd_sta_ctx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + wext_state->roamProfile.EncryptionType.numEntries = 0; + hdd_sta_ctx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE; + wext_state->roamProfile.mcEncryptionType.numEntries = 0; + + wlan_hdd_clear_wapi_privacy(adapter); +} + int wlan_hdd_try_disconnect(hdd_adapter_t *pAdapter) { unsigned long rc; @@ -18363,8 +18623,10 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, * Check if this is reassoc to same bssid, if reassoc is success, return */ status = wlan_hdd_reassoc_bssid_hint(pAdapter, req); - if (!status) + if (!status) { + hdd_set_roaming_in_progress(true); return status; + } /* Try disconnecting if already in connected state */ status = wlan_hdd_try_disconnect(pAdapter); @@ -18373,32 +18635,39 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, return -EALREADY; } - /* Check for max concurrent connections after doing disconnect if any */ + /*initialise security parameters */ + status = wlan_hdd_cfg80211_set_privacy(pAdapter, req); + + if (0 > status) { + hdd_err("Failed to set security params"); + return status; + } + + /* + * Check for max concurrent connections after doing disconnect if any, + * must be called after the invocation of wlan_hdd_cfg80211_set_privacy + * so privacy is already set for the current adapter before it's + * checked against concurrency. + */ if (req->channel) { if (!cds_allow_concurrency( cds_convert_device_mode_to_qdf_type( pAdapter->device_mode), req->channel->hw_value, HW_MODE_20_MHZ)) { hdd_warn("This concurrency combination is not allowed"); - return -ECONNREFUSED; + status = -ECONNREFUSED; + goto con_chk_failed; } } else { if (!cds_allow_concurrency( cds_convert_device_mode_to_qdf_type( pAdapter->device_mode), 0, HW_MODE_20_MHZ)) { hdd_warn("This concurrency combination is not allowed"); - return -ECONNREFUSED; + status = -ECONNREFUSED; + goto con_chk_failed; } } - /*initialise security parameters */ - status = wlan_hdd_cfg80211_set_privacy(pAdapter, req); - - if (0 > status) { - hdd_err("Failed to set security params"); - return status; - } - if (req->channel) channel = req->channel->hw_value; else @@ -18411,8 +18680,11 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, bssid_hint, channel, 0); if (0 > status) { hdd_err("connect failed"); - return status; } + return status; + +con_chk_failed: + wlan_hdd_cfg80211_clear_privacy(pAdapter); EXIT(); return status; } @@ -18440,20 +18712,21 @@ static int wlan_hdd_cfg80211_connect(struct wiphy *wiphy, int wlan_hdd_disconnect(hdd_adapter_t *pAdapter, u16 reason) { - int status, result = 0; + QDF_STATUS status; + int result = 0; unsigned long rc; - hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + hdd_station_ctx_t *hdd_sta_ctx; + hdd_context_t *hdd_ctx; eConnectionState prev_conn_state; - tHalHandle hal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tHalHandle hal; uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT; ENTER(); - status = wlan_hdd_validate_context(pHddCtx); + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + hdd_ctx = WLAN_HDD_GET_CTX(pAdapter); + hal = WLAN_HDD_GET_HAL_CTX(pAdapter); - if (0 != status) - return status; if (pAdapter->device_mode == QDF_STA_MODE) { sme_indicate_disconnect_inprogress(hal, pAdapter->sessionId); hdd_debug("Stop firmware roaming"); @@ -18465,7 +18738,7 @@ int wlan_hdd_disconnect(hdd_adapter_t *pAdapter, u16 reason) * */ INIT_COMPLETION(pAdapter->roaming_comp_var); - if (hdd_is_roaming_in_progress(pHddCtx)) { + if (hdd_is_roaming_in_progress(hdd_ctx)) { rc = wait_for_completion_timeout( &pAdapter->roaming_comp_var, msecs_to_jiffies(WLAN_WAIT_TIME_STOP_ROAM)); @@ -18486,7 +18759,7 @@ int wlan_hdd_disconnect(hdd_adapter_t *pAdapter, u16 reason) } } - prev_conn_state = pHddStaCtx->conn_info.connState; + prev_conn_state = hdd_sta_ctx->conn_info.connState; /*stop tx queues */ hdd_info("Disabling queues"); wlan_hdd_netif_queue_control(pAdapter, @@ -18523,7 +18796,7 @@ int wlan_hdd_disconnect(hdd_adapter_t *pAdapter, u16 reason) hdd_debug("Already disconnected or connect was in sme/roam pending list and removed by disconnect"); } else if (0 != status) { hdd_err("csr_roam_disconnect failure, status: %d", (int)status); - pHddStaCtx->staDebugState = status; + hdd_sta_ctx->staDebugState = status; result = -EINVAL; goto disconnected; } diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 173ccc116e52..b2d39fa6eacc 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -459,12 +459,14 @@ void wlan_hdd_rso_cmd_status_cb(void *ctx, struct rso_cmd_status *rso_status); /** * wlan_hdd_cfg80211_chainrssi_callback - chainrssi callback - * @ctx: hdd context + * @hdd_ctx: hdd context * @pmsg: pmsg + * @context: callback context * * Return: void */ -void wlan_hdd_cfg80211_chainrssi_callback(void *ctx, void *pmsg); +void wlan_hdd_cfg80211_chainrssi_callback(void *hdd_ctx, void *pmsg, + void *context); void hdd_rssi_threshold_breached(void *hddctx, struct rssi_breach_event *data); diff --git a/core/hdd/src/wlan_hdd_debugfs.c b/core/hdd/src/wlan_hdd_debugfs.c index 6ee6020e7644..c757a6be00c0 100644 --- a/core/hdd/src/wlan_hdd_debugfs.c +++ b/core/hdd/src/wlan_hdd_debugfs.c @@ -593,8 +593,7 @@ static void hdd_power_debugstats_cb(struct power_stats_response *response, power_stats->cumulative_sleep_time_ms = response->cumulative_sleep_time_ms; power_stats->cumulative_total_on_time_ms - = response->cumulative_total_on_time_ms - - response->cumulative_sleep_time_ms; + = response->cumulative_total_on_time_ms; power_stats->deep_sleep_enter_counter = response->deep_sleep_enter_counter; power_stats->last_deep_sleep_enter_tstamp_ms diff --git a/core/hdd/src/wlan_hdd_debugfs_roam.c b/core/hdd/src/wlan_hdd_debugfs_roam.c index b04b6ffa8c26..a6baaac183d9 100644 --- a/core/hdd/src/wlan_hdd_debugfs_roam.c +++ b/core/hdd/src/wlan_hdd_debugfs_roam.c @@ -213,7 +213,6 @@ static char *hdd_roam_scan_trigger_to_str(uint32_t roam_scan_trigger) default: return "UNKNOWN REASON"; } - return "UNKNOWN REASON"; } /** @@ -278,7 +277,6 @@ static char *hdd_client_id_to_str(uint32_t client_id) default: return "UNKNOWN"; } - return "UNKNOWN"; } /** diff --git a/core/hdd/src/wlan_hdd_disa.c b/core/hdd/src/wlan_hdd_disa.c index 064f5526b718..721b52f4ef1d 100644 --- a/core/hdd/src/wlan_hdd_disa.c +++ b/core/hdd/src/wlan_hdd_disa.c @@ -25,49 +25,50 @@ #include "wlan_hdd_disa.h" #include "sme_api.h" +#include "wlan_hdd_request_manager.h" -#define ENCRYPT_DECRYPT_CONTEXT_MAGIC 0x4475354 #define WLAN_WAIT_TIME_ENCRYPT_DECRYPT 1000 - /** * hdd_encrypt_decrypt_msg_context - hdd encrypt/decrypt message context - * - * @magic: magic number - * @completion: Completion variable for encrypt/decrypt message - * @response_event: encrypt/decrypt message request wait event + * @status: status of response. 0: no error, -ENOMEM: unable to allocate + * memory for the response payload + * @request: encrypt/decrypt request + * @response: encrypt/decrypt response */ struct hdd_encrypt_decrypt_msg_context { - unsigned int magic; - struct completion completion; + int status; + struct encrypt_decrypt_req_params request; struct sir_encrypt_decrypt_rsp_params response; }; -static struct hdd_encrypt_decrypt_msg_context encrypt_decrypt_msg_context; /** - * hdd_encrypt_decrypt_msg_cb () - sends encrypt/decrypt data to user space + * hdd_encrypt_decrypt_msg_cb () - encrypt/decrypt response message handler + * @cookie: hdd request cookie * @encrypt_decrypt_rsp_params: encrypt/decrypt response parameters * * Return: none */ -static void hdd_encrypt_decrypt_msg_cb(void *hdd_context, - struct sir_encrypt_decrypt_rsp_params *encrypt_decrypt_rsp_params) +static void hdd_encrypt_decrypt_msg_cb(void *cookie, + struct sir_encrypt_decrypt_rsp_params + *encrypt_decrypt_rsp_params) { - hdd_context_t *hdd_ctx = hdd_context; - int ret; + struct hdd_request *request; struct hdd_encrypt_decrypt_msg_context *context; ENTER(); - ret = wlan_hdd_validate_context(hdd_ctx); - if (ret) - return; - if (!encrypt_decrypt_rsp_params) { hdd_err("rsp params is NULL"); return; } + request = hdd_request_get(cookie); + if (!request) { + hdd_err("obsolete request"); + return; + } + print_hex_dump(KERN_INFO, "Data in hdd_encrypt_decrypt_msg_cb: ", DUMP_PREFIX_NONE, 16, 1, encrypt_decrypt_rsp_params->data, @@ -78,52 +79,42 @@ static void hdd_encrypt_decrypt_msg_cb(void *hdd_context, encrypt_decrypt_rsp_params->status, encrypt_decrypt_rsp_params->data_length); - spin_lock(&hdd_context_lock); + context = hdd_request_priv(request); - context = &encrypt_decrypt_msg_context; - /* The caller presumably timed out so there is nothing we can do */ - if (context->magic != ENCRYPT_DECRYPT_CONTEXT_MAGIC) { - spin_unlock(&hdd_context_lock); - return; - } - - /* context is valid so caller is still waiting */ context->response = *encrypt_decrypt_rsp_params; if (encrypt_decrypt_rsp_params->data_length) { context->response.data = qdf_mem_malloc(sizeof(uint8_t) * encrypt_decrypt_rsp_params->data_length); - if (context->response.data == NULL) { - hdd_err("cdf_mem_alloc failed for data"); - spin_unlock(&hdd_context_lock); + if (!context->response.data) { + hdd_err("memory allocation failed"); + context->status = -ENOMEM; + hdd_request_complete(request); + hdd_request_put(request); return; + } else { + qdf_mem_copy(context->response.data, + encrypt_decrypt_rsp_params->data, + encrypt_decrypt_rsp_params->data_length); } - qdf_mem_copy(context->response.data, - encrypt_decrypt_rsp_params->data, - encrypt_decrypt_rsp_params->data_length); + } else { + /* make sure we don't have a rogue pointer */ + context->response.data = NULL; } - /* - * Indicate to calling thread that - * response data is available - */ - context->magic = 0; - - complete(&context->completion); - - spin_unlock(&hdd_context_lock); - + hdd_request_complete(request); + hdd_request_put(request); EXIT(); } - /** - * hdd_encrypt_decrypt_msg_cb () - sends encrypt/decrypt data to user space + * hdd_post_encrypt_decrypt_msg_rsp () - sends encrypt/decrypt msg to user space + * @hdd_ctx: pointer to hdd context * @encrypt_decrypt_rsp_params: encrypt/decrypt response parameters * - * Return: none + * Return: 0 on success, negative errno on failure */ static int hdd_post_encrypt_decrypt_msg_rsp(hdd_context_t *hdd_ctx, struct sir_encrypt_decrypt_rsp_params *encrypt_decrypt_rsp_params) @@ -331,7 +322,7 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params encrypt_decrypt_params->data_len); if (encrypt_decrypt_params->data == NULL) { - hdd_err("cdf_mem_alloc failed for data"); + hdd_err("memory allocation failed"); return -ENOMEM; } @@ -349,111 +340,119 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params } /** + * hdd_encrypt_decrypt_context_dealloc() - deallocate memory allocated for data + * @priv: Pointer to private data + * + * Return: None + */ +static void hdd_encrypt_decrypt_context_dealloc(void *priv) +{ + struct hdd_encrypt_decrypt_msg_context *context = priv; + + if (context->request.data) { + qdf_mem_free(context->request.data); + context->request.data = NULL; + } + + if (context->response.data) { + qdf_mem_free(context->response.data); + context->response.data = NULL; + } +} + +/** * hdd_encrypt_decrypt_msg () - process encrypt/decrypt message * @adapter : adapter context * @hdd_ctx: hdd context * @data: Pointer to data * @data_len: Data length * - Return: 0 on success, negative errno on failure + * Return: 0 on success, negative errno on failure */ static int hdd_encrypt_decrypt_msg(hdd_adapter_t *adapter, - hdd_context_t *hdd_ctx, - const void *data, - int data_len) + hdd_context_t *hdd_ctx, + const void *data, + int data_len) { - struct encrypt_decrypt_req_params encrypt_decrypt_params = {0}; QDF_STATUS qdf_status; int ret; + void *cookie; + struct hdd_request *request; struct hdd_encrypt_decrypt_msg_context *context; - unsigned long rc; + static const struct hdd_request_params params = { + .priv_size = sizeof(*context), + .timeout_ms = WLAN_WAIT_TIME_ENCRYPT_DECRYPT, + .dealloc = hdd_encrypt_decrypt_context_dealloc, + }; + + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request Allocation Failure"); + return -ENOMEM; + } + context = hdd_request_priv(request); - ret = hdd_fill_encrypt_decrypt_params(&encrypt_decrypt_params, - adapter, data, data_len); + ret = hdd_fill_encrypt_decrypt_params(&context->request, + adapter, data, data_len); if (ret) - return ret; + goto clean_up; - spin_lock(&hdd_context_lock); - context = &encrypt_decrypt_msg_context; - context->magic = ENCRYPT_DECRYPT_CONTEXT_MAGIC; - INIT_COMPLETION(context->completion); - spin_unlock(&hdd_context_lock); + cookie = hdd_request_cookie(request); - qdf_status = sme_encrypt_decrypt_msg(hdd_ctx->hHal, - &encrypt_decrypt_params); + qdf_status = sme_encrypt_decrypt_msg_register_callback(hdd_ctx->hHal, + hdd_encrypt_decrypt_msg_cb); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + hdd_err("Encrypt/Decrypt callback failed %d", qdf_status); + ret = -EINVAL; + goto clean_up; + } - qdf_mem_free(encrypt_decrypt_params.data); + qdf_status = sme_encrypt_decrypt_msg(hdd_ctx->hHal, + &context->request, + cookie); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("Unable to post encrypt/decrypt message"); - return -EINVAL; + ret = -EINVAL; + goto deregister_cb; } - rc = wait_for_completion_timeout(&context->completion, - msecs_to_jiffies(WLAN_WAIT_TIME_ENCRYPT_DECRYPT)); - - spin_lock(&hdd_context_lock); - if (!rc && (context->magic == - ENCRYPT_DECRYPT_CONTEXT_MAGIC)) { + ret = hdd_request_wait_for_response(request); + if (ret) { hdd_err("Target response timed out"); - context->magic = 0; - spin_unlock(&hdd_context_lock); - return -ETIMEDOUT; + goto deregister_cb; } - spin_unlock(&hdd_context_lock); - ret = hdd_post_encrypt_decrypt_msg_rsp(hdd_ctx, - &encrypt_decrypt_msg_context.response); + ret = context->status; + if (ret) { + hdd_err("Target response processing failed"); + goto deregister_cb; + } + + ret = hdd_post_encrypt_decrypt_msg_rsp(hdd_ctx, &context->response); if (ret) hdd_err("Failed to post encrypt/decrypt message response"); - qdf_mem_free(encrypt_decrypt_msg_context.response.data); +deregister_cb: + qdf_status = sme_encrypt_decrypt_msg_deregister_callback(hdd_ctx->hHal); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + hdd_err("De-register encrypt/decrypt callback failed: %d", + qdf_status); + ret = -EINVAL; + } +clean_up: + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + hdd_request_put(request); EXIT(); return ret; } /** - * hdd_encrypt_decrypt_init () - exposes encrypt/decrypt initialization - * functionality - * @hdd_ctx: hdd context - * - Return: 0 on success, negative errno on failure - */ -int hdd_encrypt_decrypt_init(hdd_context_t *hdd_ctx) -{ - QDF_STATUS status; - - init_completion(&encrypt_decrypt_msg_context.completion); - - status = sme_encrypt_decrypt_msg_register_callback(hdd_ctx->hHal, - hdd_encrypt_decrypt_msg_cb); - if (!QDF_IS_STATUS_SUCCESS(status)) { - hdd_err("encrypt/decrypt callback failed %d", status); - return -EINVAL; - } - return 0; -} - -/** - * hdd_encrypt_decrypt_deinit () - exposes encrypt/decrypt deinitialization - * functionality - * @hdd_ctx: hdd context - * - Return: 0 on success, negative errno on failure - */ -int hdd_encrypt_decrypt_deinit(hdd_context_t *hdd_ctx) -{ - QDF_STATUS status; - - status = sme_encrypt_decrypt_msg_deregister_callback(hdd_ctx->hHal); - if (!QDF_IS_STATUS_SUCCESS(status)) - hdd_err("De-register encrypt/decrypt callback failed: %d", - status); - return 0; -} - -/** * __wlan_hdd_cfg80211_encrypt_decrypt_msg () - Encrypt/Decrypt msg * @wiphy: Pointer to wireless phy * @wdev: Pointer to wireless device diff --git a/core/hdd/src/wlan_hdd_disa.h b/core/hdd/src/wlan_hdd_disa.h index b35c02c5dbbe..c9b6eed8f19d 100644 --- a/core/hdd/src/wlan_hdd_disa.h +++ b/core/hdd/src/wlan_hdd_disa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018 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 @@ -22,34 +22,6 @@ #include "wlan_hdd_main.h" #include "sir_api.h" -#ifdef WLAN_FEATURE_DISA -/** - * hdd_encrypt_decrypt_init () - exposes encrypt/decrypt initialization - * functionality - * @hdd_ctx: hdd context - * - Return: 0 on success, negative errno on failure - */ -int hdd_encrypt_decrypt_init(hdd_context_t *hdd_ctx); - -/** - * hdd_encrypt_decrypt_deinit () - exposes encrypt/decrypt deinitialization - * functionality - * @hdd_ctx: hdd context - * - Return: 0 on success, negative errno on failure - */ -int hdd_encrypt_decrypt_deinit(hdd_context_t *hdd_ctx); -#else -static inline int hdd_encrypt_decrypt_init(hdd_context_t *hdd_ctx) -{ - return -ENOTSUPP; -} -static inline int hdd_encrypt_decrypt_deinit(hdd_context_t *hdd_ctx) -{ - return -ENOTSUPP; -} -#endif #ifdef WLAN_FEATURE_DISA /** diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 546009777711..507ae0145a38 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -1371,7 +1371,11 @@ static void hdd_cleanup_on_fw_down(void) static void wlan_hdd_set_the_pld_uevent(struct pld_uevent_data *uevent) { switch (uevent->uevent) { + case PLD_FW_DOWN: + cds_set_target_ready(false); + break; case PLD_RECOVERY: + cds_set_target_ready(false); cds_set_recovery_in_progress(true); break; default: diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c index 7f8b1c35ad3b..547955c429f7 100644 --- a/core/hdd/src/wlan_hdd_ext_scan.c +++ b/core/hdd/src/wlan_hdd_ext_scan.c @@ -733,7 +733,9 @@ wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind( for (j = 0; j < ap_info->numOfRssi; j++) hdd_debug("Rssi %d", *rssi++); - ap_info += ap_info->numOfRssi * sizeof(*rssi); + ap_info = (tSirWifiSignificantChange *)((char *)ap_info + + ap_info->numOfRssi * sizeof(*rssi) + + sizeof(*ap_info)); } if (nla_put_u32(skb, @@ -779,7 +781,9 @@ wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind( nla_nest_end(skb, ap); - ap_info += ap_info->numOfRssi * sizeof(*rssi); + ap_info = (tSirWifiSignificantChange *)((char *)ap_info + + ap_info->numOfRssi * sizeof(*rssi) + + sizeof(*ap_info)); } nla_nest_end(skb, aps); @@ -4365,23 +4369,6 @@ int wlan_hdd_cfg80211_reset_passpoint_list(struct wiphy *wiphy, #undef PARAM_ROAM_PLMN /** - * wlan_hdd_init_completion_extwow() - Initialize ext wow variable - * @hdd_ctx: Global HDD context - * - * Return: none - */ -#ifdef WLAN_FEATURE_EXTWOW_SUPPORT -static inline void wlan_hdd_init_completion_extwow(hdd_context_t *pHddCtx) -{ - init_completion(&pHddCtx->ready_to_extwow); -} -#else -static inline void wlan_hdd_init_completion_extwow(hdd_context_t *pHddCtx) -{ -} -#endif - -/** * wlan_hdd_cfg80211_extscan_init() - Initialize the ExtScan feature * @hdd_ctx: Global HDD context * @@ -4389,7 +4376,6 @@ static inline void wlan_hdd_init_completion_extwow(hdd_context_t *pHddCtx) */ void wlan_hdd_cfg80211_extscan_init(hdd_context_t *hdd_ctx) { - wlan_hdd_init_completion_extwow(hdd_ctx); init_completion(&ext_scan_context.response_event); spin_lock_init(&ext_scan_context.context_lock); } diff --git a/core/hdd/src/wlan_hdd_ftm.c b/core/hdd/src/wlan_hdd_ftm.c index f87bc4029ed6..8d29a448c42b 100644 --- a/core/hdd/src/wlan_hdd_ftm.c +++ b/core/hdd/src/wlan_hdd_ftm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -304,7 +304,7 @@ int wlan_hdd_qcmbr_unified_ioctl(hdd_adapter_t *adapter, struct ifreq *ifr) { int ret = 0; - if (is_compat_task()) + if (in_compat_syscall()) ret = wlan_hdd_qcmbr_compat_ioctl(adapter, ifr); else ret = wlan_hdd_qcmbr_ioctl(adapter, ifr); diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 474c7fd7935c..368d93bb518a 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -384,8 +384,10 @@ static int __hdd_hostapd_stop(struct net_device *dev) ENTER_DEV(dev); ret = wlan_hdd_validate_context(hdd_ctx); - if (ret) + if (ret) { + set_bit(DOWN_DURING_SSR, &adapter->event_flags); return ret; + } if (!sap_ctx) { hdd_err("invalid sap ctx: %pK", sap_ctx); @@ -549,7 +551,7 @@ QDF_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter, static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *psta_mac_addr = addr; - hdd_adapter_t *adapter; + hdd_adapter_t *adapter, *adapter_temp; hdd_context_t *hdd_ctx; int ret = 0; struct qdf_mac_addr mac_addr; @@ -564,8 +566,12 @@ static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr) qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, QDF_MAC_ADDR_SIZE); - if (hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes)) { - hdd_err("adapter exist with same mac address " MAC_ADDRESS_STR, + adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes); + if (adapter_temp) { + if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) + return 0; + hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR, + adapter_temp->dev->name, MAC_ADDR_ARRAY(mac_addr.bytes)); return -EINVAL; } @@ -729,6 +735,7 @@ static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter, return status; if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { + hdd_ipa_ap_disconnect(pHostapdAdapter); status = wlansap_stop_bss( WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)); if (QDF_IS_STATUS_SUCCESS(status)) @@ -1448,6 +1455,8 @@ static void hdd_fill_station_info(hdd_adapter_t *pHostapdAdapter, return; } + qdf_mem_copy(&stainfo->capability, &event->capability_info, + sizeof(uint16_t)); stainfo->freq = cds_chan_to_freq(event->chan_info.chan_id); stainfo->dot11_mode = hdd_convert_dot11mode_from_phymode(event->chan_info.info); @@ -1576,6 +1585,38 @@ hdd_stop_sap_due_to_invalid_channel(struct work_struct *work) cds_ssr_unprotect(__func__); } +QDF_STATUS hdd_softap_set_peer_authorized(hdd_adapter_t *adapter, + struct qdf_mac_addr *peer_mac) +{ + QDF_STATUS status; + hdd_context_t *hdd_ctx; + + if (hdd_validate_adapter(adapter)) { + hdd_err("Invalid adapter"); + return QDF_STATUS_E_INVAL; + } + + hdd_ctx = (hdd_context_t *) (adapter->pHddCtx); + if (wlan_hdd_validate_context(hdd_ctx)) { + hdd_err("Invalid HDD Context"); + return QDF_STATUS_E_INVAL; + } + + status = hdd_softap_change_sta_state(adapter, peer_mac, + OL_TXRX_PEER_STATE_AUTH); + + if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("Not able to change TL state to AUTHENTICATED"); + return status; + } + + status = wlan_hdd_send_sta_authorized_event(adapter, hdd_ctx, peer_mac); + if (QDF_IS_STATUS_ERROR(status)) + hdd_debug("Failed to sent STA authorized event"); + + return status; +} + QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, void *usrDataForCallback) { @@ -1608,6 +1649,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, QDF_STATUS status = QDF_STATUS_SUCCESS; struct hdd_chan_change_params chan_change; tSap_StationAssocReassocCompleteEvent *event; + tSap_StationSetKeyCompleteEvent *key_complete; int ret = 0; struct ch_params_s sap_ch_param = {0}; eCsrPhyMode phy_mode; @@ -2012,9 +2054,17 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, * forward the message to hostapd once implementation * is done for now just print */ + + key_complete = &pSapEvent->sapevt.sapStationSetKeyCompleteEvent; hdd_debug("SET Key: configured status = %s", - pSapEvent->sapevt.sapStationSetKeyCompleteEvent. - status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + key_complete->status ? + "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS"); + + if (QDF_IS_STATUS_SUCCESS(key_complete->status)) { + hdd_softap_set_peer_authorized(pHostapdAdapter, + &key_complete->peerMacAddr); + } + return QDF_STATUS_SUCCESS; case eSAP_STA_MIC_FAILURE_EVENT: { @@ -2223,6 +2273,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, stainfo->rssi = disassoc_comp->rssi; stainfo->tx_rate = disassoc_comp->tx_rate; stainfo->rx_rate = disassoc_comp->rx_rate; + stainfo->rx_mc_bc_cnt = disassoc_comp->rx_mc_bc_cnt; stainfo->reason_code = disassoc_comp->reason_code; qdf_status = qdf_event_set(&pHostapdState->qdf_sta_disassoc_event); @@ -5298,6 +5349,7 @@ __iw_softap_stopbss(struct net_device *dev, WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); qdf_event_reset(&pHostapdState->qdf_stop_bss_event); + hdd_ipa_ap_disconnect(pHostapdAdapter); status = wlansap_stop_bss( WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)); if (QDF_IS_STATUS_SUCCESS(status)) { @@ -7806,16 +7858,7 @@ int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx) return 0; } -/** - * wlan_hdd_disable_channels() - Cache the channels - * and current state of the channels from the channel list - * received in the command and disable the channels on the - * wiphy and reg table. - * @hdd_ctx: Pointer to hdd context - * - * Return: 0 on success, Error code on failure - */ -static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx) +int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx) { struct hdd_cache_channels *cache_chann; struct wiphy *wiphy; @@ -7910,7 +7953,6 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, tpWLAN_SAPEventCB pSapEventCallback; hdd_hostapd_state_t *pHostapdState; tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter); - struct qc_mac_acl_entry *acl_entry = NULL; int32_t i; struct hdd_config *iniConfig; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); @@ -8010,7 +8052,8 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, pHddCtx); } - if (pHostapdAdapter->device_mode == QDF_SAP_MODE) { + if (pHostapdAdapter->device_mode == QDF_SAP_MODE && + !iniConfig->disable_channel) { /* * Disable the channels received in command * SET_DISABLE_CHANNEL_LIST @@ -8172,8 +8215,10 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len); if (pIe) { - if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) { - hdd_err("**Wps Ie Length is too small***"); + /* To acess pIe[15], length needs to be atlest 14 */ + if (pIe[1] < 14) { + hdd_err("**Wps Ie Length(%hhu) is too small***", + pIe[1]); ret = -EINVAL; goto error; } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == @@ -8340,60 +8385,6 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode; #endif - pIe = - wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, - WPA_OUI_TYPE_SIZE, pBeacon->tail, - pBeacon->tail_len); - - /* pIe for black list is following form: - * type : 1 byte - * length : 1 byte - * OUI : 4 bytes - * acl type : 1 byte - * no of mac addr in black list: 1 byte - * list of mac_acl_entries: variable, 6 bytes per mac - * address + sizeof(int) for vlan id - */ - if ((pIe != NULL) && (pIe[1] != 0)) { - pConfig->SapMacaddr_acl = pIe[6]; - pConfig->num_deny_mac = pIe[7]; - hdd_debug("acl type = %d no deny mac = %d", pIe[6], pIe[7]); - if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS) - pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS; - acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); - for (i = 0; i < pConfig->num_deny_mac; i++) { - qdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, - sizeof(qcmacaddr)); - acl_entry++; - } - } - pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, - WPA_OUI_TYPE_SIZE, pBeacon->tail, - pBeacon->tail_len); - - /* pIe for white list is following form: - * type : 1 byte - * length : 1 byte - * OUI : 4 bytes - * acl type : 1 byte - * no of mac addr in white list: 1 byte - * list of mac_acl_entries: variable, 6 bytes per mac - * address + sizeof(int) for vlan id - */ - if ((pIe != NULL) && (pIe[1] != 0)) { - pConfig->SapMacaddr_acl = pIe[6]; - pConfig->num_accept_mac = pIe[7]; - hdd_debug("acl type = %d no accept mac = %d", - pIe[6], pIe[7]); - if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS) - pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS; - acl_entry = (struct qc_mac_acl_entry *)(pIe + 8); - for (i = 0; i < pConfig->num_accept_mac; i++) { - qdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, - sizeof(qcmacaddr)); - acl_entry++; - } - } if (!(ssid && qdf_str_len(PRE_CAC_SSID) == ssid_len && (0 == qdf_mem_cmp(ssid, PRE_CAC_SSID, ssid_len)))) { pIe = wlan_hdd_cfg80211_get_ie_ptr( @@ -8629,7 +8620,8 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, return 0; error: - if (pHostapdAdapter->device_mode == QDF_SAP_MODE) + if (pHostapdAdapter->device_mode == QDF_SAP_MODE && + !iniConfig->disable_channel) wlan_hdd_restore_channels(pHddCtx); /* Revert the indoor to passive marking if START BSS fails */ if (iniConfig->disable_indoor_channel && @@ -8718,6 +8710,8 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, if (0 != ret) return ret; + cds_flush_sta_ap_intf_work(pHddCtx); + /* * If a STA connection is in progress in another adapter, disconnect * the STA and complete the SAP operation. STA will reconnect @@ -8814,6 +8808,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, WLAN_HDD_GET_SAP_CTX_PTR(pAdapter), true); qdf_event_reset(&pHostapdState->qdf_stop_bss_event); + hdd_ipa_ap_disconnect(pAdapter); status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter)); if (QDF_IS_STATUS_SUCCESS(status)) { qdf_status = @@ -9160,16 +9155,18 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy, hdd_err("ERR: clear event failed"); /* - * Stop opportunistic timer here if running as we are already doing - * hw mode change before vdev start based on the new concurrency - * situation. If timer is not stopped and if it gets triggered before - * VDEV_UP, it will reset the hw mode to some wrong value. + * For Start Ap, the driver checks whether the SAP comes up in a + * different or same band( whether we require DBS or Not). + * If we dont require DBS, then the driver does nothing assuming + * the state would be already in non DBS mode, and just continues + * with vdev up on same MAC, by stoping the opportunistic timer, + * which results in a connection of 1x1 if already the state was in + * DBS. So first stop timer, and check the current hw mode. + * If the SAP comes up in band different from STA, DBS mode is already + * set. IF not, then well check for upgrade, and shift the connection + * back to single MAC 2x2 (if initial was 2x2). */ - status = cds_stop_opportunistic_timer(); - if (status != QDF_STATUS_SUCCESS) { - hdd_err("Failed to stop DBS opportunistic timer"); - return -EINVAL; - } + cds_checkn_update_hw_mode_single_mac_mode(channel); status = cds_current_connections_update(pAdapter->sessionId, channel, @@ -9514,3 +9511,17 @@ void hdd_sap_destroy_events(hdd_adapter_t *adapter) } EXIT(); } +void hdd_ipa_ap_disconnect(hdd_adapter_t *pAdapter) +{ + hdd_context_t *hdd_ctx; + hdd_ctx = WLAN_HDD_GET_CTX(pAdapter); + + if (hdd_ipa_is_enabled(hdd_ctx)) { + if (hdd_ipa_wlan_evt(pAdapter, + WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->uBCStaId, + HDD_IPA_AP_DISCONNECT, + pAdapter->dev->dev_addr)) { + hdd_err("WLAN_AP_DISCONNECT event failed"); + } + } +} diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h index a4c8c4b9b289..b23544b44387 100644 --- a/core/hdd/src/wlan_hdd_hostapd.h +++ b/core/hdd/src/wlan_hdd_hostapd.h @@ -129,4 +129,37 @@ bool hdd_is_peer_associated(hdd_adapter_t *adapter, void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter); void hdd_sap_destroy_events(hdd_adapter_t *adapter); +/** + * hdd_softap_set_peer_authorized() - set peer authorized + * @adapter: pointer to the hostapd adapter + * @peer_mac: MAC address of the peer + * + * This functions sends the PEER authorize command to the SME/WMI and also + * notifies the hostapd that the peer is authorized. + * + * Return: QDF_STATUS + */ +QDF_STATUS hdd_softap_set_peer_authorized(hdd_adapter_t *adapter, + struct qdf_mac_addr *peer_mac); + +/** + * hdd_ipa_ap_disconnect() - call hdd_ipa_wlan_evt if + * ipa is enabled + * @pAdapter: pointer to adapter context + * + * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error + */ +void hdd_ipa_ap_disconnect(hdd_adapter_t *pAdapter); + +/** + * wlan_hdd_disable_channels() - Cache the channels + * and current state of the channels from the channel list + * received in the command and disable the channels on the + * wiphy and reg table. + * @hdd_ctx: Pointer to hdd context + * + * Return: 0 on success, Error code on failure + */ +int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx); + #endif /* end #if !defined(WLAN_HDD_HOSTAPD_H) */ diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index b829d85ebd78..af93917b5634 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -80,6 +80,16 @@ */ #define NUM_OF_STA_DATA_TO_PRINT 16 +#ifdef WLAN_FEATURE_EXTWOW_SUPPORT +/** + * struct enable_ext_wow_priv - Private data structure for ext wow + * @ext_wow_should_suspend: Suspend status of ext wow + */ +struct enable_ext_wow_priv { + bool ext_wow_should_suspend; +}; +#endif + /* * Android DRIVER command structures */ @@ -792,7 +802,7 @@ static int hdd_parse_reassoc_command_v1_data(const uint8_t *pValue, } #ifdef WLAN_FEATURE_ROAM_OFFLOAD -void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, +QDF_STATUS hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, const tSirMacAddr bssid, int channel) { hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter); @@ -803,9 +813,10 @@ void hdd_wma_send_fastreassoc_cmd(hdd_adapter_t *adapter, qdf_mem_copy(connected_bssid, hdd_sta_ctx->conn_info.bssId.bytes, ETH_ALEN); - sme_fast_reassoc(WLAN_HDD_GET_HAL_CTX(adapter), - profile, bssid, channel, adapter->sessionId, - connected_bssid); + return sme_fast_reassoc(WLAN_HDD_GET_HAL_CTX(adapter), + profile, bssid, channel, + adapter->sessionId, + connected_bssid); } #endif @@ -868,8 +879,10 @@ int hdd_reassoc(hdd_adapter_t *adapter, const uint8_t *bssid, /* Proceed with reassoc */ if (roaming_offload_enabled(hdd_ctx)) { - hdd_wma_send_fastreassoc_cmd(adapter, - bssid, (int)channel); + if (QDF_STATUS_SUCCESS != + hdd_wma_send_fastreassoc_cmd(adapter, bssid, + (int)channel)) + ret = -EINVAL; } else { tCsrHandoffRequest handoffInfo; @@ -1884,16 +1897,28 @@ static QDF_STATUS hdd_parse_plm_cmd(uint8_t *pValue, tSirPlmReq *pPlmRequest) #endif #ifdef WLAN_FEATURE_EXTWOW_SUPPORT -static void wlan_hdd_ready_to_extwow(void *callbackContext, bool is_success) +/** + * wlan_hdd_ready_to_extwow() - Callback function for enable ext wow + * @cookie: callback context + * @is_success: suspend status of ext wow + * + * Return: none + */ +static void wlan_hdd_ready_to_extwow(void *cookie, bool is_success) { - hdd_context_t *hdd_ctx = (hdd_context_t *) callbackContext; - int rc; + struct hdd_request *request = NULL; + struct enable_ext_wow_priv *priv = NULL; - rc = wlan_hdd_validate_context(hdd_ctx); - if (rc) + request = hdd_request_get(cookie); + if (!request) { + hdd_err("Obselete request"); return; - hdd_ctx->ext_wow_should_suspend = is_success; - complete(&hdd_ctx->ready_to_extwow); + } + priv = hdd_request_priv(request); + priv->ext_wow_should_suspend = is_success; + + hdd_request_complete(request); + hdd_request_put(request); } static int hdd_enable_ext_wow(hdd_adapter_t *adapter, @@ -1903,31 +1928,46 @@ static int hdd_enable_ext_wow(hdd_adapter_t *adapter, QDF_STATUS qdf_ret_status; hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(adapter); - int rc; + int rc = 0; + struct enable_ext_wow_priv *priv = NULL; + struct hdd_request *request = NULL; + void *cookie = NULL; + struct hdd_request_params hdd_params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_READY_TO_EXTWOW, + }; qdf_mem_copy(¶ms, arg_params, sizeof(params)); - INIT_COMPLETION(hdd_ctx->ready_to_extwow); + request = hdd_request_alloc(&hdd_params); + if (!request) { + hdd_err("Request Allocation Failure"); + return -ENOMEM; + } + cookie = hdd_request_cookie(request); qdf_ret_status = sme_configure_ext_wow(hHal, ¶ms, - &wlan_hdd_ready_to_extwow, - hdd_ctx); + &wlan_hdd_ready_to_extwow, + cookie); if (QDF_STATUS_SUCCESS != qdf_ret_status) { hdd_err("sme_configure_ext_wow returned failure %d", - qdf_ret_status); - return -EPERM; + qdf_ret_status); + rc = -EPERM; + goto exit; } - rc = wait_for_completion_timeout(&hdd_ctx->ready_to_extwow, - msecs_to_jiffies(WLAN_WAIT_TIME_READY_TO_EXTWOW)); - if (!rc) { + rc = hdd_request_wait_for_response(request); + if (rc) { hdd_err("Failed to get ready to extwow"); - return -EPERM; + rc = -EPERM; + goto exit; } - if (!hdd_ctx->ext_wow_should_suspend) { + priv = hdd_request_priv(request); + if (!priv->ext_wow_should_suspend) { hdd_err("Received ready to ExtWoW failure"); - return -EPERM; + rc = -EPERM; + goto exit; } if (hdd_ctx->config->extWowGotoSuspend) { @@ -1939,8 +1979,8 @@ static int hdd_enable_ext_wow(hdd_adapter_t *adapter, rc = wlan_hdd_cfg80211_suspend_wlan(hdd_ctx->wiphy, NULL); if (rc < 0) { hdd_err("wlan_hdd_cfg80211_suspend_wlan failed, error = %d", - rc); - return rc; + rc); + goto exit; } rc = wlan_hdd_bus_suspend(state); @@ -1948,11 +1988,12 @@ static int hdd_enable_ext_wow(hdd_adapter_t *adapter, hdd_err("wlan_hdd_bus_suspend failed, status = %d", rc); wlan_hdd_cfg80211_resume_wlan(hdd_ctx->wiphy); - return rc; + goto exit; } } - - return 0; +exit: + hdd_request_put(request); + return rc; } static int hdd_enable_ext_wow_parser(hdd_adapter_t *adapter, int vdev_id, @@ -6617,6 +6658,35 @@ QDF_STATUS hdd_update_smps_antenna_mode(hdd_context_t *hdd_ctx, int mode) return QDF_STATUS_SUCCESS; } +/** + * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set dual + * mac scan config + * @status: Status of set antenna mode + * @context: callback context + * + * Callback on setting the dual mac configuration + * + * Return: None + */ +static void +wlan_hdd_soc_set_antenna_mode_cb(enum set_antenna_mode_status status, + void *context) +{ + struct hdd_request *request = NULL; + + hdd_debug("Status: %d", status); + + request = hdd_request_get(context); + if (!request) { + hdd_err("obsolete request"); + return; + } + + /* Signal the completion of set dual mac config */ + hdd_request_complete(request); + hdd_request_put(request); +} + int hdd_set_antenna_mode(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx, int mode) { @@ -6624,6 +6694,11 @@ int hdd_set_antenna_mode(hdd_adapter_t *adapter, struct sir_antenna_mode_param params; QDF_STATUS status; int ret = 0; + struct hdd_request *request = NULL; + static const struct hdd_request_params request_params = { + .priv_size = 0, + .timeout_ms = WLAN_WAIT_TIME_ANTENNA_MODE_REQ, + }; if (hdd_ctx->current_antenna_mode == mode) { hdd_err("System already in the requested mode"); @@ -6667,36 +6742,40 @@ int hdd_set_antenna_mode(hdd_adapter_t *adapter, goto exit; } - params.set_antenna_mode_resp = - (void *)wlan_hdd_soc_set_antenna_mode_cb; + request = hdd_request_alloc(&request_params); + if (!request) { + hdd_err("Request Allocation Failure"); + ret = -ENOMEM; + goto exit; + } + + params.set_antenna_mode_ctx = hdd_request_cookie(request); + params.set_antenna_mode_resp = wlan_hdd_soc_set_antenna_mode_cb; hdd_debug("Set antenna mode rx chains: %d tx chains: %d", params.num_rx_chains, params.num_tx_chains); - - INIT_COMPLETION(hdd_ctx->set_antenna_mode_cmpl); status = sme_soc_set_antenna_mode(hdd_ctx->hHal, ¶ms); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("set antenna mode failed status : %d", status); ret = -EFAULT; - goto exit; + goto request_put; } - ret = wait_for_completion_timeout( - &hdd_ctx->set_antenna_mode_cmpl, - msecs_to_jiffies(WLAN_WAIT_TIME_ANTENNA_MODE_REQ)); - if (!ret) { + ret = hdd_request_wait_for_response(request); + if (ret) { hdd_err("send set antenna mode timed out"); - ret = -EFAULT; - goto exit; + goto request_put; } status = hdd_update_smps_antenna_mode(hdd_ctx, mode); if (QDF_STATUS_SUCCESS != status) { ret = -EFAULT; - goto exit; + goto request_put; } ret = 0; +request_put: + hdd_request_put(request); exit: #ifdef FEATURE_WLAN_TDLS /* Reset tdls NSS flags */ @@ -7033,6 +7112,70 @@ static int hdd_alloc_chan_cache(hdd_context_t *hdd_ctx, int num_chan) } /** + * check_disable_channels() - Check for disable channel + * @hdd_ctx: Pointer to hdd context + * @operating_channel: Current operating channel of adapter + * + * This function checks original_channels array for a specific channel + * + * Return: 0 if channel not found, 1 if channel found + */ +static bool check_disable_channels(hdd_context_t *hdd_ctx, + uint8_t operating_channel) +{ + uint32_t num_channels; + uint8_t i; + + if (!hdd_ctx || !hdd_ctx->original_channels || + !hdd_ctx->original_channels->channel_info) + return false; + + num_channels = hdd_ctx->original_channels->num_channels; + for (i = 0; i < num_channels; i++) + if (hdd_ctx->original_channels->channel_info[i].channel_num == + operating_channel) + return true; + return false; +} + +/** + * disconnect_sta_and_stop_sap() - Disconnect STA and stop SAP + * + * @hdd_ctx: Pointer to hdd context + * + * Disable channels provided by user and disconnect STA if it is + * connected to any AP, stop SAP and send deauthentication request + * to STAs connected to SAP. + * + * Return: None + */ +static void disconnect_sta_and_stop_sap(hdd_context_t *hdd_ctx) +{ + hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; + hdd_adapter_t *adapter; + QDF_STATUS status; + + if (!hdd_ctx) + return; + + wlan_hdd_disable_channels(hdd_ctx); + + status = hdd_get_front_adapter(hdd_ctx, &adapter_node); + while (adapter_node && (status == QDF_STATUS_SUCCESS)) { + adapter = adapter_node->pAdapter; + + if (!hdd_validate_adapter(adapter) && + (adapter->device_mode == QDF_SAP_MODE) && + (check_disable_channels(hdd_ctx, + adapter->sessionCtx.ap.operatingChannel))) + wlan_hdd_stop_sap(adapter); + + status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next); + adapter_node = next; + } +} + +/** * hdd_parse_disable_chan_cmd() - Parse the channel list received * in command. * @adapter: pointer to hdd adapter @@ -7201,6 +7344,9 @@ static int hdd_parse_disable_chan_cmd(hdd_adapter_t *adapter, uint8_t *ptr) } ret = 0; } + + if (!is_command_repeated && hdd_ctx->config->disable_channel) + disconnect_sta_and_stop_sap(hdd_ctx); mem_alloc_failed: qdf_mutex_release(&hdd_ctx->cache_channel_lock); @@ -7645,7 +7791,7 @@ static int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch (cmd) { case (SIOCDEVPRIVATE + 1): - if (is_compat_task()) + if (in_compat_syscall()) ret = hdd_driver_compat_ioctl(adapter, ifr); else ret = hdd_driver_ioctl(adapter, ifr); diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index 7e41a7e0461d..e0cb480fc5fe 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -5413,13 +5413,6 @@ static int __hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets, else next_prod_bw = hdd_ctx->config->IpaLowBandwidthMbps; - HDD_IPA_DP_LOG(QDF_TRACE_LEVEL_DEBUG, - "CONS perf curr: %d, next: %d", - hdd_ipa->curr_cons_bw, next_cons_bw); - HDD_IPA_DP_LOG(QDF_TRACE_LEVEL_DEBUG, - "PROD perf curr: %d, next: %d", - hdd_ipa->curr_prod_bw, next_prod_bw); - if (hdd_ipa->curr_cons_bw != next_cons_bw) { hdd_debug("Requesting CONS perf curr: %d, next: %d", hdd_ipa->curr_cons_bw, next_cons_bw); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index d63ccbda31c8..94a99a32b56d 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -204,6 +204,9 @@ static qdf_wake_lock_t wlan_wake_lock; #define WOW_MIN_PATTERN_SIZE 6 #define WOW_MAX_PATTERN_SIZE 64 +#define IS_IDLE_STOP (!cds_is_driver_unloading() && \ + !cds_is_driver_recovering()) + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) static const struct wiphy_wowlan_support wowlan_support_reg_init = { .flags = WIPHY_WOWLAN_ANY | @@ -521,8 +524,6 @@ static int __hdd_netdev_notifier_call(struct notifier_block *nb, cds_flush_work(&adapter->scan_block_work); /* Need to clean up blocked scan request */ wlan_hdd_cfg80211_scan_block_cb(&adapter->scan_block_work); - qdf_list_destroy(&adapter->blocked_scan_request_q); - qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); hdd_debug("Scan is not Pending from user"); /* * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective @@ -701,20 +702,19 @@ static void hdd_qdf_trace_enable(QDF_MODULE_ID moduleId, uint32_t bitmask) int wlan_hdd_validate_context_in_loading(hdd_context_t *hdd_ctx) { if (NULL == hdd_ctx || NULL == hdd_ctx->config) { - hdd_info("%pS HDD context is Null", (void *)_RET_IP_); + hdd_info("HDD context is Null"); return -ENODEV; } if (cds_is_driver_recovering()) { - hdd_info("%pS Recovery in Progress. State: 0x%x Ignore!!!", - (void *)_RET_IP_, cds_get_driver_state()); + hdd_info("Recovery in Progress. State: 0x%x Ignore!!!", + cds_get_driver_state()); return -EAGAIN; } if (hdd_ctx->start_modules_in_progress || hdd_ctx->stop_modules_in_progress) { - hdd_info("%pS Start/Stop Modules in progress. Ignore!!!", - (void *)_RET_IP_); + hdd_info("Start/Stop Modules in progress. Ignore!!!"); return -EAGAIN; } @@ -731,13 +731,13 @@ int wlan_hdd_validate_context_in_loading(hdd_context_t *hdd_ctx) int wlan_hdd_validate_context(hdd_context_t *hdd_ctx) { if (NULL == hdd_ctx || NULL == hdd_ctx->config) { - hdd_debug("%pS HDD context is Null", (void *)_RET_IP_); + hdd_debug("HDD context is Null"); return -ENODEV; } if (cds_is_driver_recovering()) { - hdd_debug("%pS Recovery in Progress. State: 0x%x Ignore!!!", - (void *)_RET_IP_, cds_get_driver_state()); + hdd_debug("Recovery in Progress. State: 0x%x Ignore!!!", + cds_get_driver_state()); return -EAGAIN; } @@ -746,20 +746,19 @@ int wlan_hdd_validate_context(hdd_context_t *hdd_ctx) if (hdd_ctx->start_modules_in_progress || hdd_ctx->stop_modules_in_progress) { - hdd_debug("%pS Start/Stop Modules in progress. Ignore!!!", - (void *)_RET_IP_); + hdd_debug("Start/Stop Modules in progress. Ignore!!!"); return -EAGAIN; } if (cds_is_driver_in_bad_state()) { - hdd_debug("%pS driver in bad State: 0x%x Ignore!!!", - (void *)_RET_IP_, cds_get_driver_state()); + hdd_debug("driver in bad State: 0x%x Ignore!!!", + cds_get_driver_state()); return -EAGAIN; } if (cds_is_fw_down()) { - hdd_debug("%pS FW is down: 0x%x Ignore!!!", - (void *)_RET_IP_, cds_get_driver_state()); + hdd_debug("FW is down: 0x%x Ignore!!!", + cds_get_driver_state()); return -EAGAIN; } @@ -1668,6 +1667,12 @@ static void hdd_update_ra_rate_limit(hdd_context_t *hdd_ctx, } #endif +static void hdd_sar_target_config(hdd_context_t *hdd_ctx, + struct wma_tgt_cfg *cfg) +{ + hdd_ctx->sar_version = cfg->sar_version; +} + void hdd_update_tgt_cfg(void *context, void *param) { hdd_context_t *hdd_ctx = (hdd_context_t *) context; @@ -1676,6 +1681,11 @@ void hdd_update_tgt_cfg(void *context, void *param) struct cds_config_info *cds_cfg = cds_get_ini_config(); uint8_t antenna_mode; + if (!hdd_ctx) { + hdd_err("hdd context is NULL"); + return; + } + if (cds_cfg) { if (hdd_ctx->config->enable_sub_20_channel_width != WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) { @@ -1731,9 +1741,9 @@ void hdd_update_tgt_cfg(void *context, void *param) hdd_ctx->hw_bd_id = cfg->hw_bd_id; qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info, sizeof(cfg->hw_bd_info)); - hdd_ctx->max_intf_count = cfg->max_intf_count; + hdd_sar_target_config(hdd_ctx, cfg); hdd_lpass_target_config(hdd_ctx, cfg); hdd_green_ap_target_config(hdd_ctx, cfg); @@ -2589,8 +2599,10 @@ static int __hdd_stop(struct net_device *dev) adapter->sessionId, adapter->device_mode)); ret = wlan_hdd_validate_context(hdd_ctx); - if (0 != ret) + if (0 != ret) { + set_bit(DOWN_DURING_SSR, &adapter->event_flags); return ret; + } /* Nothing to be done if the interface is not opened */ if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { @@ -2799,6 +2811,7 @@ static void hdd_close_cesium_nl_sock(void) static int __hdd_set_mac_address(struct net_device *dev, void *addr) { hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_adapter_t *adapter_temp; hdd_context_t *hdd_ctx; struct sockaddr *psta_mac_addr = addr; QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS; @@ -2818,9 +2831,12 @@ static int __hdd_set_mac_address(struct net_device *dev, void *addr) return ret; qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, QDF_MAC_ADDR_SIZE); - - if (hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes)) { - hdd_err("adapter exist with same mac address " MAC_ADDRESS_STR, + adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes); + if (adapter_temp) { + if (!qdf_str_cmp(adapter_temp->dev->name, dev->name)) + return 0; + hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR, + adapter_temp->dev->name, MAC_ADDR_ARRAY(mac_addr.bytes)); return -EINVAL; } @@ -3253,6 +3269,7 @@ static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx, adapter->offloads_configured = false; adapter->isLinkUpSvcNeeded = false; adapter->higherDtimTransition = true; + adapter->send_mode_change = true; /* Init the net_device structure */ strlcpy(pWlanDev->name, name, IFNAMSIZ); @@ -4552,9 +4569,10 @@ QDF_STATUS hdd_close_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, } adapterNode = pCurrent; if (QDF_STATUS_SUCCESS == status) { - hdd_debug("wait for bus bw work to flush"); hdd_bus_bw_compute_timer_stop(hdd_ctx); - cancel_work_sync(&hdd_ctx->bus_bw_work); + + qdf_list_destroy(&adapter->blocked_scan_request_q); + qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock); /* cleanup adapter */ cds_clear_concurrency_mode(adapter->device_mode); @@ -4811,14 +4829,9 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, hdd_ctx->hHal, adapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE); - else if (QDF_STA_MODE == adapter->device_mode) { - qdf_ret_status = - wlan_hdd_try_disconnect(adapter); - hdd_debug("Send disconnected event to userspace"); - wlan_hdd_cfg80211_indicate_disconnect( - adapter->dev, true, - WLAN_REASON_UNSPECIFIED); - } + else if (QDF_STA_MODE == adapter->device_mode) + wlan_hdd_disconnect(adapter, + eCSR_DISCONNECT_REASON_DEAUTH); else qdf_ret_status = sme_roam_disconnect( hdd_ctx->hHal, @@ -4908,6 +4921,7 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, QDF_STATUS status; QDF_STATUS qdf_status; + hdd_ipa_ap_disconnect(adapter); /* Stop Bss. */ status = wlansap_stop_bss( WLAN_HDD_GET_SAP_CTX_PTR(adapter)); @@ -4973,6 +4987,7 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, adapter->sessionCtx.ap.sapContext = NULL; mutex_unlock(&hdd_ctx->sap_lock); + wlan_hdd_check_conc_and_update_tdls_state(hdd_ctx, false); #ifdef WLAN_OPEN_SOURCE cancel_work_sync(&adapter->ipv4NotifierWorkQueue); #endif @@ -5037,11 +5052,7 @@ QDF_STATUS hdd_stop_all_adapters(hdd_context_t *hdd_ctx, bool close_session) ENTER(); cds_flush_work(&hdd_ctx->sap_pre_cac_work); - if (hdd_ctx->sta_ap_intf_check_work_info) { - cds_flush_work(&hdd_ctx->sta_ap_intf_check_work); - qdf_mem_free(hdd_ctx->sta_ap_intf_check_work_info); - hdd_ctx->sta_ap_intf_check_work_info = NULL; - } + cds_flush_sta_ap_intf_work(hdd_ctx); status = hdd_get_front_adapter(hdd_ctx, &adapterNode); @@ -5093,11 +5104,7 @@ QDF_STATUS hdd_reset_all_adapters(hdd_context_t *hdd_ctx) ENTER(); cds_flush_work(&hdd_ctx->sap_pre_cac_work); - if (hdd_ctx->sta_ap_intf_check_work_info) { - cds_flush_work(&hdd_ctx->sta_ap_intf_check_work); - qdf_mem_free(hdd_ctx->sta_ap_intf_check_work_info); - hdd_ctx->sta_ap_intf_check_work_info = NULL; - } + cds_flush_sta_ap_intf_work(hdd_ctx); status = hdd_get_front_adapter(hdd_ctx, &adapterNode); @@ -6619,8 +6626,6 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx) qdf_mc_timer_stop(&hdd_ctx->tdls_source_timer); } - hdd_bus_bandwidth_destroy(hdd_ctx); - #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE if (QDF_TIMER_STATE_RUNNING == qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) { @@ -6690,6 +6695,7 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx) #endif qdf_nbuf_deinit_replenish_timer(); + hdd_bus_bandwidth_destroy(hdd_ctx); if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) { hdd_info("Release wakelock for monitor mode!"); @@ -7310,10 +7316,9 @@ static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx, } #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) -static void hdd_bus_bw_work_handler(struct work_struct *work) +static void hdd_bus_bw_compute_cbk(void *priv) { - hdd_context_t *hdd_ctx = container_of(work, hdd_context_t, - bus_bw_work); + hdd_context_t *hdd_ctx = (hdd_context_t *)priv; hdd_adapter_t *adapter = NULL; uint64_t tx_packets = 0, rx_packets = 0; uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0; @@ -7328,9 +7333,6 @@ static void hdd_bus_bw_work_handler(struct work_struct *work) if (wlan_hdd_validate_context(hdd_ctx)) return; - if (hdd_ctx->isWiphySuspended) - goto restart_timer; - for (status = hdd_get_front_adapter(hdd_ctx, &adapterNode); NULL != adapterNode && QDF_STATUS_SUCCESS == status; status = @@ -7419,71 +7421,30 @@ static void hdd_bus_bw_work_handler(struct work_struct *work) hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets); -restart_timer: - /* ensure periodic timer should still be running before restarting it */ - qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock); - if (hdd_ctx->bus_bw_timer_running) - qdf_timer_mod(&hdd_ctx->bus_bw_timer, - hdd_ctx->config->busBandwidthComputeInterval); - qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock); -} - -/** - * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback. - * @arg: Argument of timer function - * - * Schedule a workqueue in this function where all the processing is done. - * - * Return: None. - */ -static void __hdd_bus_bw_cbk(void *arg) -{ - hdd_context_t *hdd_ctx = (hdd_context_t *) arg; - - if (wlan_hdd_validate_context(hdd_ctx)) - return; - - schedule_work(&hdd_ctx->bus_bw_work); -} - -/** - * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection. - * @arg: Argument of timer function - * - * Return: None. - */ -static void hdd_bus_bw_cbk(unsigned long arg) -{ - cds_ssr_protect(__func__); - __hdd_bus_bw_cbk((void *)arg); - cds_ssr_unprotect(__func__); + qdf_mc_timer_start(&hdd_ctx->bus_bw_timer, + hdd_ctx->config->busBandwidthComputeInterval); } int hdd_bus_bandwidth_init(hdd_context_t *hdd_ctx) { spin_lock_init(&hdd_ctx->bus_bw_lock); - INIT_WORK(&hdd_ctx->bus_bw_work, - hdd_bus_bw_work_handler); - hdd_ctx->bus_bw_timer_running = false; - qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock); - qdf_timer_init(NULL, - &hdd_ctx->bus_bw_timer, - hdd_bus_bw_cbk, (void *)hdd_ctx, - QDF_TIMER_TYPE_SW); + + qdf_mc_timer_init(&hdd_ctx->bus_bw_timer, + QDF_TIMER_TYPE_SW, + hdd_bus_bw_compute_cbk, (void *)hdd_ctx); return 0; } void hdd_bus_bandwidth_destroy(hdd_context_t *hdd_ctx) { - if (hdd_ctx->bus_bw_timer_running) + if (qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer) == + QDF_TIMER_STATE_RUNNING && + hdd_ctx->config->enable_tcp_delack) hdd_reset_tcp_delack(hdd_ctx); - hdd_debug("wait for bus bw work to flush"); - cancel_work_sync(&hdd_ctx->bus_bw_work); - qdf_timer_free(&hdd_ctx->bus_bw_timer); - hdd_ctx->bus_bw_timer_running = false; - qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock); + hdd_bus_bw_compute_timer_stop(hdd_ctx); + qdf_mc_timer_destroy(&hdd_ctx->bus_bw_timer); } #endif @@ -8375,7 +8336,8 @@ void hdd_ch_avoid_cb(void *hdd_context, void *indi_param) if (CDS_CHANNEL_FREQ(channel_loop) > ch_avoid_indi->avoid_freq_range[ range_loop].end_freq) - end_channel_idx--; + if (end_channel_idx) + end_channel_idx--; break; } } @@ -8507,6 +8469,8 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) int i; hdd_adapter_list_node_t *adapter_node, *next; QDF_STATUS status = QDF_STATUS_SUCCESS; + struct ieee80211_mgmt *mgmt = + (struct ieee80211_mgmt *)frame_ind->frameBuf; /* Get the global VOSS context.*/ cds_context = cds_get_global_context(); @@ -8520,6 +8484,11 @@ void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind) if (0 != wlan_hdd_validate_context(hdd_ctx)) return; + if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) { + hdd_err(" Invalid frame length"); + return; + } + if (SME_SESSION_ID_ANY == frame_ind->sessionId) { for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) { adapter = @@ -8661,9 +8630,6 @@ static int hdd_context_init(hdd_context_t *hdd_ctx) hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX; - hdd_init_ll_stats_ctx(); - - init_completion(&hdd_ctx->chain_rssi_context.response_event); init_completion(&hdd_ctx->mc_sus_event_var); init_completion(&hdd_ctx->ready_to_suspend); @@ -8673,8 +8639,6 @@ static int hdd_context_init(hdd_context_t *hdd_ctx) qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS); - init_completion(&hdd_ctx->set_antenna_mode_cmpl); - ret = hdd_scan_context_init(hdd_ctx); if (ret) goto list_destroy; @@ -10264,6 +10228,53 @@ static int hdd_set_auto_shutdown_cb(hdd_context_t *hdd_ctx) } #endif +#ifdef MWS_COEX +/** + * hdd_set_mws_coex() - Set MWS coex configurations + * @adapter: HDD adapter + * + * This function sends MWS-COEX 4G quick FTDM and + * MWS-COEX 5G-NR power limit to FW + * + * Return: 0 on success and errno on failure. + */ +static int hdd_init_mws_coex(hdd_adapter_t *adapter) +{ + int ret = 0; + hdd_context_t *hdd_ctx; + + if (!adapter) { + hdd_err("Invalid Param"); + return -EINVAL; + } + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + + ret = sme_cli_set_command(adapter->sessionId, + WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM, + hdd_ctx->config->g_mws_coex_4g_quick_tdm, + PDEV_CMD); + if (ret) { + hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy"); + return ret; + } + + ret = sme_cli_set_command(adapter->sessionId, + WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT, + hdd_ctx->config->g_mws_coex_5g_nr_pwr_limit, + PDEV_CMD); + if (ret) { + hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy"); + return ret; + } + return ret; +} +#else +static int hdd_init_mws_coex(hdd_adapter_t *adapter) +{ + return 0; +} +#endif + /** * hdd_features_init() - Init features * @hdd_ctx: HDD context @@ -10332,6 +10343,12 @@ static int hdd_features_init(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter) goto out; } + ret = hdd_init_mws_coex(adapter); + if (ret) { + hdd_err("Error initializing mws-coex"); + goto out; + } + /* FW capabilities received, Set the Dot11 mode */ sme_setdef_dot11mode(hdd_ctx->hHal); sme_set_prefer_80MHz_over_160MHz(hdd_ctx->hHal, @@ -10391,7 +10408,6 @@ static int hdd_features_init(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter) hdd_err("Error setting txlimit in sme: %d", status); wlan_hdd_tsf_init(hdd_ctx); - hdd_encrypt_decrypt_init(hdd_ctx); if (hdd_ctx->config->goptimize_chan_avoid_event) { status = sme_enable_disable_chanavoidind_event( @@ -10609,8 +10625,6 @@ static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx) /* De-init features */ hdd_features_deinit(hdd_ctx); - hdd_encrypt_decrypt_deinit(hdd_ctx); - sme_destroy_config(hdd_ctx->hHal); /* De-init Policy Manager */ @@ -10649,6 +10663,7 @@ static int hdd_deconfigure_cds(hdd_context_t *hdd_ctx) } + /** * hdd_wlan_stop_modules - Single driver state machine for stoping modules * @hdd_ctx: HDD context @@ -10666,9 +10681,7 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool ftm_mode) qdf_device_t qdf_ctx; QDF_STATUS qdf_status; int ret = 0; - bool is_unload_stop = cds_is_driver_unloading(); bool is_recover_stop = cds_is_driver_recovering(); - bool is_idle_stop = !is_unload_stop && !is_recover_stop; int active_threads; int debugfs_threads; @@ -10697,7 +10710,7 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool ftm_mode) if (active_threads) cds_print_external_threads(); - if (is_idle_stop && !ftm_mode) { + if (IS_IDLE_STOP && !ftm_mode) { mutex_unlock(&hdd_ctx->iface_change_lock); qdf_sched_delayed_work(&hdd_ctx->iface_idle_work, hdd_ctx->config->iface_change_wait_time); @@ -10785,7 +10798,7 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx, bool ftm_mode) ol_cds_free(); - if (is_idle_stop) { + if (IS_IDLE_STOP && cds_is_target_ready()) { ret = pld_power_off(qdf_ctx->dev); if (ret) hdd_err("CNSS power down failed put device into Low power mode:%d", @@ -10974,7 +10987,6 @@ int hdd_wlan_startup(struct device *dev) int ret; bool rtnl_held; - ENTER(); hdd_ctx = hdd_context_create(dev); @@ -11012,6 +11024,7 @@ int hdd_wlan_startup(struct device *dev) wlan_hdd_change_tdls_mode, hdd_ctx); + hdd_bus_bandwidth_init(hdd_ctx); hdd_driver_memdump_init(); ret = hdd_wlan_start_modules(hdd_ctx, NULL, false); @@ -11073,8 +11086,6 @@ int hdd_wlan_startup(struct device *dev) wlan_hdd_update_11n_mode(hdd_ctx->config); - hdd_bus_bandwidth_init(hdd_ctx); - hdd_lpass_notify_wlan_version(hdd_ctx); if (hdd_ctx->rps) @@ -11125,6 +11136,7 @@ err_exit_nl_srv: hdd_driver_memdump_deinit(); qdf_mc_timer_destroy(&hdd_ctx->tdls_source_timer); + hdd_bus_bandwidth_destroy(hdd_ctx); hdd_green_ap_deinit(hdd_ctx); hdd_request_manager_deinit(); @@ -11311,9 +11323,6 @@ int hdd_register_cb(hdd_context_t *hdd_ctx) if (!QDF_IS_STATUS_SUCCESS(status)) hdd_err("set bt activity info callback failed"); - sme_chain_rssi_register_callback(hdd_ctx->hHal, - wlan_hdd_cfg80211_chainrssi_callback); - status = sme_congestion_register_callback(hdd_ctx->hHal, hdd_update_cca_info_cb); if (!QDF_IS_STATUS_SUCCESS(status)) @@ -11801,7 +11810,6 @@ static bool hdd_any_adapter_is_assoc(hdd_context_t *hdd_ctx) status = hdd_get_front_adapter(hdd_ctx, &node); while (QDF_IS_STATUS_SUCCESS(status) && node) { hdd_adapter_t *adapter = node->pAdapter; - if (adapter && hdd_adapter_is_client(adapter) && WLAN_HDD_GET_STATION_CTX_PTR(adapter)-> @@ -11821,37 +11829,16 @@ static bool hdd_any_adapter_is_assoc(hdd_context_t *hdd_ctx) return false; } -static bool hdd_bus_bw_compute_timer_is_running(hdd_context_t *hdd_ctx) -{ - bool is_running; - - qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock); - is_running = hdd_ctx->bus_bw_timer_running; - qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock); - - return is_running; -} - -static void __hdd_bus_bw_compute_timer_start(hdd_context_t *hdd_ctx) -{ - qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock); - hdd_ctx->bus_bw_timer_running = true; - qdf_timer_start(&hdd_ctx->bus_bw_timer, - hdd_ctx->config->busBandwidthComputeInterval); - qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock); -} - void hdd_bus_bw_compute_timer_start(hdd_context_t *hdd_ctx) { ENTER(); - if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) { - hdd_debug("Bandwidth compute timer already started"); + if (QDF_TIMER_STATE_RUNNING == + qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) return; - } - - __hdd_bus_bw_compute_timer_start(hdd_ctx); + qdf_mc_timer_start(&hdd_ctx->bus_bw_timer, + hdd_ctx->config->busBandwidthComputeInterval); EXIT(); } @@ -11859,39 +11846,33 @@ void hdd_bus_bw_compute_timer_try_start(hdd_context_t *hdd_ctx) { ENTER(); - if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) { - hdd_debug("Bandwidth compute timer already started"); + if (QDF_TIMER_STATE_RUNNING == + qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) return; - } if (hdd_any_adapter_is_assoc(hdd_ctx)) - __hdd_bus_bw_compute_timer_start(hdd_ctx); - + qdf_mc_timer_start(&hdd_ctx->bus_bw_timer, + hdd_ctx->config-> + busBandwidthComputeInterval); EXIT(); -} -static void __hdd_bus_bw_compute_timer_stop(hdd_context_t *hdd_ctx) -{ - hdd_ipa_set_perf_level(hdd_ctx, 0, 0); - - qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock); - qdf_timer_stop(&hdd_ctx->bus_bw_timer); - hdd_ctx->bus_bw_timer_running = false; - qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock); - - hdd_reset_tcp_delack(hdd_ctx); } void hdd_bus_bw_compute_timer_stop(hdd_context_t *hdd_ctx) { ENTER(); - if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) { - hdd_debug("Bandwidth compute timer already stopped"); + if (QDF_TIMER_STATE_RUNNING != + qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) { + /* trying to stop timer, when not running is not good */ + hdd_debug("bus band width compute timer is not running"); return; } - __hdd_bus_bw_compute_timer_stop(hdd_ctx); + hdd_ipa_set_perf_level(hdd_ctx, 0, 0); + qdf_mc_timer_stop(&hdd_ctx->bus_bw_timer); + if (hdd_ctx->config->enable_tcp_delack) + hdd_reset_tcp_delack(hdd_ctx); EXIT(); } @@ -11900,14 +11881,20 @@ void hdd_bus_bw_compute_timer_try_stop(hdd_context_t *hdd_ctx) { ENTER(); - if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) { - hdd_debug("Bandwidth compute timer already stopped"); + if (QDF_TIMER_STATE_RUNNING != + qdf_mc_timer_get_current_state(&hdd_ctx->bus_bw_timer)) { + /* trying to stop timer, when not running is not good */ + hdd_debug("bus band width compute timer is not running"); return; } - if (!hdd_any_adapter_is_assoc(hdd_ctx)) - __hdd_bus_bw_compute_timer_stop(hdd_ctx); - + if (!hdd_any_adapter_is_assoc(hdd_ctx)) { + /* reset the ipa perf level */ + hdd_ipa_set_perf_level(hdd_ctx, 0, 0); + qdf_mc_timer_stop(&hdd_ctx->bus_bw_timer); + if (hdd_ctx->config->enable_tcp_delack) + hdd_reset_tcp_delack(hdd_ctx); + } EXIT(); } #endif @@ -12005,6 +11992,7 @@ void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter) hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter); hdd_debug("Now doing SAP STOPBSS"); qdf_event_reset(&hostapd_state->qdf_stop_bss_event); + hdd_ipa_ap_disconnect(ap_adapter); if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx-> sapContext)) { qdf_status = qdf_wait_for_event_completion( @@ -12101,30 +12089,6 @@ end: } /** - * wlan_hdd_soc_set_antenna_mode_cb() - Callback for set dual - * mac scan config - * @status: Status of set antenna mode - * - * Callback on setting the dual mac configuration - * - * Return: None - */ -void wlan_hdd_soc_set_antenna_mode_cb( - enum set_antenna_mode_status status) -{ - hdd_context_t *hdd_ctx; - - hdd_debug("Status: %d", status); - - hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - if (0 != wlan_hdd_validate_context(hdd_ctx)) - return; - - /* Signal the completion of set dual mac config */ - complete(&hdd_ctx->set_antenna_mode_cmpl); -} - -/** * hdd_get_fw_version() - Get FW version * @hdd_ctx: pointer to HDD context. * @major_spid: FW version - major spid. diff --git a/core/hdd/src/wlan_hdd_napi.c b/core/hdd/src/wlan_hdd_napi.c index d318c7534ee2..0793cc785ff1 100644 --- a/core/hdd/src/wlan_hdd_napi.c +++ b/core/hdd/src/wlan_hdd_napi.c @@ -240,7 +240,7 @@ int hdd_napi_event(enum qca_napi_event event, void *data) return rc; } -#ifdef HELIUMPLUS +#if defined HELIUMPLUS && defined MSM_PLATFORM /** * hdd_napi_perfd_cpufreq() - set/reset min CPU freq for cores * @req_state: high/low @@ -418,7 +418,7 @@ int hdd_napi_serialize(int is_on) } return rc; } -#endif /* HELIUMPLUS */ +#endif /* HELIUMPLUS && MSM_PLATFORM */ /** * hdd_napi_poll() - NAPI poll function diff --git a/core/hdd/src/wlan_hdd_ocb.c b/core/hdd/src/wlan_hdd_ocb.c index 3abc9a87f6ff..847762fe3abb 100644 --- a/core/hdd/src/wlan_hdd_ocb.c +++ b/core/hdd/src/wlan_hdd_ocb.c @@ -1303,6 +1303,7 @@ static void hdd_ocb_get_tsf_timer_callback(void *context_ptr, return; } + priv = hdd_request_priv(hdd_request); if (response) { priv->response = *response; priv->status = 0; diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index 3f8c57821c96..3d7955bda2e2 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -3306,8 +3306,8 @@ static inline bool is_public_action_frame(uint8_t *pb_frames, static inline bool is_p2p_action_frame(uint8_t *pb_frames, uint32_t frame_len) { - if (frame_len <= WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + - SIR_MAC_P2P_OUI_SIZE) { + if (frame_len <= (WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET + + SIR_MAC_P2P_OUI_SIZE + 2)) { hdd_debug("Not a p2p action frame len: %d", frame_len); return false; } diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 5004526df150..59d3f0995e14 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1522,10 +1522,10 @@ QDF_STATUS hdd_wlan_shutdown(void) qdf_mc_timer_stop(&pHddCtx->tdls_source_timer); - hdd_bus_bandwidth_destroy(pHddCtx); - hdd_wlan_stop_modules(pHddCtx, false); + hdd_bus_bandwidth_destroy(pHddCtx); + hdd_lpass_notify_stop(pHddCtx); hdd_info("WLAN driver shutdown complete"); @@ -1587,6 +1587,28 @@ static void hdd_send_default_scan_ies(hdd_context_t *hdd_ctx) } } +void hdd_is_interface_down_during_ssr(hdd_context_t *hdd_ctx) +{ + hdd_adapter_t *adapter = NULL; + hdd_adapter_list_node_t *adapternode = NULL, *pnext = NULL; + QDF_STATUS status; + + ENTER(); + + status = hdd_get_front_adapter(hdd_ctx, &adapternode); + while (NULL != adapternode && QDF_STATUS_SUCCESS == status) { + adapter = adapternode->pAdapter; + if (test_bit(DOWN_DURING_SSR, &adapter->event_flags)) { + hdd_stop_adapter(hdd_ctx, adapter, true); + clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); + } + status = hdd_get_next_adapter(hdd_ctx, adapternode, &pnext); + adapternode = pnext; + } + + EXIT(); +} + /** * hdd_wlan_re_init() - HDD SSR re-init function * @@ -1673,7 +1695,7 @@ err_re_init: success: if (pHddCtx->config->sap_internal_restart) hdd_ssr_restart_sap(pHddCtx); - + hdd_is_interface_down_during_ssr(pHddCtx); hdd_wlan_ssr_reinit_event(); return QDF_STATUS_SUCCESS; } @@ -2031,7 +2053,8 @@ next_adapter: pScanInfo = &pAdapter->scan_info; if (sme_neighbor_middle_of_roaming - (pHddCtx->hHal, pAdapter->sessionId)) { + (pHddCtx->hHal, pAdapter->sessionId) || + hdd_is_roaming_in_progress(pHddCtx)) { hdd_err("Roaming in progress, do not allow suspend"); wlan_hdd_inc_suspend_stats(pHddCtx, SUSPEND_FAIL_ROAM); diff --git a/core/hdd/src/wlan_hdd_request_manager.c b/core/hdd/src/wlan_hdd_request_manager.c index a90b928e8c9d..0c2ef5614b61 100644 --- a/core/hdd/src/wlan_hdd_request_manager.c +++ b/core/hdd/src/wlan_hdd_request_manager.c @@ -83,15 +83,14 @@ struct hdd_request *hdd_request_alloc(const struct hdd_request_params *params) struct hdd_request *request; if (!is_initialized) { - hdd_err("invoked when not initialized from %pS", - (void *)_RET_IP_); + hdd_err("invoked when not initialized"); return NULL; } length = sizeof(*request) + params->priv_size; request = qdf_mem_malloc(length); if (!request) { - hdd_err("allocation failed for %pS", (void *)_RET_IP_); + hdd_err("allocation failed"); return NULL; } request->reference_count = 1; @@ -101,8 +100,7 @@ struct hdd_request *hdd_request_alloc(const struct hdd_request_params *params) request->cookie = cookie++; qdf_list_insert_back(&requests, &request->node); qdf_spin_unlock_bh(&spinlock); - hdd_debug("request %pK, cookie %pK, caller %pS", - request, request->cookie, (void *)_RET_IP_); + hdd_debug("request %pK, cookie %pK", request, request->cookie); return request; } @@ -123,8 +121,7 @@ struct hdd_request *hdd_request_get(void *cookie) struct hdd_request *request; if (!is_initialized) { - hdd_err("invoked when not initialized from %pS", - (void *)_RET_IP_); + hdd_err("invoked when not initialized"); return NULL; } qdf_spin_lock_bh(&spinlock); @@ -132,8 +129,7 @@ struct hdd_request *hdd_request_get(void *cookie) if (request) request->reference_count++; qdf_spin_unlock_bh(&spinlock); - hdd_debug("cookie %pK, request %pK, caller %pS", - cookie, request, (void *)_RET_IP_); + hdd_debug("cookie %pK, request %pK", cookie, request); return request; } @@ -142,8 +138,7 @@ void hdd_request_put(struct hdd_request *request) { bool unlinked = false; - hdd_debug("request %pK, cookie %pK, caller %pS", - request, request->cookie, (void *)_RET_IP_); + hdd_debug("request %pK, cookie %pK", request, request->cookie); qdf_spin_lock_bh(&spinlock); request->reference_count--; if (0 == request->reference_count) { @@ -172,7 +167,6 @@ void hdd_request_complete(struct hdd_request *request) void hdd_request_manager_init(void) { - hdd_debug("%pS", (void *)_RET_IP_); if (is_initialized) return; @@ -190,6 +184,5 @@ void hdd_request_manager_init(void) */ void hdd_request_manager_deinit(void) { - hdd_debug("%pS", (void *)_RET_IP_); is_initialized = false; } diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index 87dcbaf315c1..98d7ac6451d4 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -644,8 +644,8 @@ static void hdd_update_dbs_scan_ctrl_ext_flag(hdd_context_t *hdd_ctx, } if (!(hdd_ctx->is_dbs_scan_duty_cycle_enabled)) { scan_dbs_policy = SME_SCAN_DBS_POLICY_IGNORE_DUTY; - hdd_info_ratelimited(HDD_DBS_SCAN_DISABLE_RATE_LIMIT, - "DBS scan duty cycle is disabled"); + hdd_debug_ratelimited(HDD_DBS_SCAN_DISABLE_RATE_LIMIT, + "DBS scan duty cycle is disabled"); goto end; } @@ -2363,6 +2363,12 @@ static int __wlan_hdd_cfg80211_scan(struct wiphy *wiphy, pAdapter->sessionId); } if (request->ie_len) { + if (request->ie_len > SIR_MAC_MAX_ADD_IE_LENGTH) { + hdd_debug("Invalid ie_len: %zu", request->ie_len); + status = -EINVAL; + goto free_mem; + } + /* save this for future association (join requires this) */ memset(&pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE)); memcpy(pScanInfo->scanAddIE.addIEdata, request->ie, @@ -2731,6 +2737,16 @@ static int wlan_hdd_vendor_scan_random_attr(struct wiphy *wiphy, return -EOPNOTSUPP; } + if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] && + !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) { + qdf_mem_zero(request->mac_addr, QDF_MAC_ADDR_SIZE); + qdf_mem_zero(request->mac_addr_mask, QDF_MAC_ADDR_SIZE); + request->mac_addr[0] = 0x2; + request->mac_addr_mask[0] = 0x3; + + return 0; + } + if (!tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC] || !tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK]) return -EINVAL; @@ -3941,6 +3957,8 @@ void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx, hdd_adapter_t *padapter) } else if (!req) { hdd_debug("pending scan is wext triggered"); } else { + hdd_debug("Removing scan id: %d, req = %pK", + scan_id, req); if (NL_SCAN == source) hdd_cfg80211_scan_done(adapter, req, aborted); @@ -3948,8 +3966,6 @@ void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx, hdd_adapter_t *padapter) hdd_vendor_scan_callback(adapter, req, aborted, scan_id); - hdd_debug("removed Scan id: %d, req = %pK", - scan_id, req); } qdf_mem_free(hdd_scan_req); qdf_spin_lock(&hdd_ctx->hdd_scan_req_q_lock); diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c index 11b927486171..0dfbfe3f3bfb 100644 --- a/core/hdd/src/wlan_hdd_softap_tx_rx.c +++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c @@ -1196,7 +1196,8 @@ QDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter) } } } - if (pAdapter->device_mode == QDF_SAP_MODE) + if (pAdapter->device_mode == QDF_SAP_MODE && + !pHddCtx->config->disable_channel) wlan_hdd_restore_channels(pHddCtx); /* Mark the indoor channel (passive) to enable */ @@ -1206,14 +1207,6 @@ QDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter) sme_update_channel_list(pHddCtx->hHal); } - if (hdd_ipa_is_enabled(pHddCtx)) { - if (hdd_ipa_wlan_evt(pAdapter, - WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->uBCStaId, - HDD_IPA_AP_DISCONNECT, - pAdapter->dev->dev_addr)) - hdd_err("WLAN_AP_DISCONNECT event failed"); - } - return qdf_status; } diff --git a/core/hdd/src/wlan_hdd_spectral.c b/core/hdd/src/wlan_hdd_spectral.c index 7b6735d24922..23cb9e4fecfe 100644 --- a/core/hdd/src/wlan_hdd_spectral.c +++ b/core/hdd/src/wlan_hdd_spectral.c @@ -115,7 +115,10 @@ static int __wlan_hdd_cfg80211_spectral_scan_start(struct wiphy *wiphy, return -EPERM; } adapter = WLAN_HDD_GET_PRIV_PTR(dev); - + if (wlan_hdd_validate_session_id(adapter->sessionId)) { + hdd_err("invalid session id: %d", adapter->sessionId); + return -EINVAL; + } /* initialize config parameters*/ config_req = hdd_ctx->ss_config; diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c index 51e305c7630c..6efe9edb7b98 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -127,7 +127,6 @@ static int rssi_mcs_tbl[][10] = { #ifdef WLAN_FEATURE_LINK_LAYER_STATS -static struct hdd_ll_stats_context ll_stats_context; /** * put_wifi_rate_stat() - put wifi rate stats @@ -1030,20 +1029,22 @@ static void hdd_ll_process_peer_stats(hdd_adapter_t *adapter, * @ctx: Pointer to hdd context * @indType: Indication type * @pRsp: Pointer to response + * @cookie: Callback context * * After receiving Link Layer indications from FW.This callback converts the * firmware data to the NL data and send the same to the kernel/upper layers. * * Return: None */ -void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, - int indType, void *pRsp) +void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, int indType, + void *pRsp, void *cookie) { hdd_context_t *pHddCtx = (hdd_context_t *) ctx; - struct hdd_ll_stats_context *context; + struct hdd_ll_stats_priv *priv = NULL; hdd_adapter_t *pAdapter = NULL; tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults) pRsp; int status; + struct hdd_request *request = NULL; status = wlan_hdd_validate_context(pHddCtx); if (status) @@ -1052,7 +1053,7 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, pAdapter = hdd_get_adapter_by_vdev(pHddCtx, linkLayerStatsResults->ifaceId); - if (NULL == pAdapter) { + if (!pAdapter) { hdd_err("vdev_id %d does not exist with host", linkLayerStatsResults->ifaceId); return; @@ -1071,18 +1072,23 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, linkLayerStatsResults->num_radio, linkLayerStatsResults->results); - context = &ll_stats_context; - spin_lock(&context->context_lock); + request = hdd_request_get(cookie); + if (!request) { + hdd_err("Obselete request"); + return; + } + + priv = hdd_request_priv(request); + /* validate response received from target */ - if ((context->request_id != linkLayerStatsResults->rspId) || - !(context->request_bitmap & linkLayerStatsResults->paramId)) { - spin_unlock(&context->context_lock); + if ((priv->request_id != linkLayerStatsResults->rspId) || + !(priv->request_bitmap & linkLayerStatsResults->paramId)) { hdd_err("Error : Request id %d response id %d request bitmap 0x%x response bitmap 0x%x", - context->request_id, linkLayerStatsResults->rspId, - context->request_bitmap, linkLayerStatsResults->paramId); + priv->request_id, linkLayerStatsResults->rspId, + priv->request_bitmap, linkLayerStatsResults->paramId); + hdd_request_put(request); return; } - spin_unlock(&context->context_lock); if (linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO) { hdd_ll_process_radio_stats(pAdapter, @@ -1091,10 +1097,8 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, linkLayerStatsResults->num_radio, linkLayerStatsResults->rspId); - spin_lock(&context->context_lock); if (!linkLayerStatsResults->moreResultToFollow) - context->request_bitmap &= ~(WMI_LINK_STATS_RADIO); - spin_unlock(&context->context_lock); + priv->request_bitmap &= ~(WMI_LINK_STATS_RADIO); } else if (linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE) { @@ -1103,17 +1107,15 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, linkLayerStatsResults->num_peers, linkLayerStatsResults->rspId); - spin_lock(&context->context_lock); /* Firmware doesn't send peerstats event if no peers are * connected. HDD should not wait for any peerstats in * this case and return the status to middleware after * receiving iface stats */ if (!linkLayerStatsResults->num_peers) - context->request_bitmap &= + priv->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER); - context->request_bitmap &= ~(WMI_LINK_STATS_IFACE); - spin_unlock(&context->context_lock); + priv->request_bitmap &= ~(WMI_LINK_STATS_IFACE); } else if (linkLayerStatsResults-> paramId & WMI_LINK_STATS_ALL_PEER) { @@ -1122,21 +1124,19 @@ void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, linkLayerStatsResults->results, linkLayerStatsResults->rspId); - spin_lock(&context->context_lock); if (!linkLayerStatsResults->moreResultToFollow) - context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER); - spin_unlock(&context->context_lock); + priv->request_bitmap &= + ~(WMI_LINK_STATS_ALL_PEER); } else { hdd_err("INVALID LL_STATS_NOTIFY RESPONSE"); } - spin_lock(&context->context_lock); /* complete response event if all requests are completed */ - if (0 == context->request_bitmap) - complete(&context->response_event); - spin_unlock(&context->context_lock); + if (!priv->request_bitmap) + hdd_request_complete(request); + hdd_request_put(request); break; } default: @@ -1213,6 +1213,17 @@ __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy, if (0 != status) return -EINVAL; + if (hdd_validate_adapter(pAdapter)) { + hdd_err("Invalid Adapter"); + return -EINVAL; + } + + if (pAdapter->device_mode != QDF_STA_MODE) { + hdd_debug("Cannot set LL_STATS for device mode %d", + pAdapter->device_mode); + return -EINVAL; + } + if (hdd_nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX, (struct nlattr *)data, data_len, qca_wlan_vendor_ll_set_policy)) { @@ -1301,34 +1312,59 @@ nla_policy [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = {.type = NLA_U32} }; +/** + * wlan_hdd_send_ll_stats_req() - send LL stats request + * @hdd_ctx: pointer to hdd context + * @req: pointer to LL stats get request + * + * Return: 0 if success, non-zero if failure + */ static int wlan_hdd_send_ll_stats_req(hdd_context_t *hdd_ctx, tSirLLStatsGetReq *req) { - unsigned long rc; - struct hdd_ll_stats_context *context; + int ret = 0; + struct hdd_ll_stats_priv *priv = NULL; + struct hdd_request *request = NULL; + void *cookie = NULL; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_LL_STATS, + }; + + ENTER(); + + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request Allocation Failure"); + return -ENOMEM; + } - context = &ll_stats_context; - spin_lock(&context->context_lock); - context->request_id = req->reqId; - context->request_bitmap = req->paramIdMask; - INIT_COMPLETION(context->response_event); - spin_unlock(&context->context_lock); + cookie = hdd_request_cookie(request); + + priv = hdd_request_priv(request); + + priv->request_id = req->reqId; + priv->request_bitmap = req->paramIdMask; if (QDF_STATUS_SUCCESS != - sme_ll_stats_get_req(hdd_ctx->hHal, req)) { + sme_ll_stats_get_req(hdd_ctx->hHal, req, cookie)) { hdd_err("sme_ll_stats_get_req Failed"); - return -EINVAL; + ret = -EINVAL; + goto exit; } - rc = wait_for_completion_timeout(&context->response_event, - msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS)); - if (!rc) { + ret = hdd_request_wait_for_response(request); + if (ret) { hdd_err("Target response timed out request id %d request bitmap 0x%x", - context->request_id, context->request_bitmap); - return -ETIMEDOUT; + priv->request_id, priv->request_bitmap); + ret = -ETIMEDOUT; + goto exit; } + EXIT(); - return 0; +exit: + hdd_request_put(request); + return ret; } int wlan_hdd_ll_stats_get(hdd_adapter_t *adapter, uint32_t req_id, @@ -1355,9 +1391,10 @@ int wlan_hdd_ll_stats_get(hdd_adapter_t *adapter, uint32_t req_id, return -EBUSY; } - if (!adapter->isLinkLayerStatsSet) - hdd_info("isLinkLayerStatsSet: %d; STATs will be all zero", - adapter->isLinkLayerStatsSet); + if (!adapter->isLinkLayerStatsSet) { + hdd_info("LL_STATs not set"); + return -EINVAL; + } get_req.reqId = req_id; get_req.paramIdMask = req_mask; @@ -4839,17 +4876,6 @@ int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy, return ret; } -/** - * hdd_init_ll_stats_ctx() - initialize link layer stats context - * - * Return: none - */ -inline void hdd_init_ll_stats_ctx(void) -{ - spin_lock_init(&ll_stats_context.context_lock); - init_completion(&ll_stats_context.response_event); - ll_stats_context.request_bitmap = 0; -} /** * hdd_display_hif_stats() - display hif stats diff --git a/core/hdd/src/wlan_hdd_stats.h b/core/hdd/src/wlan_hdd_stats.h index 45d805fdf48f..496106f682a3 100644 --- a/core/hdd/src/wlan_hdd_stats.h +++ b/core/hdd/src/wlan_hdd_stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -80,17 +80,14 @@ struct index_data_rate_type { #ifdef WLAN_FEATURE_LINK_LAYER_STATS /** - * struct hdd_ll_stats_context - hdd link layer stats context + * struct hdd_ll_stats_priv - hdd link layer stats private * * @request_id: userspace-assigned link layer stats request id * @request_bitmap: userspace-assigned link layer stats request bitmap - * @response_event: LL stats request wait event */ -struct hdd_ll_stats_context { +struct hdd_ll_stats_priv { uint32_t request_id; uint32_t request_bitmap; - struct completion response_event; - spinlock_t context_lock; }; /* @@ -283,8 +280,8 @@ void wlan_hdd_cfg80211_stats_ext_callback(void *ctx, void wlan_hdd_cfg80211_stats_ext2_callback(void *ctx, struct stats_ext2_event *pmsg); -void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, - int indType, void *pRsp); +void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, int indType, + void *pRsp, void *context); /** * wlan_hdd_get_rcpi() - Wrapper to get current RCPI diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index ca758c9c571a..7c7a8a70a9e2 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -1959,7 +1959,7 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, /* If TDLS support is disabled then no need to update target */ if (false == hdd_ctx->config->fEnableTDLSSupport) { - hdd_err("TDLS not enabled"); + hdd_err("TDLS not supported"); goto done; } @@ -1995,6 +1995,11 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, */ hdd_ctx->tdls_source_bitmap = 0; } else { + if (!hdd_ctx->enable_tdls_in_fw) { + hdd_debug("Current HW mode is dbs, don't enable tdls in FW, wait for HW mode change"); + mutex_unlock(&hdd_ctx->tdls_lock); + goto done; + } if (false == hdd_ctx->config->fEnableTDLSImplicitTrigger) { hdd_ctx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY; } else if (true == hdd_ctx->config->fTDLSExternalControl) { @@ -2231,7 +2236,14 @@ void wlan_hdd_check_conc_and_update_tdls_state(hdd_context_t *hdd_ctx, hdd_ctx, true); return; } - wlan_hdd_update_tdls_info(temp_adapter, false, false); + mutex_lock(&hdd_ctx->tdls_lock); + if (eTDLS_SUPPORT_NOT_ENABLED == hdd_ctx->tdls_mode || + hdd_ctx->set_state_info.set_state_cnt == 0) { + mutex_unlock(&hdd_ctx->tdls_lock); + wlan_hdd_update_tdls_info(temp_adapter, false, false); + return; + } + mutex_unlock(&hdd_ctx->tdls_lock); } } @@ -5620,7 +5632,8 @@ static void wlan_hdd_tdls_ct_sampling_tx_rx(hdd_adapter_t *adapter, return; } - valid_mac_entries = hdd_ctx->valid_mac_entries; + valid_mac_entries = QDF_MIN(hdd_ctx->valid_mac_entries, + TDLS_CT_MAC_MAX_TABLE_SIZE); memcpy(ct_peer_mac_table, hdd_ctx->ct_peer_mac_table, (sizeof(struct tdls_ct_mac_table)) * valid_mac_entries); @@ -6490,6 +6503,7 @@ void hdd_tdls_notify_hw_mode_change(bool is_dbs_hw_mode) hdd_context_t *hdd_ctx; v_CONTEXT_t g_context; enum tdls_support_mode tdls_mode; + hdd_adapter_t *temp_adapter; g_context = cds_get_global_context(); @@ -6501,7 +6515,14 @@ void hdd_tdls_notify_hw_mode_change(bool is_dbs_hw_mode) if (!hdd_ctx) return; - if (hdd_ctx->tdls_mode == eTDLS_SUPPORT_NOT_ENABLED) { + mutex_lock(&hdd_ctx->tdls_lock); + if (is_dbs_hw_mode) + hdd_ctx->enable_tdls_in_fw = false; + else + hdd_ctx->enable_tdls_in_fw = true; + mutex_unlock(&hdd_ctx->tdls_lock); + + if (hdd_ctx->tdls_mode == eTDLS_SUPPORT_NOT_ENABLED && is_dbs_hw_mode) { hdd_debug("TDLS mode is not enabled continue with hw mode change"); return; } @@ -6534,8 +6555,17 @@ void hdd_tdls_notify_hw_mode_change(bool is_dbs_hw_mode) revert_tdls_mode: hdd_debug("hw mode is non DBS, so revert to last tdls mode %d", tdls_mode); - wlan_hdd_tdls_set_mode(hdd_ctx, - tdls_mode, - false, - HDD_SET_TDLS_MODE_SOURCE_POLICY_MGR); + temp_adapter = wlan_hdd_tdls_get_adapter(hdd_ctx); + if (temp_adapter) { + mutex_lock(&hdd_ctx->tdls_lock); + if (hdd_ctx->set_state_info.set_state_cnt == 0) { + mutex_unlock(&hdd_ctx->tdls_lock); + hdd_debug("HW mode is changed to Non DBS enable TDLS in FW"); + wlan_hdd_update_tdls_info(temp_adapter, false, false); + } else { + mutex_unlock(&hdd_ctx->tdls_lock); + } + wlan_hdd_tdls_set_mode(hdd_ctx, tdls_mode, false, + HDD_SET_TDLS_MODE_SOURCE_POLICY_MGR); + } } diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 89c5ac95997e..e8640faab7b4 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -1453,11 +1453,11 @@ static bool hdd_is_duplicate_ip_arp(struct sk_buff *skb) if (NULL == skb) return false; - arp_ip = hdd_get_arp_src_ip(skb); - if (!skb->dev) return false; + arp_ip = hdd_get_arp_src_ip(skb); + in_dev = __in_dev_get_rtnl(skb->dev); if (in_dev) { for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 21bb16a287fd..463a351d4fba 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -2703,7 +2703,7 @@ int hdd_priv_get_data(struct iw_point *p_priv_data, union iwreq_data *wrqu) return -EINVAL; #ifdef CONFIG_COMPAT - if (is_compat_task()) { + if (in_compat_syscall()) { struct compat_iw_point *p_compat_priv_data; /* Compat task: @@ -9367,7 +9367,6 @@ static int __iw_get_char_setnone(struct net_device *dev, int count = 0, check = 1; tHalHandle hHal = NULL; - tpAniSirGlobal pMac = NULL; hdd_station_ctx_t *pHddStaCtx = NULL; hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); @@ -9424,16 +9423,7 @@ static int __iw_get_char_setnone(struct net_device *dev, buf = scnprintf(extra + len, WE_MAX_STR_LEN - len, - "\n pMac is NULL"); - len += buf; - break; - } - pMac = PMAC_STRUCT(hHal); - if (!pMac) { - buf = - scnprintf(extra + len, - WE_MAX_STR_LEN - len, - "\n pMac is NULL"); + "\n hHal is NULL"); len += buf; break; } @@ -9880,7 +9870,7 @@ static int __iw_setnone_getnone(struct net_device *dev, * compat support in the kernel does not handle this case. so we * need to explicitly handle it here. */ - if (is_compat_task()) { + if (in_compat_syscall()) { struct compat_iw_point *compat_iw_point = (struct compat_iw_point *)&wrqu->data; sub_cmd = compat_iw_point->flags; @@ -12232,6 +12222,12 @@ static int __iw_set_two_ints_getnone(struct net_device *dev, hdd_warn("Crash Inject ini disabled"); return 0; } + + if (value[1] == 3) { + hdd_warn("Trigger host initiated recovery"); + cds_trigger_recovery(CDS_REASON_UNSPECIFIED); + return 0; + } ret = wma_cli_set2_command(pAdapter->sessionId, GEN_PARAM_CRASH_INJECT, value[1], value[2], GEN_CMD); diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index e9a86b37142c..7c831aacb4c6 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -790,7 +790,6 @@ typedef struct sAniSirLim { /* ////////////////////////////// HT RELATED ////////////////////////////////////////// */ #ifdef FEATURE_WLAN_TDLS - uint8_t gLimAddStaTdls; uint8_t gLimTdlsLinkMode; /* ////////////////////////////// TDLS RELATED ////////////////////////////////////////// */ #endif @@ -1018,6 +1017,7 @@ typedef struct sAniSirGlobal { uint32_t peer_rssi; uint32_t peer_txrate; uint32_t peer_rxrate; + uint32_t rx_mc_bc_cnt; } tAniSirGlobal; typedef enum { diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index 04f7d4afb774..53bc7ea6d796 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 60 +#define QWLAN_VERSION_EXTRA "P" +#define QWLAN_VERSION_BUILD 63 -#define QWLAN_VERSIONSTR "5.1.1.60W" +#define QWLAN_VERSIONSTR "5.1.1.63P" #endif /* QWLAN_VERSION_H */ diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index a25235311cc5..9f282ccae43e 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -573,16 +573,35 @@ struct sir_set_dual_mac_cfg { }; /** + * enum set_antenna_mode_status - Status of set antenna mode + * command + * @SET_ANTENNA_MODE_STATUS_OK: command successful + * @SET_ANTENNA_MODE_STATUS_EINVAL: invalid antenna mode + * @SET_ANTENNA_MODE_STATUS_ECANCELED: mode change cancelled + * @SET_ANTENNA_MODE_STATUS_ENOTSUP: mode not supported + */ +enum set_antenna_mode_status { + SET_ANTENNA_MODE_STATUS_OK, + SET_ANTENNA_MODE_STATUS_EINVAL, + SET_ANTENNA_MODE_STATUS_ECANCELED, + SET_ANTENNA_MODE_STATUS_ENOTSUP, +}; + +typedef void (*antenna_mode_cb)(enum set_antenna_mode_status status, + void *context); + +/** * struct sir_antenna_mode_param - antenna mode param * @num_tx_chains: Number of TX chains * @num_rx_chains: Number of RX chains - * @reason: Reason for setting antenna mode * @set_antenna_mode_resp: callback to set antenna mode command + * @set_antenna_mode_ctx: callback context to set antenna mode command */ struct sir_antenna_mode_param { uint32_t num_tx_chains; uint32_t num_rx_chains; - void *set_antenna_mode_resp; + antenna_mode_cb set_antenna_mode_resp; + void *set_antenna_mode_ctx; }; /** @@ -1495,6 +1514,7 @@ typedef struct sSirSmeAssocInd { tDot11fIEHTCaps HTCaps; tDot11fIEVHTCaps VHTCaps; + tSirMacCapabilityInfo capability_info; } tSirSmeAssocInd, *tpSirSmeAssocInd; /* / Definition for Association confirm */ @@ -3840,6 +3860,7 @@ typedef struct { uint32_t kek_len; uint64_t ullKeyReplayCounter; /* replay counter */ struct qdf_mac_addr bssid; + bool is_fils_connection; } tSirGtkOffloadParams, *tpSirGtkOffloadParams; /*--------------------------------------------------------------------------- @@ -4011,21 +4032,6 @@ struct sir_dual_mac_config_resp { }; /** - * enum set_antenna_mode_status - Status of set antenna mode - * command - * @SET_ANTENNA_MODE_STATUS_OK: command successful - * @SET_ANTENNA_MODE_STATUS_EINVAL: invalid antenna mode - * @SET_ANTENNA_MODE_STATUS_ECANCELED: mode change cancelled - * @SET_ANTENNA_MODE_STATUS_ENOTSUP: mode not supported - */ -enum set_antenna_mode_status { - SET_ANTENNA_MODE_STATUS_OK, - SET_ANTENNA_MODE_STATUS_EINVAL, - SET_ANTENNA_MODE_STATUS_ECANCELED, - SET_ANTENNA_MODE_STATUS_ENOTSUP, -}; - -/** * struct sir_antenna_mode_resp - set antenna mode response * @status: Status of setting the antenna mode */ @@ -4515,6 +4521,11 @@ struct sir_peer_info_req { * @rssi: rssi * @tx_rate: last tx rate * @rx_rate: last rx rate + * @rx_mc_bc_cnt: Multicast broadcast packet count received from + * current station + * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt + * feature or not, if first bit is 1 it indictes that FW supports this + * feature, if it is 0 it indicates FW doesn't support this feature * * a station's information */ @@ -4523,6 +4534,7 @@ struct sir_peer_info { int8_t rssi; uint32_t tx_rate; uint32_t rx_rate; + uint32_t rx_mc_bc_cnt; }; /** @@ -6785,7 +6797,6 @@ typedef void (*hw_mode_transition_cb)(uint32_t old_hw_mode_index, uint32_t new_hw_mode_index, uint32_t num_vdev_mac_entries, struct sir_vdev_mac_map *vdev_mac_map); -typedef void (*antenna_mode_cb)(uint32_t status); /** * struct sir_nss_update_request diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index f8d35c988654..9096b361dabd 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -188,6 +188,8 @@ #define SIR_MAC_VHT_GID_NOTIFICATION 1 #define SIR_MAC_VHT_OPMODE_NOTIFICATION 2 +#define SIR_MAC_VHT_OPMODE_SIZE 3 + #define NUM_OF_SOUNDING_DIMENSIONS 1 /*Nss - 1, (Nss = 2 for 2x2)*/ /* HT Action Field Codes */ #define SIR_MAC_SM_POWER_SAVE 1 @@ -627,6 +629,11 @@ #define SIR_MAC_VENDOR_AP_4_OUI "\x8C\xFD\xF0" #define SIR_MAC_VENDOR_AP_4_OUI_LEN 3 + +/* Maximum allowable size of a beacon and probe rsp frame */ +#define SIR_MAX_BEACON_SIZE 512 +#define SIR_MAX_PROBE_RESP_SIZE 512 + /* / Status Code (present in Management response frames) enum */ typedef enum eSirMacStatusCodes { diff --git a/core/mac/inc/wni_cfg.h b/core/mac/inc/wni_cfg.h index 348995cdae84..6a436fc3c708 100644 --- a/core/mac/inc/wni_cfg.h +++ b/core/mac/inc/wni_cfg.h @@ -247,6 +247,14 @@ enum { WNI_CFG_PS_WOW_DATA_INACTIVITY_TIMEOUT, WNI_CFG_RATE_FOR_TX_MGMT_2G, WNI_CFG_RATE_FOR_TX_MGMT_5G, + WNI_CFG_EDCA_ETSI_ACBK_LOCAL, + WNI_CFG_EDCA_ETSI_ACBE_LOCAL, + WNI_CFG_EDCA_ETSI_ACVI_LOCAL, + WNI_CFG_EDCA_ETSI_ACVO_LOCAL, + WNI_CFG_EDCA_ETSI_ACBK, + WNI_CFG_EDCA_ETSI_ACBE, + WNI_CFG_EDCA_ETSI_ACVI, + WNI_CFG_EDCA_ETSI_ACVO, /* Any new items to be added should be above this strictly */ CFG_PARAM_MAX_NUM }; @@ -290,6 +298,14 @@ enum { #define WNI_CFG_EDCA_WME_ACBE_LEN 20 #define WNI_CFG_EDCA_WME_ACVI_LEN 20 #define WNI_CFG_EDCA_WME_ACVO_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACBK_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACBE_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACVI_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACVO_LOCAL_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACBK_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACBE_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACVI_LEN 20 +#define WNI_CFG_EDCA_ETSI_ACVO_LEN 20 #define WNI_CFG_SCAN_CONTROL_LIST_LEN 128 #define WNI_CFG_SUPPORTED_MCS_SET_LEN 16 #define WNI_CFG_BASIC_MCS_SET_LEN 16 @@ -673,7 +689,8 @@ enum { #define WNI_CFG_EDCA_PROFILE_ANI 0 #define WNI_CFG_EDCA_PROFILE_WMM 1 #define WNI_CFG_EDCA_PROFILE_TIT_DEMO 2 -#define WNI_CFG_EDCA_PROFILE_MAX 3 +#define WNI_CFG_EDCA_PROFILE_ETSI_EUROPE 3 +#define WNI_CFG_EDCA_PROFILE_MAX 4 #define WNI_CFG_EDCA_PROFILE_ACM_IDX 0 #define WNI_CFG_EDCA_PROFILE_AIFSN_IDX 1 #define WNI_CFG_EDCA_PROFILE_CWMINA_IDX 2 diff --git a/core/mac/src/cfg/cfg_param_name.c b/core/mac/src/cfg/cfg_param_name.c index be0063d7c847..d960a6219657 100644 --- a/core/mac/src/cfg/cfg_param_name.c +++ b/core/mac/src/cfg/cfg_param_name.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 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 @@ -329,4 +329,12 @@ unsigned char *g_cfg_param_name[] = { (unsigned char *)"SAP_MAX_MCS_DATA", (unsigned char *)"RATE_FOR_TX_MGMT_2G", (unsigned char *)"RATE_FOR_TX_MGMT_5G", + (unsigned char *)"EDCA_ETSI_ACBK_LOCAL", + (unsigned char *)"EDCA_ETSI_ACBE_LOCAL", + (unsigned char *)"EDCA_ETSI_ACVI_LOCAL", + (unsigned char *)"EDCA_ETSI_ACVO_LOCAL", + (unsigned char *)"EDCA_ETSI_ACBK", + (unsigned char *)"EDCA_ETSI_ACBE", + (unsigned char *)"EDCA_ETSI_ACVI", + (unsigned char *)"EDCA_ETSI_ACVO", }; diff --git a/core/mac/src/cfg/cfg_proc_msg.c b/core/mac/src/cfg/cfg_proc_msg.c index 33a92dd45862..14c64325eb38 100644 --- a/core/mac/src/cfg/cfg_proc_msg.c +++ b/core/mac/src/cfg/cfg_proc_msg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 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 @@ -1164,6 +1164,30 @@ cgstatic cfg_static[CFG_PARAM_MAX_NUM] = { WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMIN, WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMAX, WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF}, + {WNI_CFG_EDCA_ETSI_ACBK_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ETSI_ACBE_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ETSI_ACVI_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ETSI_ACVO_LOCAL, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ETSI_ACBK, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ETSI_ACBE, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ETSI_ACVI, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, + {WNI_CFG_EDCA_ETSI_ACVO, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, + 0, 0, 0}, }; @@ -1360,7 +1384,47 @@ cfgstatic_string cfg_static_string[CFG_MAX_STATIC_STRING] = { {WNI_CFG_WPS_UUID, WNI_CFG_WPS_UUID_LEN, 6, - {0xa, 0xb, 0xc, 0xd, 0xe, 0xf} } + {0xa, 0xb, 0xc, 0xd, 0xe, 0xf} }, + {WNI_CFG_EDCA_ETSI_ACBK_LOCAL, + WNI_CFG_EDCA_ETSI_ACBK_LOCAL_LEN, + 17, + {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0xbb, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, + 0xf, 0x3, 0xff, 0x0} }, + {WNI_CFG_EDCA_ETSI_ACBE_LOCAL, + WNI_CFG_EDCA_ETSI_ACBE_LOCAL_LEN, + 17, + {0x0, 0x3, 0x0, 0xf, 0x0, 0x3f, 0xbb, 0x0, 0x1f, 0x3, 0xff, 0x0, 0x0, + 0xf, 0x0, 0x3f, 0x0} }, + {WNI_CFG_EDCA_ETSI_ACVI_LOCAL, + WNI_CFG_EDCA_ETSI_ACVI_LOCAL_LEN, + 17, + {0x0, 0x1, 0x0, 0x7, 0x0, 0xf, 0x7d, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, + 0x7, 0x0, 0xf, 0x5e} }, + {WNI_CFG_EDCA_ETSI_ACVO_LOCAL, + WNI_CFG_EDCA_ETSI_ACVO_LOCAL_LEN, + 17, + {0x0, 0x1, 0x0, 0x3, 0x0, 0x7, 0x3e, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, + 0x3, 0x0, 0x7, 0x2f} }, + {WNI_CFG_EDCA_ETSI_ACBK, + WNI_CFG_EDCA_ETSI_ACBK_LEN, + 17, + {0x0, 0x7, 0x0, 0xf, 0x3, 0xff, 0xbb, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, + 0xf, 0x3, 0xff, 0x0} }, + {WNI_CFG_EDCA_ETSI_ACBE, + WNI_CFG_EDCA_ETSI_ACBE_LEN, + 17, + {0x0, 0x3, 0x0, 0xf, 0x3, 0xff, 0xbb, 0x0, 0xf, 0x3, 0xff, 0x0, 0x0, + 0xf, 0x3, 0xff, 0x0} }, + {WNI_CFG_EDCA_ETSI_ACVI, + WNI_CFG_EDCA_ETSI_ACVI_LEN, + 17, + {0x0, 0x2, 0x0, 0x7, 0x0, 0xf, 0x7d, 0x0, 0x7, 0x0, 0xf, 0xbc, 0x0, + 0x7, 0x0, 0xf, 0x5e} }, + {WNI_CFG_EDCA_ETSI_ACVO, + WNI_CFG_EDCA_ETSI_ACVO_LEN, + 17, + {0x0, 0x2, 0x0, 0x3, 0x0, 0x7, 0x3e, 0x0, 0x3, 0x0, 0x7, 0x66, 0x0, + 0x3, 0x0, 0x7, 0x2f} }, }; /*--------------------------------------------------------------------*/ @@ -1861,8 +1925,11 @@ process_cfg_download_req(tpAniSirGlobal pMac) if ((pMac->cfg.gCfgEntry[i].control & CFG_CTL_VALID) == 0) continue; - if (index >= pMac->cfg.gCfgMaxSBufSize) + if (index >= pMac->cfg.gCfgMaxSBufSize) { + pe_debug("No space id:%d BufSize:%d index:%d", + i, pMac->cfg.gCfgMaxSBufSize, index); continue; + } pDstTest = &pMac->cfg.gCfgSBuf[index]; pStrCfg = (cfgstatic_string*)cfg_static[i].pStrData; diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index beec2735af59..aa2663b1f879 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -59,10 +59,6 @@ typedef struct tagComebackTimerInfo { /* Maximum Number of WEP KEYS */ #define MAX_WEP_KEYS 4 -/* Maximum allowable size of a beacon frame */ -#define SCH_MAX_BEACON_SIZE 512 - -#define SCH_MAX_PROBE_RESP_SIZE 512 #define SCH_PROTECTION_RESET_TIME 4000 /*-------------------------------------------------------------------------- diff --git a/core/mac/src/pe/include/sch_api.h b/core/mac/src/pe/include/sch_api.h index 15451bcd54c4..e23b49c91a3b 100644 --- a/core/mac/src/pe/include/sch_api.h +++ b/core/mac/src/pe/include/sch_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2015,2018 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 @@ -51,6 +51,7 @@ extern void sch_qos_update_local(tpAniSirGlobal pMac, tpPESession psessionEntry) extern void sch_edca_profile_update(tpAniSirGlobal pMac, tpPESession psessionEntry); +void sch_edca_profile_update_all(tpAniSirGlobal pmac); /* / Set the fixed fields in a beacon frame */ extern tSirRetStatus sch_set_fixed_beacon_fields(tpAniSirGlobal pMac, tpPESession psessionEntry); diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index c71929ede3ac..c14be9b74fd8 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -2487,6 +2487,11 @@ QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx, return QDF_STATUS_E_FAILURE; } + if ((*local_ie_len) > (MAX_DEFAULT_SCAN_IE_LEN - EXT_CAP_IE_HDR_LEN)) { + pe_err("Invalid Scan IE length"); + return QDF_STATUS_E_FAILURE; + } + /* copy ie prior to ext cap to local buffer */ qdf_mem_copy(local_ie_buf, ie_data, (*local_ie_len)); @@ -2503,6 +2508,11 @@ QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx, pe_err("Failed %d to create ext cap IE. Use default value instead", status); local_ie_buf[*local_ie_len + 1] = DOT11F_IE_EXTCAP_MAX_LEN; + if ((*local_ie_len) > (MAX_DEFAULT_SCAN_IE_LEN - + (DOT11F_IE_EXTCAP_MAX_LEN + EXT_CAP_IE_HDR_LEN))) { + pe_err("Invalid Scan IE length"); + return QDF_STATUS_E_FAILURE; + } (*local_ie_len) += EXT_CAP_IE_HDR_LEN; qdf_mem_copy(local_ie_buf + (*local_ie_len), default_scan_ext_cap.bytes, @@ -2512,6 +2522,12 @@ QDF_STATUS lim_update_ext_cap_ie(tpAniSirGlobal mac_ctx, } lim_merge_extcap_struct(&driver_ext_cap, &default_scan_ext_cap, true); local_ie_buf[*local_ie_len + 1] = driver_ext_cap.num_bytes; + + if ((*local_ie_len) > (MAX_DEFAULT_SCAN_IE_LEN - + (EXT_CAP_IE_HDR_LEN + driver_ext_cap.num_bytes))) { + pe_err("Invalid Scan IE length"); + return QDF_STATUS_E_FAILURE; + } (*local_ie_len) += EXT_CAP_IE_HDR_LEN; qdf_mem_copy(local_ie_buf + (*local_ie_len), driver_ext_cap.bytes, driver_ext_cap.num_bytes); diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index 5b62911dc988..3df193015967 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -340,8 +340,8 @@ static inline bool is_non_rsn_cipher(uint8_t cipher_suite) * frame handling to determine whether received RSN in * Assoc/Reassoc request frames include supported cipher suites or not. * - * Return: eSIR_SUCCESS if ALL BSS basic rates are present in the - * received rateset else failure status. + * Return: eSIR_SUCCESS if ALL supported cipher suites are present in the + * received rsn IE else failure status. */ uint8_t @@ -452,8 +452,8 @@ lim_check_rx_rsn_ie_match(tpAniSirGlobal mac_ctx, tDot11fIERSN rx_rsn_ie, * frame handling to determine whether received RSN in * Assoc/Reassoc request frames include supported cipher suites or not. * - * Return: Success if ALL BSS basic rates are present in the - * received rateset else failure status. + * Return: Success if ALL supported cipher suites are present in the + * received wpa IE else failure status. */ uint8_t diff --git a/core/mac/src/pe/lim/lim_ft_preauth.c b/core/mac/src/pe/lim/lim_ft_preauth.c index c8d1f5212e08..24c98a3313b5 100644 --- a/core/mac/src/pe/lim/lim_ft_preauth.c +++ b/core/mac/src/pe/lim/lim_ft_preauth.c @@ -292,10 +292,10 @@ void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, QDF_STATUS status, lim_diag_event_report(pMac, WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, pMac->lim.pSessionEntry, eSIR_SUCCESS, eSIR_SUCCESS); #endif - - lim_send_auth_mgmt_frame(pMac, &authFrame, - psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId, - LIM_NO_WEP_IN_FC, psessionEntry); + if (psessionEntry->ftPEContext.pFTPreAuthReq) + lim_send_auth_mgmt_frame(pMac, &authFrame, + psessionEntry->ftPEContext.pFTPreAuthReq->preAuthbssId, + LIM_NO_WEP_IN_FC, psessionEntry); return; diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index eb1b8c7d1af9..a0705ba905a6 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -728,7 +728,7 @@ static void lim_print_ht_cap(tpAniSirGlobal mac_ctx, tpPESession session, * * wpa ie related checks * - * Return: true of no error, false otherwise + * Return: true if no error, false otherwise */ static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx, tpSirMacMgmtHdr hdr, @@ -737,6 +737,7 @@ static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx, uint8_t sub_type, bool *pmf_connection) { uint8_t *wps_ie = NULL; + uint32_t ret; tDot11fIEWPA dot11f_ie_wpa = {0}; tDot11fIERSN dot11f_ie_rsn = {0}; tSirRetStatus status = eSIR_SUCCESS; @@ -767,11 +768,11 @@ static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx, if (assoc_req->rsnPresent) { if (assoc_req->rsn.length) { /* Unpack the RSN IE */ - if (dot11f_unpack_ie_rsn(mac_ctx, + ret = dot11f_unpack_ie_rsn(mac_ctx, &assoc_req->rsn.info[0], assoc_req->rsn.length, - &dot11f_ie_rsn, false) != - DOT11F_PARSE_SUCCESS) { + &dot11f_ie_rsn, false); + if (!DOT11F_SUCCEEDED(ret)) { pe_err("Invalid RSN ie"); return false; } @@ -843,11 +844,11 @@ static bool lim_chk_n_process_wpa_rsn_ie(tpAniSirGlobal mac_ctx, /* Unpack the WPA IE */ if (assoc_req->wpa.length) { /* OUI is not taken care */ - if (dot11f_unpack_ie_wpa(mac_ctx, - &assoc_req->wpa.info[4], - assoc_req->wpa.length, - &dot11f_ie_wpa, false) != - DOT11F_PARSE_SUCCESS) { + ret = dot11f_unpack_ie_wpa(mac_ctx, + &assoc_req->wpa.info[4], + (assoc_req->wpa.length - 4), + &dot11f_ie_wpa, false); + if (!DOT11F_SUCCEEDED(ret)) { pe_err("Invalid WPA IE"); return false; } @@ -1841,6 +1842,11 @@ void lim_process_assoc_req_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_pkt_info, if ((session->access_policy_vendor_ie) && (session->access_policy == LIM_ACCESS_POLICY_RESPOND_IF_IE_IS_PRESENT)) { + if (frame_len <= LIM_ASSOC_REQ_IE_OFFSET) { + pe_debug("Received action frame of invalid len %d", + frame_len); + return; + } if (!cfg_get_vendor_ie_ptr_from_oui(mac_ctx, &session->access_policy_vendor_ie[2], 3, frm_body + LIM_ASSOC_REQ_IE_OFFSET, diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index 34956ae44849..f5f1597e0a6f 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -779,6 +779,7 @@ lim_fill_assoc_ind_params(tpAniSirGlobal mac_ctx, sme_assoc_ind->HTCaps = assoc_ind->HTCaps; if (assoc_ind->VHTCaps.present) sme_assoc_ind->VHTCaps = assoc_ind->VHTCaps; + sme_assoc_ind->capability_info = assoc_ind->capabilityInfo; } diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c index 686646ad51c6..5cf1f04803e0 100644 --- a/core/mac/src/pe/lim/lim_process_tdls.c +++ b/core/mac/src/pe/lim/lim_process_tdls.c @@ -2974,7 +2974,6 @@ tSirRetStatus lim_process_sme_tdls_add_sta_req(tpAniSirGlobal pMac, goto lim_tdls_add_sta_error; } - pMac->lim.gLimAddStaTdls = true; /* To start with, send add STA request to HAL */ if (eSIR_FAILURE == lim_tdls_setup_add_sta(pMac, pAddStaReq, psessionEntry)) { diff --git a/core/mac/src/pe/lim/lim_send_messages.c b/core/mac/src/pe/lim/lim_send_messages.c index ddd81924f2f3..621e55a23590 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-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 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 @@ -227,7 +227,8 @@ tSirRetStatus lim_send_switch_chnl_params(tpAniSirGlobal pMac, pChnlParams->vhtCapable = pSessionEntry->vhtCapability; pChnlParams->dot11_mode = pSessionEntry->dot11mode; pChnlParams->nss = pSessionEntry->nss; - pe_debug("nss value: %d", pChnlParams->nss); + pe_debug("nss value: %d dot11_mode %d", + pChnlParams->nss, pChnlParams->dot11_mode); /*Set DFS flag for DFS channel */ if (ch_width == CH_WIDTH_160MHZ) { 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 8a0257fb405a..d21b1b12d15f 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 @@ -2193,7 +2193,7 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) uint8_t session_id; uint16_t aid = 0; uint16_t chan_space = 0; - struct ch_params_s ch_params; + struct ch_params_s ch_params = {0}; tLimWiderBWChannelSwitchInfo *chnl_switch_info = NULL; tLimChannelSwitchInfo *lim_ch_switch = NULL; @@ -2217,6 +2217,7 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) if (!session_entry) { pe_err("Session does not exists for %pM", csa_params->bssId); + qdf_mem_free(csa_offload_ind); goto err; } @@ -2225,11 +2226,13 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) if (!sta_ds) { pe_err("sta_ds does not exist"); + qdf_mem_free(csa_offload_ind); goto err; } if (!LIM_IS_STA_ROLE(session_entry)) { pe_debug("Invalid role to handle CSA"); + qdf_mem_free(csa_offload_ind); goto err; } @@ -2406,6 +2409,7 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) (session_entry->ch_width == session_entry->gLimChannelSwitch.ch_width)) { pe_err("Ignore CSA, no change in ch and bw"); + qdf_mem_free(csa_offload_ind); goto err; } diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c index 1634560a0ba0..9f80c4ffafe6 100644 --- a/core/mac/src/pe/lim/lim_session.c +++ b/core/mac/src/pe/lim/lim_session.c @@ -480,11 +480,11 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId, if (eSIR_INFRA_AP_MODE == bssType || eSIR_IBSS_MODE == bssType) { session_ptr->pSchProbeRspTemplate = - qdf_mem_malloc(SCH_MAX_PROBE_RESP_SIZE); + qdf_mem_malloc(SIR_MAX_PROBE_RESP_SIZE); session_ptr->pSchBeaconFrameBegin = - qdf_mem_malloc(SCH_MAX_BEACON_SIZE); + qdf_mem_malloc(SIR_MAX_BEACON_SIZE); session_ptr->pSchBeaconFrameEnd = - qdf_mem_malloc(SCH_MAX_BEACON_SIZE); + qdf_mem_malloc(SIR_MAX_BEACON_SIZE); if ((NULL == session_ptr->pSchProbeRspTemplate) || (NULL == session_ptr->pSchBeaconFrameBegin) || (NULL == session_ptr->pSchBeaconFrameEnd)) { diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 19f883b4f9a6..468239a8fc89 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -5472,10 +5472,8 @@ void lim_process_add_sta_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) else if (LIM_IS_NDI_ROLE(session)) lim_ndp_add_sta_rsp(mac_ctx, session, msg->bodyptr); #ifdef FEATURE_WLAN_TDLS - else if (mac_ctx->lim.gLimAddStaTdls) { + else if (add_sta_params->staType == STA_ENTRY_TDLS_PEER) lim_process_tdls_add_sta_rsp(mac_ctx, msg->bodyptr, session); - mac_ctx->lim.gLimAddStaTdls = false; - } #endif else lim_process_mlm_add_sta_rsp(mac_ctx, msg, session); diff --git a/core/mac/src/pe/sch/sch_api.c b/core/mac/src/pe/sch/sch_api.c index 87f40199552d..e82d6d9d32a7 100644 --- a/core/mac/src/pe/sch/sch_api.c +++ b/core/mac/src/pe/sch/sch_api.c @@ -240,7 +240,15 @@ tSirRetStatus sch_send_beacon_req(tpAniSirGlobal pMac, uint8_t *beaconPayload, pe_err("TimIeOffset:[%d]", beaconParams->TimIeOffset); #endif - beaconParams->beacon = beaconPayload; + if (size >= SIR_MAX_BEACON_SIZE) { + pe_err("beacon size (%d) exceed host limit %d", + size, SIR_MAX_BEACON_SIZE); + QDF_ASSERT(0); + qdf_mem_free(beaconParams); + return eSIR_FAILURE; + } + qdf_mem_copy(beaconParams->beacon, beaconPayload, size); + beaconParams->beaconLength = (uint32_t) size; msgQ.bodyptr = beaconParams; msgQ.bodyval = 0; @@ -418,7 +426,7 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac, nBytes += nPayload + sizeof(tSirMacMgmtHdr); /* Make sure we are not exceeding allocated len */ - if (nBytes > SCH_MAX_PROBE_RESP_SIZE) { + if (nBytes > SIR_MAX_PROBE_RESP_SIZE) { pe_err("nBytes %d greater than max size", nBytes); qdf_mem_free(addIE); return eSIR_FAILURE; @@ -466,7 +474,8 @@ uint32_t lim_send_probe_rsp_template_to_hal(tpAniSirGlobal pMac, pe_err("malloc failed for bytes %d", nBytes); } else { sir_copy_mac_addr(pprobeRespParams->bssId, psessionEntry->bssId); - pprobeRespParams->pProbeRespTemplate = pFrame2Hal; + qdf_mem_copy(pprobeRespParams->probeRespTemplate, + pFrame2Hal, nBytes); pprobeRespParams->probeRespTemplateLen = nBytes; qdf_mem_copy(pprobeRespParams->ucProxyProbeReqValidIEBmap, IeBitmap, (sizeof(uint32_t) * 8)); diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c index dbdabeb606ee..4d96187c839d 100644 --- a/core/mac/src/pe/sch/sch_beacon_gen.c +++ b/core/mac/src/pe/sch/sch_beacon_gen.c @@ -321,7 +321,7 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) } n_status = dot11f_pack_beacon1(mac_ctx, bcn_1, ptr, - SCH_MAX_BEACON_SIZE - offset, &n_bytes); + SIR_MAX_BEACON_SIZE - offset, &n_bytes); if (DOT11F_FAILED(n_status)) { pe_err("Failed to packed a tDot11fBeacon1 (0x%08x)", n_status); @@ -446,9 +446,6 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) /* populate_dot11f_vht_ext_bss_load( mac_ctx, &bcn2.VHTExtBssLoad); */ - if (session->gLimOperatingMode.present) - populate_dot11f_operating_mode(mac_ctx, - &bcn_2->OperatingMode, session); } if (session->limSystemRole != eLIM_STA_IN_IBSS_ROLE) populate_dot11f_ext_cap(mac_ctx, is_vht_enabled, &bcn_2->ExtCap, @@ -561,9 +558,17 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) } + if (session->vhtCapability && session->gLimOperatingMode.present) { + populate_dot11f_operating_mode(mac_ctx, &bcn_2->OperatingMode, + session); + lim_strip_ie(mac_ctx, addn_ie, &addn_ielen, + SIR_MAC_VHT_OPMODE_EID, ONE_BYTE, NULL, 0, + NULL, SIR_MAC_VHT_OPMODE_SIZE - 2); + } + n_status = dot11f_pack_beacon2(mac_ctx, bcn_2, session->pSchBeaconFrameEnd, - SCH_MAX_BEACON_SIZE, &n_bytes); + SIR_MAX_BEACON_SIZE, &n_bytes); if (DOT11F_FAILED(n_status)) { pe_err("Failed to packed a tDot11fBeacon2 (0x%08x)", n_status); @@ -603,8 +608,9 @@ sch_set_fixed_beacon_fields(tpAniSirGlobal mac_ctx, tpPESession session) /* TODO: Append additional IE here. */ if (addn_ielen > 0) sch_append_addn_ie(mac_ctx, session, - session->pSchBeaconFrameEnd + n_bytes, - SCH_MAX_BEACON_SIZE, &n_bytes, addn_ie, addn_ielen); + session->pSchBeaconFrameEnd + n_bytes, + SIR_MAX_BEACON_SIZE, &n_bytes, + addn_ie, addn_ielen); session->schBeaconOffsetEnd = (uint16_t) n_bytes; extra_ie_len = n_bytes - extra_ie_offset; diff --git a/core/mac/src/pe/sch/sch_message.c b/core/mac/src/pe/sch/sch_message.c index 944bb1ba534f..51569c03848f 100644 --- a/core/mac/src/pe/sch/sch_message.c +++ b/core/mac/src/pe/sch/sch_message.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -76,6 +76,26 @@ void sch_set_beacon_interval(tpAniSirGlobal pMac, tpPESession psessionEntry) pMac->sch.schObject.gSchBeaconInterval = (uint16_t) bi; } +/** + * sch_edca_profile_update_all() - update EDCA profile + * @pmac: tpAniSirGlobal + * + * update EDCA parameter for APs when country code changed. + * + * return None + */ +void sch_edca_profile_update_all(tpAniSirGlobal pmac) +{ + uint32_t i; + tpPESession psession_entry; + + for (i = 0; i < pmac->lim.maxBssId; i++) { + psession_entry = &pmac->lim.gpSession[i]; + if (psession_entry->valid) + sch_edca_profile_update(pmac, psession_entry); + } +} + /* -------------------------------------------------------------------- */ /** * sch_process_message @@ -197,19 +217,33 @@ sch_get_params(tpAniSirGlobal pMac, uint32_t val; uint32_t i, idx; uint32_t *prf; - + uint8_t country_code_str[WNI_CFG_COUNTRY_CODE_LEN]; + uint32_t country_code_len = WNI_CFG_COUNTRY_CODE_LEN; uint32_t ani_l[] = { WNI_CFG_EDCA_ANI_ACBE_LOCAL, WNI_CFG_EDCA_ANI_ACBK_LOCAL, WNI_CFG_EDCA_ANI_ACVI_LOCAL, WNI_CFG_EDCA_ANI_ACVO_LOCAL}; uint32_t wme_l[] = { WNI_CFG_EDCA_WME_ACBE_LOCAL, WNI_CFG_EDCA_WME_ACBK_LOCAL, WNI_CFG_EDCA_WME_ACVI_LOCAL, WNI_CFG_EDCA_WME_ACVO_LOCAL}; + uint32_t etsi_l[] = {WNI_CFG_EDCA_ETSI_ACBE_LOCAL, + WNI_CFG_EDCA_ETSI_ACBK_LOCAL, + WNI_CFG_EDCA_ETSI_ACVI_LOCAL, + WNI_CFG_EDCA_ETSI_ACVO_LOCAL}; uint32_t ani_b[] = { WNI_CFG_EDCA_ANI_ACBE, WNI_CFG_EDCA_ANI_ACBK, WNI_CFG_EDCA_ANI_ACVI, WNI_CFG_EDCA_ANI_ACVO}; uint32_t wme_b[] = { WNI_CFG_EDCA_WME_ACBE, WNI_CFG_EDCA_WME_ACBK, WNI_CFG_EDCA_WME_ACVI, WNI_CFG_EDCA_WME_ACVO}; - - if (wlan_cfg_get_int(pMac, WNI_CFG_EDCA_PROFILE, &val) != eSIR_SUCCESS) { + uint32_t etsi_b[] = {WNI_CFG_EDCA_ETSI_ACBE, WNI_CFG_EDCA_ETSI_ACBK, + WNI_CFG_EDCA_ETSI_ACVI, WNI_CFG_EDCA_ETSI_ACVO}; + + if (wlan_cfg_get_str(pMac, WNI_CFG_COUNTRY_CODE, country_code_str, + &country_code_len) == eSIR_SUCCESS && + cds_is_etsi_europe_country(country_code_str)) { + val = WNI_CFG_EDCA_PROFILE_ETSI_EUROPE; + pe_debug("switch to ETSI EUROPE profile country code %c%c", + country_code_str[0], country_code_str[1]); + } else if (wlan_cfg_get_int(pMac, WNI_CFG_EDCA_PROFILE, &val) != + eSIR_SUCCESS) { pe_err("failed to cfg get EDCA_PROFILE id %d", WNI_CFG_EDCA_PROFILE); return eSIR_FAILURE; @@ -229,6 +263,9 @@ sch_get_params(tpAniSirGlobal pMac, case WNI_CFG_EDCA_PROFILE_WMM: prf = &wme_l[0]; break; + case WNI_CFG_EDCA_PROFILE_ETSI_EUROPE: + prf = &etsi_l[0]; + break; case WNI_CFG_EDCA_PROFILE_ANI: default: prf = &ani_l[0]; @@ -239,6 +276,9 @@ sch_get_params(tpAniSirGlobal pMac, case WNI_CFG_EDCA_PROFILE_WMM: prf = &wme_b[0]; break; + case WNI_CFG_EDCA_PROFILE_ETSI_EUROPE: + prf = &etsi_b[0]; + break; case WNI_CFG_EDCA_PROFILE_ANI: default: prf = &ani_b[0]; diff --git a/core/mac/src/sys/common/src/wlan_qct_sys.c b/core/mac/src/sys/common/src/wlan_qct_sys.c index daeed0ee6dd6..d870adc7b0cd 100644 --- a/core/mac/src/sys/common/src/wlan_qct_sys.c +++ b/core/mac/src/sys/common/src/wlan_qct_sys.c @@ -212,13 +212,7 @@ QDF_STATUS sys_mc_process_msg(v_CONTEXT_t p_cds_context, cds_msg_t *pMsg) break; } mac_ctx = PMAC_STRUCT(hHal); - if (NULL == mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SYS, - QDF_TRACE_LEVEL_ERROR, - FL("Invalid mac context")); - qdf_mem_free(pMsg->bodyptr); - break; - } + if (NULL == mac_ctx->ftm_msg_processor_callback) { QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_ERROR, diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 19015541b19d..622dbbd00f8b 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -4626,7 +4626,7 @@ sir_convert_addts_req2_struct(tpAniSirGlobal pMac, if (addts.num_WMMTCLAS) { j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS); - if (SIR_MAC_TCLASIE_MAXNUM > j) + if (SIR_MAC_TCLASIE_MAXNUM < j) j = SIR_MAC_TCLASIE_MAXNUM; for (i = pAddTs->numTclas; i < j; ++i) { @@ -4786,7 +4786,7 @@ sir_convert_addts_rsp2_struct(tpAniSirGlobal pMac, if (addts.num_WMMTCLAS) { j = (uint8_t) (pAddTs->numTclas + addts.num_WMMTCLAS); - if (SIR_MAC_TCLASIE_MAXNUM > j) + if (SIR_MAC_TCLASIE_MAXNUM < j) j = SIR_MAC_TCLASIE_MAXNUM; for (i = pAddTs->numTclas; i < j; ++i) { diff --git a/core/sap/dfs/src/dfs_process_radarevent.c b/core/sap/dfs/src/dfs_process_radarevent.c index 56bb9612e237..34cf9921a9d7 100644 --- a/core/sap/dfs/src/dfs_process_radarevent.c +++ b/core/sap/dfs/src/dfs_process_radarevent.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2002-2018 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 @@ -618,30 +618,6 @@ int dfs_process_radarevent(struct ath_dfs *dfs, found = 0; /* - * Use this fix only when device is not in test mode, as - * it drops some valid phyerrors. - * In FCC or JAPAN domain,if the follwing signature matches - * its likely that this is a false radar pulse pattern - * so process the next pulse in the queue. - */ - if ((dfs->disable_dfs_ch_switch == false) && - (DFS_FCC_REGION == dfs->dfsdomain || - DFS_MKK_REGION == dfs->dfsdomain) && - (re.re_dur >= 11 && re.re_dur <= 20) && - (diff_ts > 500 || diff_ts <= 305) && - (re.sidx == -4)) { - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "\n%s: Rejecting on Peak Index = %d,re.re_dur = %d,diff_ts = %d\n", - __func__, re.sidx, re.re_dur, diff_ts); - - ATH_DFSQ_LOCK(dfs); - empty = STAILQ_EMPTY(&(dfs->dfs_radarq)); - ATH_DFSQ_UNLOCK(dfs); - continue; - } - - /* * Modifying the pulse duration for FCC Type 4 * or JAPAN W56 Type 6 radar pulses when the * following condition is reported in radar diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 23ea7b3e0ef6..cf97b0aa02ed 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -286,6 +286,7 @@ typedef struct sap_StationAssocReassocCompleteEvent_s { uint8_t tx_mcs_map; tDot11fIEHTCaps ht_caps; tDot11fIEVHTCaps vht_caps; + tSirMacCapabilityInfo capability_info; } tSap_StationAssocReassocCompleteEvent; typedef struct sap_StationDisassocCompleteEvent_s { @@ -298,6 +299,7 @@ typedef struct sap_StationDisassocCompleteEvent_s { int rssi; int tx_rate; int rx_rate; + uint32_t rx_mc_bc_cnt; } tSap_StationDisassocCompleteEvent; typedef struct sap_StationSetKeyCompleteEvent_s { diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c index 4bc0477f7581..4e3e9fe68fe3 100644 --- a/core/sap/src/sap_api_link_cntl.c +++ b/core/sap/src/sap_api_link_cntl.c @@ -155,16 +155,6 @@ QDF_STATUS wlansap_scan_callback(tHalHandle hal_handle, __func__, scan_id); #endif operChannel = sap_select_channel(hal_handle, sap_ctx, result); - if (!operChannel) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "No channel was selected from preferred channel for Operating channel"); - - operChannel = sap_ctx->acs_cfg->start_ch; - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "Selecting operating channel as starting channel from preferred channel list: %d", - operChannel); - } sme_scan_result_purge(hal_handle, result); break; @@ -364,16 +354,6 @@ wlansap_pre_start_bss_acs_scan_callback(tHalHandle hal_handle, void *pcontext, } #endif oper_channel = sap_select_channel(hal_handle, sap_ctx, presult); - if (!oper_channel) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "No channel was selected from preferred channel for Operating channel"); - - oper_channel = sap_ctx->acs_cfg->start_ch; - - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "Selecting operating channel as starting channel from preferred channel list: %d", - oper_channel); - } sme_scan_result_purge(hal_handle, presult); } @@ -1029,6 +1009,14 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_MED, FL("sapdfs: Indicate eSAP_DFS_RADAR_DETECT to HDD")); + + if (!csr_roam_info) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid CSR Roam Info")); + wlansap_context_put(sap_ctx); + return -QDF_STATUS_E_INVAL; + } + sap_signal_hdd_event(sap_ctx, NULL, eSAP_DFS_RADAR_DETECT, (void *) eSAP_STATUS_SUCCESS); /* sync to latest DFS-NOL */ @@ -1104,13 +1092,23 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId, switch (roam_result) { case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_IND: - wlansap_roam_process_infra_assoc_ind(sap_ctx, roam_result, - csr_roam_info, &qdf_ret_status); + if (csr_roam_info) + wlansap_roam_process_infra_assoc_ind(sap_ctx, + roam_result, csr_roam_info, + &qdf_ret_status); break; case eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, FL("CSR roam_result = eCSR_ROAM_RESULT_INFRA_ASSOCIATION_CNF (%d)"), roam_result); + + if (!csr_roam_info) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid CSR Roam Info")); + qdf_ret_status = QDF_STATUS_E_INVAL; + break; + } + sap_ctx->nStaWPARSnReqIeLength = csr_roam_info->rsnIELen; if (sap_ctx->nStaWPARSnReqIeLength) qdf_mem_copy(sap_ctx->pStaWpaRsnReqIE, @@ -1198,6 +1196,14 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, FL("CSR roam_result = eCSR_ROAM_RESULT_INFRA_STARTED (%d)"), roam_result); + + if (!csr_roam_info) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + FL("Invalid CSR Roam Info")); + qdf_ret_status = QDF_STATUS_E_INVAL; + break; + } + /* * In the current implementation, hostapd is not aware that * drive will support DFS. Hence, driver should inform diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c index ef4ad35b393e..ad0af578e4a4 100644 --- a/core/sap/src/sap_ch_select.c +++ b/core/sap/src/sap_ch_select.c @@ -1572,6 +1572,8 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, int8_t rssi = 0; uint8_t chn_num = 0; uint8_t channel_id = 0; + uint8_t i; + bool found = false; tCsrScanResultInfo *pScanResult; tSapSpectChInfo *pSpectCh = pSpectInfoParams->pSpectCh; @@ -1635,15 +1637,31 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, chn_num++) { /* - * if the Beacon has channel ID, use it other wise we will - * rely on the channelIdSelf + * If the Beacon has channel ID, use it other wise we + * will rely on the channelIdSelf */ if (pScanResult->BssDescriptor.channelId == 0) channel_id = - pScanResult->BssDescriptor.channelIdSelf; + pScanResult->BssDescriptor.channelIdSelf; else channel_id = - pScanResult->BssDescriptor.channelId; + pScanResult->BssDescriptor.channelId; + + /* + * Check if channel is present in scan channel list or + * not. If not present, then continue as no need to + * process the beacon on this channel. + */ + for (i = 0; i < sap_ctx->num_of_channel; i++) { + if (channel_id == + sap_ctx->channelList[i]) { + found = true; + break; + } + } + + if (!found) + continue; if (pSpectCh && (channel_id == pSpectCh->chNum)) { if (pSpectCh->rssiAgr < diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 0e3926128777..db481a1fa65b 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -769,7 +769,7 @@ static QDF_STATUS sap_get_channel_list(ptSapContext sapContext, #endif /*========================================================================== - FUNCTION sap_get_5ghz_channel_list + FUNCTION sap_get_24ghz_5ghz_channel_list DESCRIPTION Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] available @@ -788,7 +788,7 @@ static QDF_STATUS sap_get_channel_list(ptSapContext sapContext, SIDE EFFECTS ============================================================================*/ -static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext); +static QDF_STATUS sap_get_24ghz_5ghz_channel_list(ptSapContext sapContext); /*========================================================================== FUNCTION sapStopDfsCacTimer @@ -1183,11 +1183,6 @@ bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID) tpAniSirGlobal pMac; pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("invalid pMac")); - return false; - } /* * Check for JAPAN W53 Channel operation capability @@ -1218,14 +1213,8 @@ bool sap_dfs_is_w53_invalid(tHalHandle hHal, uint8_t channelID) */ bool sap_dfs_is_channel_in_preferred_location(tHalHandle hHal, uint8_t channelID) { - tpAniSirGlobal pMac; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); - pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("invalid pMac")); - return true; - } if ((SAP_CHAN_PREFERRED_INDOOR == pMac->sap.SapDfsInfo.sap_operating_chan_preferred_location) && (true == IS_CHAN_JAPAN_OUTDOOR(channelID))) { @@ -1338,11 +1327,6 @@ static uint8_t sap_apply_rules(ptSapContext sap_ctx) } mac_ctx = PMAC_STRUCT(hal); - if (NULL == mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("mac_ctx pointer NULL")); - return 0; - } preferred_location = mac_ctx->sap.SapDfsInfo.sap_operating_chan_preferred_location; @@ -1691,11 +1675,6 @@ static uint8_t sap_random_channel_sel(ptSapContext sap_ctx) } mac_ctx = PMAC_STRUCT(hal); - if (NULL == mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("invalid mac_ctx")); - return 0; - } /* * Retrieve the original one and store it. @@ -1709,9 +1688,9 @@ static uint8_t sap_random_channel_sel(ptSapContext sap_ctx) ch_wd = mac_ctx->sap.SapDfsInfo.orig_chanWidth; } - if (sap_get_5ghz_channel_list(sap_ctx)) { + if (sap_get_24ghz_5ghz_channel_list(sap_ctx)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, - FL("Getting 5Ghz channel list failed")); + FL("Getting 2.4Ghz/5Ghz channel list failed")); return 0; } @@ -1837,12 +1816,11 @@ static void sap_mark_dfs_channels(ptSapContext sapContext, uint8_t *channels, int i, j; tSapDfsNolInfo *psapDfsChannelNolList = NULL; uint8_t nRegDomainDfsChannels; - tHalHandle hHal; + tHalHandle hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); tpAniSirGlobal pMac; uint64_t time_elapsed_since_last_radar; uint64_t time_when_radar_found; - hHal = CDS_GET_HAL_CB(sapContext->p_cds_gctx); if (NULL == channels) return; if (NULL == hHal) { @@ -1851,11 +1829,6 @@ static void sap_mark_dfs_channels(ptSapContext sapContext, uint8_t *channels, return; } pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("invalid pMac")); - return; - } /* * Mark the current channel on which Radar is found @@ -2312,11 +2285,6 @@ QDF_STATUS sap_goto_channel_sel(ptSapContext sap_context, } mac_ctx = PMAC_STRUCT(h_hal); - if (NULL == mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid MAC context")); - return QDF_STATUS_E_FAILURE; - } if (cds_concurrent_beaconing_sessions_running()) { con_ch = @@ -2938,11 +2906,6 @@ QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx, return QDF_STATUS_E_FAILURE; } mac_ctx = PMAC_STRUCT(hal); - if (NULL == mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid MAC context")); - return QDF_STATUS_E_FAILURE; - } if (sap_hddevent != eSAP_UPDATE_SCAN_RESULT) QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, @@ -3111,6 +3074,8 @@ QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx, reassoc_complete->ht_caps = csr_roaminfo->ht_caps; if (csr_roaminfo->vht_caps.present) reassoc_complete->vht_caps = csr_roaminfo->vht_caps; + reassoc_complete->capability_info = + csr_roaminfo->capability_info; break; @@ -3138,6 +3103,7 @@ QDF_STATUS sap_signal_hdd_event(ptSapContext sap_ctx, disassoc_comp->rssi = csr_roaminfo->rssi; disassoc_comp->rx_rate = csr_roaminfo->rx_rate; disassoc_comp->tx_rate = csr_roaminfo->tx_rate; + disassoc_comp->rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt; disassoc_comp->reason_code = csr_roaminfo->disassoc_reason; break; @@ -4414,11 +4380,6 @@ QDF_STATUS sap_fsm(ptSapContext sap_ctx, ptWLAN_SAPEvent sap_event) } mac_ctx = PMAC_STRUCT(hal); - if (NULL == mac_ctx) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("Invalid MAC context")); - return QDF_STATUS_E_FAILURE; - } QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, FL("sap_ctx=%pK, state_var=%d, msg=0x%x"), @@ -4879,7 +4840,7 @@ static QDF_STATUS sap_get_channel_list(ptSapContext sap_ctx, #ifdef FEATURE_WLAN_CH_AVOID uint8_t i; #endif - tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + tpAniSirGlobal mac_ctx; tSapChSelSpectInfo spect_info_obj = { NULL, 0 }; uint16_t ch_width; @@ -4891,6 +4852,7 @@ static QDF_STATUS sap_get_channel_list(ptSapContext sap_ctx, return QDF_STATUS_E_FAULT; } + mac_ctx = PMAC_STRUCT(hal); start_ch_num = sap_ctx->acs_cfg->start_ch; end_ch_num = sap_ctx->acs_cfg->end_ch; ch_width = sap_ctx->acs_cfg->ch_width; @@ -5083,7 +5045,7 @@ static QDF_STATUS sap_get_channel_list(ptSapContext sap_ctx, * Function for initializing list of 2.4/5 Ghz [NON-DFS/DFS] * available channels in the current regulatory domain. */ -static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext) +static QDF_STATUS sap_get_24ghz_5ghz_channel_list(ptSapContext sapContext) { uint8_t count = 0; int i; @@ -5125,7 +5087,8 @@ static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext) "Get PCL failed"); return status; } - for (i = 0; i <= pcl.pcl_len; i++) { + + for (i = 0; i < pcl.pcl_len; i++) { if (CDS_IS_CHANNEL_5GHZ(pcl.pcl_list[i])) { ch_state = cds_get_channel_state(pcl.pcl_list[i]); if (!(ch_state == CHANNEL_STATE_ENABLE || @@ -5142,6 +5105,43 @@ static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext) } } + if (!count) { + for (i = 0; i < pcl.pcl_len; i++) { + if (CDS_IS_CHANNEL_24GHZ(pcl.pcl_list[i])) { + ch_state = cds_get_channel_state( + pcl.pcl_list[i]); + if (ch_state != CHANNEL_STATE_ENABLE) + continue; + sapContext->SapAllChnlList.channelList[count]. + channel = pcl.pcl_list[i]; + QDF_TRACE(QDF_MODULE_ID_SAP, + QDF_TRACE_LEVEL_INFO_LOW, + "%s[%d] CHANNEL = %d", + __func__, __LINE__, pcl.pcl_list[i]); + sapContext->SapAllChnlList.channelList[count]. + valid = true; + count++; + } + } + } + + if (!count) { + for (i = 0; i < sapContext->acs_cfg->ch_list_count; i++) { + ch_state = cds_get_channel_state( + sapContext->acs_cfg->ch_list[i]); + if (ch_state != CHANNEL_STATE_ENABLE) + continue; + sapContext->SapAllChnlList.channelList[count].channel = + sapContext->acs_cfg->ch_list[i]; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, + "%s[%d] CHANNEL = %d", __func__, __LINE__, + sapContext->acs_cfg->ch_list[i]); + sapContext->SapAllChnlList.channelList[count].valid = + true; + count++; + } + } + sapContext->SapAllChnlList.numChannel = count; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_LOW, "%s[%d] NUMBER OF CHANNELS count = %d" diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 2f437148a32f..f9a96875e283 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -854,7 +854,7 @@ QDF_STATUS wlansap_start_bss(void *pCtx, /* pwextCtx */ pSapCtx->is_chan_change_inprogress = false; pSapCtx->stop_bss_in_progress = false; /* Set the BSSID to your "self MAC Addr" read the mac address - from Configuation ITEM received from HDD */ + from configuration ITEM received from HDD */ pSapCtx->csr_roamProfile.BSSIDs.numOfBSSIDs = 1; qdf_mem_copy(pSapCtx->csr_roamProfile.BSSIDs.bssid, pSapCtx->self_mac_addr, sizeof(struct qdf_mac_addr)); @@ -878,7 +878,7 @@ QDF_STATUS wlansap_start_bss(void *pCtx, /* pwextCtx */ } else { /* If concurrent session is running that is already associated * then we just follow that sessions country info (whether - * present or not doesn't maater as we have to follow whatever + * present or not doesn't matter as we have to follow whatever * STA session does) */ if ((0 == sme_get_concurrent_operation_channel(hHal)) && pConfig->ieee80211d) { @@ -889,13 +889,6 @@ QDF_STATUS wlansap_start_bss(void *pCtx, /* pwextCtx */ } pmac = PMAC_STRUCT(hHal); - if (NULL == pmac) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, - "%s: Invalid MAC context from p_cds_gctx", - __func__); - qdf_status = QDF_STATUS_E_FAULT; - goto fail; - } /* * Copy the DFS Test Mode setting to pmac for * access in lower layers @@ -2698,6 +2691,21 @@ wlansap_channel_change_request(void *pSapCtx, uint8_t target_channel) mac_ctx = PMAC_STRUCT(hHal); phy_mode = sapContext->csr_roamProfile.phyMode; + /* Update phy_mode if the target channel is in the other band */ + if (CDS_IS_CHANNEL_5GHZ(target_channel) && + ((phy_mode == eCSR_DOT11_MODE_11g) || + (phy_mode == eCSR_DOT11_MODE_11g_ONLY))) + phy_mode = eCSR_DOT11_MODE_11a; + else if (CDS_IS_CHANNEL_24GHZ(target_channel) && + (phy_mode == eCSR_DOT11_MODE_11a)) + phy_mode = eCSR_DOT11_MODE_11g; + + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, + "%s: phy_mode: %d, target_channel: %d new phy_mode: %d", + __func__, sapContext->csr_roamProfile.phyMode, + target_channel, phy_mode); + sapContext->csr_roamProfile.phyMode = phy_mode; + if (sapContext->csr_roamProfile.ChannelInfo.numOfChannels == 0 || sapContext->csr_roamProfile.ChannelInfo.ChannelList == NULL) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, @@ -2729,8 +2737,8 @@ wlansap_channel_change_request(void *pSapCtx, uint8_t target_channel) ch_params, &sapContext->csr_roamProfile); QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - "%s: chan:%d width:%d offset:%d seg0:%d seg1:%d", - __func__, sapContext->channel, ch_params->ch_width, + "%s: chan:%d phy_mode %d width:%d offset:%d seg0:%d seg1:%d", + __func__, sapContext->channel, phy_mode, ch_params->ch_width, ch_params->sec_ch_offset, ch_params->center_freq_seg0, ch_params->center_freq_seg1); @@ -3031,12 +3039,12 @@ wlan_sap_set_channel_avoidance(tHalHandle hal, bool sap_channel_avoidance) { tpAniSirGlobal mac_ctx = NULL; - if (NULL != hal) + if (NULL != hal) { mac_ctx = PMAC_STRUCT(hal); - if (mac_ctx == NULL || hal == NULL) { + } else { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("hal or mac_ctx pointer NULL")); + FL("hal pointer NULL")); return QDF_STATUS_E_FAULT; } mac_ctx->sap.sap_channel_avoidance = sap_channel_avoidance; diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 09804ac7e941..f1439dc7f3ad 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -1578,6 +1578,8 @@ typedef struct tagCsrRoamInfo { int rssi; int tx_rate; int rx_rate; + tSirMacCapabilityInfo capability_info; + uint32_t rx_mc_bc_cnt; } tCsrRoamInfo; typedef struct tagCsrFreqScanInfo { @@ -1621,6 +1623,7 @@ typedef struct sSirSmeAssocIndToUpperLayerCnf { tDot11fIEHTCaps HTCaps; tDot11fIEVHTCaps VHTCaps; + tSirMacCapabilityInfo capability_info; } tSirSmeAssocIndToUpperLayerCnf, *tpSirSmeAssocIndToUpperLayerCnf; typedef struct tagCsrSummaryStatsInfo { diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 5c580a106734..3a71ec424921 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -421,6 +421,7 @@ QDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId, uint32_t numItems, bool update_entire_cache); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * sme_get_pmk_info(): A wrapper function to request CSR to save PMK * @hal: Global structure @@ -432,7 +433,6 @@ QDF_STATUS sme_roam_set_pmkid_cache(tHalHandle hHal, uint8_t sessionId, void sme_get_pmk_info(tHalHandle hal, uint8_t session_id, tPmkidCacheInfo *pmk_cache); -#ifdef WLAN_FEATURE_ROAM_OFFLOAD QDF_STATUS sme_roam_set_psk_pmk(tHalHandle hHal, uint8_t sessionId, uint8_t *pPSK_PMK, size_t pmk_len); #endif @@ -1060,10 +1060,12 @@ QDF_STATUS sme_ll_stats_clear_req(tHalHandle hHal, QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq *psetStatsReq); QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, - tSirLLStatsGetReq *pgetStatsReq); + tSirLLStatsGetReq *pgetStatsReq, + void *context); QDF_STATUS sme_set_link_layer_stats_ind_cb(tHalHandle hHal, void (*callbackRoutine)(void *callbackCtx, - int indType, void *pRsp)); + int indType, void *pRsp, + void *cookie)); QDF_STATUS sme_set_link_layer_ext_cb(tHalHandle hal, void (*ll_stats_ext_cb)(tHddHandle callback_ctx, tSirLLStatsResults * rsp)); @@ -1594,15 +1596,16 @@ QDF_STATUS sme_update_fils_setting(tHalHandle hal, uint8_t session_id, * * @hal - MAC global handle * @callback_routine - callback routine from HDD + * @context - callback context * * This API is invoked by HDD to register its callback in SME * * Return: QDF_STATUS */ QDF_STATUS sme_encrypt_decrypt_msg_register_callback(tHalHandle hal, - void (*encrypt_decrypt_cb)(void *hdd_context, - struct sir_encrypt_decrypt_rsp_params - *encrypt_decrypt_rsp_params)); + void (*encrypt_decrypt_cb)(void *cookie, + struct sir_encrypt_decrypt_rsp_params + *encrypt_decrypt_rsp_params)); /** * sme_encrypt_decrypt_msg_deregister_callback() - Registers @@ -1625,7 +1628,8 @@ QDF_STATUS sme_encrypt_decrypt_msg_deregister_callback(tHalHandle h_hal); * Return: QDF_STATUS enumeration. */ QDF_STATUS sme_encrypt_decrypt_msg(tHalHandle hal, - struct encrypt_decrypt_req_params *encrypt_decrypt_params); + struct encrypt_decrypt_req_params *encrypt_decrypt_params, + void *context); #endif /** @@ -1910,11 +1914,26 @@ QDF_STATUS sme_get_chain_rssi(tHalHandle phal, * sme_chain_rssi_register_callback - chain rssi callback * @phal: global hal handle * @pchain_rssi_ind_cb: callback function pointer + * @context: callback context * * Return: QDF_STATUS enumeration. */ -QDF_STATUS sme_chain_rssi_register_callback(tHalHandle phal, - void (*pchain_rssi_ind_cb)(void *ctx, void *pmsg)); +QDF_STATUS +sme_chain_rssi_register_callback(tHalHandle phal, + void (*pchain_rssi_ind_cb)(void *ctx, + void *pmsg, + void *context), + void *context); + +/** + * sme_chain_rssi_deregister_callback() - De-register chain rssi callback + * @hal: global hal handle + * + * This function De-registers the scandone callback to SME + * + * Return: None + */ +void sme_chain_rssi_deregister_callback(tHalHandle hal); /** * sme_process_msg_callback() - process callback message from LIM diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 3c88d387cdee..6bc5a58b6252 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -182,8 +182,9 @@ typedef struct tagSmeStruct { void (*pChAvoidNotificationCb)(void *hdd_context, void *indi_param); #endif /* FEATURE_WLAN_CH_AVOID */ #ifdef WLAN_FEATURE_LINK_LAYER_STATS + void *ll_stats_context; void (*pLinkLayerStatsIndCallback)(void *callbackContext, - int indType, void *pRsp); + int indType, void *pRsp, void *context); void (*link_layer_stats_ext_cb)(tHddHandle callback_ctx, tSirLLStatsResults *rsp); #endif /* WLAN_FEATURE_LINK_LAYER_STATS */ @@ -259,8 +260,9 @@ typedef struct tagSmeStruct { p2p_lo_callback p2p_lo_event_callback; void *p2p_lo_event_context; sme_send_oem_data_rsp_msg oem_data_rsp_callback; - void (*encrypt_decrypt_cb)(void *, - struct sir_encrypt_decrypt_rsp_params *); + void *encrypt_decrypt_context; + void (*encrypt_decrypt_cb)(void *cookie, + struct sir_encrypt_decrypt_rsp_params *rsp); void (*lost_link_info_cb)(void *context, struct sir_lost_link_info *lost_link_info); void (*rso_cmd_status_cb)(void *hdd_context, @@ -270,7 +272,8 @@ typedef struct tagSmeStruct { void (*bt_activity_info_cb)(void *context, uint32_t bt_activity); void (*chip_power_save_fail_cb)(void *, struct chip_pwr_save_fail_detected_params *); - void (*pchain_rssi_ind_cb)(void *ctx, void *pmsg); + void *pchain_rssi_ind_ctx; + void (*pchain_rssi_ind_cb)(void *hdd_ctx, void *pmsg, void *context); void (*spectral_scan_cb)(void *context, struct spectral_samp_msg *samp_msg); void (*stats_ext2_cb)(void *, struct stats_ext2_event *); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 90a656c91498..f834505780cb 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1563,24 +1563,17 @@ QDF_STATUS sme_update_roam_params(tHalHandle hal, } #ifdef WLAN_FEATURE_GTK_OFFLOAD -static void sme_process_get_gtk_info_rsp(tHalHandle hHal, +static void sme_process_get_gtk_info_rsp(tpAniSirGlobal mac_ctx, tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp) { - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); - - if (NULL == pMac) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL, - "%s: pMac is null", __func__); - return; - } - if (pMac->sme.gtk_offload_get_info_cb == NULL) { + if (mac_ctx->sme.gtk_offload_get_info_cb == NULL) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: HDD callback is null", __func__); return; } - pMac->sme.gtk_offload_get_info_cb( - pMac->sme.gtk_offload_get_info_cb_context, + mac_ctx->sme.gtk_offload_get_info_cb( + mac_ctx->sme.gtk_offload_get_info_cb_context, pGtkOffloadGetInfoRsp); } #endif @@ -2308,25 +2301,19 @@ QDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal, #endif /* FEATURE_WLAN_ESE */ static -QDF_STATUS sme_ibss_peer_info_response_handler(tHalHandle hHal, +QDF_STATUS sme_ibss_peer_info_response_handler(tpAniSirGlobal mac_ctx, tpSirIbssGetPeerInfoRspParams pIbssPeerInfoParams) { - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL, - "%s: pMac is null", __func__); - return QDF_STATUS_E_FAILURE; - } - if (pMac->sme.peerInfoParams.peerInfoCbk == NULL) { + if (mac_ctx->sme.peerInfoParams.peerInfoCbk == NULL) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, "%s: HDD callback is null", __func__); return QDF_STATUS_E_FAILURE; } - pMac->sme.peerInfoParams.peerInfoCbk(pMac->sme.peerInfoParams.pUserData, - &pIbssPeerInfoParams-> - ibssPeerInfoRspParams); + mac_ctx->sme.peerInfoParams.peerInfoCbk( + mac_ctx->sme.peerInfoParams.pUserData, + &pIbssPeerInfoParams->ibssPeerInfoRspParams); return QDF_STATUS_SUCCESS; } @@ -2411,6 +2398,7 @@ static QDF_STATUS sme_process_antenna_mode_resp(tpAniSirGlobal mac, tListElem *entry; tSmeCmd *command; bool found; + void *context; antenna_mode_cb callback; struct sir_antenna_mode_resp *param; @@ -2439,13 +2427,13 @@ static QDF_STATUS sme_process_antenna_mode_resp(tpAniSirGlobal mac, return QDF_STATUS_E_FAILURE; } - callback = - command->u.set_antenna_mode_cmd.set_antenna_mode_resp; + context = command->u.set_antenna_mode_cmd.set_antenna_mode_ctx; + callback = command->u.set_antenna_mode_cmd.set_antenna_mode_resp; if (callback) { if (!param) sme_err("Set antenna mode call back is NULL"); else - callback(param->status); + callback(param->status, context); } else sme_err("Callback does not exist"); @@ -2809,6 +2797,7 @@ QDF_STATUS sme_process_msg(tHalHandle hHal, cds_msg_t *pMsg) pMac->peer_rssi = peer_stats[0].rssi; pMac->peer_txrate = peer_stats[0].tx_rate; pMac->peer_rxrate = peer_stats[0].rx_rate; + pMac->rx_mc_bc_cnt = peer_stats[0].rx_mc_bc_cnt; } } qdf_mem_free(pMsg->bodyptr); @@ -3228,10 +3217,14 @@ QDF_STATUS sme_close(tHalHandle hHal) { QDF_STATUS status = QDF_STATUS_E_FAILURE; QDF_STATUS fail_status = QDF_STATUS_SUCCESS; - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpAniSirGlobal pMac; - if (!pMac) + if (NULL != hHal) { + pMac = PMAC_STRUCT(hHal); + } else { + sme_err(" Invalid hHal"); return QDF_STATUS_E_FAILURE; + } /* Note: pSession will be invalid from here on, do not access */ status = csr_close(pMac); @@ -3449,14 +3442,16 @@ QDF_STATUS sme_get_ap_channel_from_scan_cache(tHalHandle hal_handle, uint8_t *ap_chnl_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle); + tpAniSirGlobal mac_ctx; tCsrScanResultFilter *scan_filter = NULL; tScanResultHandle filtered_scan_result = NULL; tSirBssDescription first_ap_profile; - if (NULL == mac_ctx) { + if (NULL != hal_handle) { + mac_ctx = PMAC_STRUCT(hal_handle); + } else { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - FL("mac_ctx is NULL")); + FL("hal_handle is NULL")); return QDF_STATUS_E_FAILURE; } scan_filter = qdf_mem_malloc(sizeof(tCsrScanResultFilter)); @@ -3941,10 +3936,14 @@ QDF_STATUS sme_roam_connect(tHalHandle hHal, uint8_t sessionId, tCsrRoamProfile *pProfile, uint32_t *pRoamId) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpAniSirGlobal pMac; - if (!pMac) + if (NULL != hHal) { + pMac = PMAC_STRUCT(hHal); + } else { + sme_err("Invalid hHal"); return QDF_STATUS_E_FAILURE; + } MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_MSG_CONNECT, sessionId, 0)); @@ -3977,19 +3976,12 @@ QDF_STATUS sme_set_phy_mode(tHalHandle hHal, eCsrPhyMode phyMode) { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "%s: invalid context", __func__); - return QDF_STATUS_E_FAILURE; - } - pMac->roam.configParam.phyMode = phyMode; pMac->roam.configParam.uCfgDot11Mode = csr_get_cfg_dot11_mode_from_csr_phy_mode(NULL, pMac->roam.configParam.phyMode, pMac->roam.configParam. ProprietaryRatesEnabled); - return QDF_STATUS_SUCCESS; } @@ -4109,12 +4101,15 @@ QDF_STATUS sme_roam_disconnect(tHalHandle hHal, uint8_t sessionId, */ void sme_dhcp_done_ind(tHalHandle hal, uint8_t session_id) { - tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + tpAniSirGlobal mac_ctx; tCsrRoamSession *session; - if (!mac_ctx) + if (NULL != hal) { + mac_ctx = PMAC_STRUCT(hal); + } else { + sme_err("Invalid hal"); return; - + } session = CSR_GET_SESSION(mac_ctx, session_id); if (!session) { sme_err("Session: %d not found", session_id); @@ -4167,7 +4162,10 @@ QDF_STATUS sme_roam_disconnect_sta(tHalHandle hHal, uint8_t sessionId, QDF_STATUS status = QDF_STATUS_E_FAILURE; tpAniSirGlobal pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) { + if (NULL != hHal) { + pMac = PMAC_STRUCT(hHal); + } else { + sme_err("Invalid hHal"); QDF_ASSERT(0); return status; } @@ -4239,9 +4237,11 @@ QDF_STATUS sme_roam_tkip_counter_measures(tHalHandle hHal, uint8_t sessionId, bool bEnable) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpAniSirGlobal pMac; - if (NULL == pMac) { + if (NULL != hHal) { + pMac = PMAC_STRUCT(hHal); + } else { QDF_ASSERT(0); return status; } @@ -4283,9 +4283,11 @@ QDF_STATUS sme_roam_get_associated_stas(tHalHandle hHal, uint8_t sessionId, uint8_t *pAssocStasBuf) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + tpAniSirGlobal pMac; - if (NULL == pMac) { + if (NULL != hHal) { + pMac = PMAC_STRUCT(hHal); + } else { QDF_ASSERT(0); return status; } @@ -4490,6 +4492,7 @@ QDF_STATUS sme_roam_del_pmkid_from_cache(tHalHandle hHal, uint8_t sessionId, return status; } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD void sme_get_pmk_info(tHalHandle hal, uint8_t session_id, tPmkidCacheInfo *pmk_cache) { @@ -4502,6 +4505,13 @@ void sme_get_pmk_info(tHalHandle hal, uint8_t session_id, sme_release_global_lock(&mac_ctx->sme); } } +#else +static inline +void sme_get_pmk_info(tHalHandle hal, uint8_t session_id, + tPmkidCacheInfo *pmk_cache) +{} +#endif + #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * sme_roam_set_psk_pmk() - A wrapper function to request CSR to save PSK/PMK @@ -5004,13 +5014,6 @@ void sme_register_ftm_msg_processor(tHalHandle hal, hdd_ftm_msg_processor callback) { tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); - - if (mac_ctx == NULL) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - FL("mac ctx is NULL")); - return; - } - mac_ctx->ftm_msg_processor_callback = callback; } @@ -14733,11 +14736,12 @@ QDF_STATUS sme_ll_stats_set_req(tHalHandle hHal, tSirLLStatsSetReq * * @hHal * @pgetStatsReq: Link Layer get stats request params structure + * @context: Callback context for ll stats * * Return QDF_STATUS */ QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, tSirLLStatsGetReq - *pgetStatsReq) + *pgetStatsReq, void *context) { QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; @@ -14756,6 +14760,7 @@ QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, tSirLLStatsGetReq *get_stats_req = *pgetStatsReq; + pMac->sme.ll_stats_context = context; if (QDF_STATUS_SUCCESS == sme_acquire_global_lock(&pMac->sme)) { /* Serialize the req through MC thread */ cds_message.bodyptr = get_stats_req; @@ -14785,16 +14790,17 @@ QDF_STATUS sme_ll_stats_get_req(tHalHandle hHal, tSirLLStatsGetReq /** * sme_set_link_layer_stats_ind_cb() - SME API to trigger the stats are - * available after get request + * available after get request * - * @hHal - * @callback_routine - HDD callback which needs to be invoked after - * getting status notification from FW + * @hHal: handle in hdd context + * @callback_routine: HDD callback which needs to be invoked after + * getting status notification from FW * * Return QDF_STATUS */ QDF_STATUS sme_set_link_layer_stats_ind_cb(tHalHandle hHal, - void (*callback_routine)(void *callbackCtx, int indType, void *pRsp)) + void (*callback_routine)(void *callbackCtx, int indType, void *pRsp, + void *context)) { QDF_STATUS status = QDF_STATUS_SUCCESS; tpAniSirGlobal pMac = PMAC_STRUCT(hHal); @@ -17633,11 +17639,13 @@ QDF_STATUS sme_set_sar_power_limits(tHalHandle hal, * sme_encrypt_decrypt_msg() - handles encrypt/decrypt mesaage * @hal: HAL handle * @encrypt_decrypt_params: struct to set encryption/decryption params. + * @context: callback context * * Return: QDF_STATUS enumeration. */ QDF_STATUS sme_encrypt_decrypt_msg(tHalHandle hal, - struct encrypt_decrypt_req_params *encrypt_decrypt_params) + struct encrypt_decrypt_req_params *encrypt_decrypt_params, + void *context) { QDF_STATUS status = QDF_STATUS_SUCCESS; tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); @@ -17664,6 +17672,7 @@ QDF_STATUS sme_encrypt_decrypt_msg(tHalHandle hal, params->data_len); } + mac_ctx->sme.encrypt_decrypt_context = context; status = sme_acquire_global_lock(&mac_ctx->sme); if (status == QDF_STATUS_SUCCESS) { /* Serialize the req through MC thread */ @@ -17692,16 +17701,17 @@ QDF_STATUS sme_encrypt_decrypt_msg(tHalHandle hal, * encrypt/decrypt message callback * * @hal - MAC global handle - * @callback_routine - callback routine from HDD + * @encrypt_decrypt_cb - callback routine from HDD + * @context - callback context * * This API is invoked by HDD to register its callback in SME * * Return: QDF_STATUS */ QDF_STATUS sme_encrypt_decrypt_msg_register_callback(tHalHandle hal, - void (*encrypt_decrypt_cb)(void *hdd_context, - struct sir_encrypt_decrypt_rsp_params - *encrypt_decrypt_rsp_params)) + void (*encrypt_decrypt_cb)(void *cookie, + struct sir_encrypt_decrypt_rsp_params + *encrypt_decrypt_rsp_params)) { QDF_STATUS status = QDF_STATUS_SUCCESS; tpAniSirGlobal mac; @@ -18632,21 +18642,18 @@ QDF_STATUS sme_get_chain_rssi(tHalHandle phal, return status; } -/** - * sme_chain_rssi_register_callback - chain rssi callback - * @hal: global hal handle - * @pchain_rssi_ind_cb: callback function pointer - * - * Return: QDF_STATUS enumeration. - */ -QDF_STATUS sme_chain_rssi_register_callback(tHalHandle phal, - void (*pchain_rssi_ind_cb)(void *, void *)) +QDF_STATUS +sme_chain_rssi_register_callback(tHalHandle phal, + void (*pchain_rssi_ind_cb)(void *, void *, + void *), + void *context) { QDF_STATUS status; tpAniSirGlobal pmac = PMAC_STRUCT(phal); status = sme_acquire_global_lock(&pmac->sme); if (QDF_STATUS_SUCCESS == status) { + pmac->sme.pchain_rssi_ind_ctx = context; pmac->sme.pchain_rssi_ind_cb = pchain_rssi_ind_cb; sme_release_global_lock(&pmac->sme); } @@ -18654,6 +18661,21 @@ QDF_STATUS sme_chain_rssi_register_callback(tHalHandle phal, return status; } +void sme_chain_rssi_deregister_callback(tHalHandle hal) +{ + tpAniSirGlobal pmac; + + if (!hal) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("hHal is not valid")); + return; + } + + pmac = PMAC_STRUCT(hal); + if (pmac->sme.pchain_rssi_ind_cb) + pmac->sme.pchain_rssi_ind_cb = NULL; +} + QDF_STATUS sme_set_reorder_timeout(tHalHandle hal, struct sir_set_rx_reorder_timeout_val *req) { @@ -18948,7 +18970,7 @@ QDF_STATUS sme_set_action_oui_ext(tHalHandle hal, tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); struct ani_action_oui *action_oui; - if (action_id > WMI_ACTION_OUI_MAXIMUM_ID) { + if (action_id >= WMI_ACTION_OUI_MAXIMUM_ID) { sme_err("Invalid OUI action ID"); return QDF_STATUS_E_INVAL; } @@ -19088,7 +19110,7 @@ QDF_STATUS sme_send_action_oui(tHalHandle hal, struct ani_action_oui *sme_action; void *wma_handle; - if (action_id > WMI_ACTION_OUI_MAXIMUM_ID) { + if (action_id >= WMI_ACTION_OUI_MAXIMUM_ID) { sme_warn("Invalid OUI action ID"); return QDF_STATUS_SUCCESS; } @@ -19265,6 +19287,20 @@ QDF_STATUS sme_fast_reassoc(tHalHandle hal, tCsrRoamProfile *profile, struct wma_roam_invoke_cmd *fastreassoc; cds_msg_t msg = {0}; tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + tCsrRoamSession *session; + session = CSR_GET_SESSION(mac_ctx, vdev_id); + if (!session || !session->pCurRoamProfile) { + sme_err("session %d not found", vdev_id); + return QDF_STATUS_E_FAILURE; + } + + if (session->pCurRoamProfile->supplicant_disabled_roaming || + session->pCurRoamProfile->driver_disabled_roaming) { + sme_debug("roaming status in Supplicant %d and in driver %d", + session->pCurRoamProfile->supplicant_disabled_roaming, + session->pCurRoamProfile->driver_disabled_roaming); + return QDF_STATUS_E_FAILURE; + } fastreassoc = qdf_mem_malloc(sizeof(*fastreassoc)); if (NULL == fastreassoc) { diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 4fd0aed708ee..b8cdc3fe0f8d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -578,10 +578,6 @@ QDF_STATUS csr_set_reg_info(tHalHandle hHal, uint8_t *apCntryCode) qdf_mem_copy(pMac->scan.countryCodeDefault, apCntryCode, cntryCodeLength); - /* If 2 bytes country code, 3rd byte must be filled with space */ - if ((WNI_CFG_COUNTRY_CODE_LEN - 1) == cntryCodeLength) - qdf_mem_set(pMac->scan.countryCodeDefault + 2, 1, 0x20); - qdf_mem_copy(pMac->scan.countryCodeCurrent, pMac->scan.countryCodeDefault, WNI_CFG_COUNTRY_CODE_LEN); status = csr_get_channel_and_power_list(pMac); @@ -1644,6 +1640,11 @@ void csr_abort_command(tpAniSirGlobal pMac, tSmeCmd *pCommand, bool fStopping) void csr_roam_substate_change(tpAniSirGlobal pMac, eCsrRoamSubState NewSubstate, uint32_t sessionId) { + if (sessionId >= CSR_ROAM_SESSION_MAX) { + sme_err("Invalid no of concurrent sessions %d", + sessionId); + return; + } sme_debug("CSR RoamSubstate: [ %s <== %s ]", mac_trace_getcsr_roam_sub_state(NewSubstate), mac_trace_getcsr_roam_sub_state(pMac->roam. @@ -2295,6 +2296,11 @@ QDF_STATUS csr_roam_read_tsf(tpAniSirGlobal pMac, uint8_t *pTimestamp, tpSirBssDescription pBssDescription = NULL; csr_neighbor_roam_get_handoff_ap_info(pMac, &handoffNode, sessionId); + + if (!handoffNode.pBssDescription) { + sme_err("Bss Description NULL"); + return QDF_STATUS_E_INVAL; + } pBssDescription = handoffNode.pBssDescription; /* Get the time diff in nano seconds */ timer_diff = (qdf_get_monotonic_boottime_ns() - @@ -5367,6 +5373,10 @@ QDF_STATUS csr_roam_set_bss_config_cfg(tpAniSirGlobal pMac, uint32_t sessionId, uint32_t cfgCb = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE; uint8_t channel = 0; tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); + if (!pSession) { + sme_err("session %d not found", sessionId); + return QDF_STATUS_E_FAILURE; + } /* Make sure we have the domain info for the BSS we try to connect to. * Do we need to worry about sequence for OSs that are not Windows?? @@ -6273,7 +6283,7 @@ static QDF_STATUS csr_roam_trigger_reassociate(tpAniSirGlobal mac_ctx, QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand) { - QDF_STATUS status = QDF_STATUS_SUCCESS; + QDF_STATUS lock_status, status = QDF_STATUS_SUCCESS; tCsrRoamInfo roamInfo; uint32_t sessionId = pCommand->sessionId; tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId); @@ -6291,7 +6301,18 @@ QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand) case eCsrForcedDisassoc: status = csr_roam_process_disassoc_deauth(pMac, pCommand, true, false); + lock_status = sme_acquire_global_lock(&pMac->sme); + if (!QDF_IS_STATUS_SUCCESS(lock_status)) { + csr_roam_complete(pMac, eCsrNothingToJoin, NULL); + /* + * Return success so that caller will not remove cmd + * again from smeCmdActiveList as it is already removed + * as part of csr_roam_complete. + */ + return QDF_STATUS_SUCCESS; + } csr_free_roam_profile(pMac, sessionId); + sme_release_global_lock(&pMac->sme); break; case eCsrSmeIssuedDisassocForHandoff: /* Not to free pMac->roam.pCurRoamProfile (via @@ -6304,12 +6325,34 @@ QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand) case eCsrForcedDisassocMICFailure: status = csr_roam_process_disassoc_deauth(pMac, pCommand, true, true); + lock_status = sme_acquire_global_lock(&pMac->sme); + if (!QDF_IS_STATUS_SUCCESS(lock_status)) { + csr_roam_complete(pMac, eCsrNothingToJoin, NULL); + /* + * Return success so that caller will not remove cmd + * again from smeCmdActiveList as it is already removed + * as part of csr_roam_complete. + */ + return QDF_STATUS_SUCCESS; + } csr_free_roam_profile(pMac, sessionId); + sme_release_global_lock(&pMac->sme); break; case eCsrForcedDeauth: status = csr_roam_process_disassoc_deauth(pMac, pCommand, false, false); + lock_status = sme_acquire_global_lock(&pMac->sme); + if (!QDF_IS_STATUS_SUCCESS(lock_status)) { + csr_roam_complete(pMac, eCsrNothingToJoin, NULL); + /* + * Return success so that caller will not remove cmd + * again from smeCmdActiveList as it is already removed + * as part of csr_roam_complete. + */ + return QDF_STATUS_SUCCESS; + } csr_free_roam_profile(pMac, sessionId); + sme_release_global_lock(&pMac->sme); break; case eCsrHddIssuedReassocToSameAP: case eCsrSmeIssuedReassocToSameAP: @@ -6369,6 +6412,17 @@ QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand) if (pCommand->u.roamCmd.fUpdateCurRoamProfile) { /* Remember the roaming profile */ + lock_status = sme_acquire_global_lock(&pMac->sme); + if (!QDF_IS_STATUS_SUCCESS(lock_status)) { + csr_roam_complete(pMac, + eCsrNothingToJoin, NULL); + /* + * Return success so that caller will not remove + * cmd again from smeCmdActiveList as it is + * already removed as part of csr_roam_complete. + */ + return QDF_STATUS_SUCCESS; + } csr_free_roam_profile(pMac, sessionId); pSession->pCurRoamProfile = qdf_mem_malloc(sizeof(tCsrRoamProfile)); @@ -6377,6 +6431,7 @@ QDF_STATUS csr_roam_process_command(tpAniSirGlobal pMac, tSmeCmd *pCommand) pSession->pCurRoamProfile, &pCommand->u.roamCmd.roamProfile); } + sme_release_global_lock(&pMac->sme); } /* * At this point original uapsd_mask is saved in @@ -7026,6 +7081,7 @@ static void csr_roam_process_results_default(tpAniSirGlobal mac_ctx, roam_info.rssi = mac_ctx->peer_rssi; roam_info.tx_rate = mac_ctx->peer_txrate; roam_info.rx_rate = mac_ctx->peer_rxrate; + roam_info.rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt; csr_roam_state_change(mac_ctx, eCSR_ROAMING_STATE_JOINED, session_id); @@ -9913,12 +9969,18 @@ static void csr_roam_roaming_state_reassoc_rsp_processor(tpAniSirGlobal pMac, tpSirSmeJoinRsp pSmeJoinRsp) { enum csr_roamcomplete_result result; - tpCsrNeighborRoamControlInfo pNeighborRoamInfo = - &pMac->roam.neighborRoamInfo[pSmeJoinRsp->sessionId]; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; tCsrRoamInfo roamInfo; uint32_t roamId = 0; tCsrRoamSession *csr_session; + if (pSmeJoinRsp->sessionId >= CSR_ROAM_SESSION_MAX) { + sme_err("Invalid session ID received %d", + pSmeJoinRsp->sessionId); + return; + } + pNeighborRoamInfo = + &pMac->roam.neighborRoamInfo[pSmeJoinRsp->sessionId]; if (eSIR_SME_SUCCESS == pSmeJoinRsp->statusCode) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, "CSR SmeReassocReq Successful"); @@ -10591,6 +10653,9 @@ void csr_roam_joined_state_msg_processor(tpAniSirGlobal pMac, void *pMsgBuf) pRoamInfo->ht_caps = pUpperLayerAssocCnf->HTCaps; if (pUpperLayerAssocCnf->VHTCaps.present) pRoamInfo->vht_caps = pUpperLayerAssocCnf->VHTCaps; + pRoamInfo->capability_info = + pUpperLayerAssocCnf->capability_info; + if (CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) { pMac->roam.roamSession[sessionId].connectState = eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED; @@ -11543,6 +11608,7 @@ csr_roam_chk_lnk_assoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) qdf_mem_copy(&roam_info_ptr->vht_caps, &pAssocInd->VHTCaps, sizeof(tDot11fIEVHTCaps)); + roam_info_ptr->capability_info = pAssocInd->capability_info; if (CSR_IS_INFRA_AP(roam_info_ptr->u.pConnectedProfile)) { if (session->pCurRoamProfile && @@ -11580,6 +11646,44 @@ csr_roam_chk_lnk_assoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) } } +static bool csr_is_deauth_disassoc_already_active(tpAniSirGlobal mac_ctx, + uint8_t session_id, struct qdf_mac_addr peer_macaddr) +{ + bool ret = false, active_cmd = false; + tSmeCmd *sme_cmd; + tListElem *entry; + + entry = csr_ll_peek_head(&mac_ctx->sme.smeCmdActiveList, + LL_ACCESS_LOCK); + while (entry) { + sme_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); + if (sme_cmd->command == eSmeCommandRoam && + (sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta || + sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta) && + sme_cmd->sessionId == session_id) { + active_cmd = true; + break; + } + entry = csr_ll_next(&mac_ctx->sme.smeCmdActiveList, entry, + LL_ACCESS_LOCK); + } + + if (!active_cmd) + return ret; + + if ((mac_ctx->roam.curSubState[session_id] == + eCSR_ROAM_SUBSTATE_DEAUTH_REQ || + mac_ctx->roam.curSubState[session_id] == + eCSR_ROAM_SUBSTATE_DISASSOC_REQ) && + !qdf_mem_cmp(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac, + QDF_MAC_ADDR_SIZE)) { + sme_err("Ignore DEAUTH_IND/DIASSOC_IND as Deauth/Disassoc already in progress"); + ret = true; + } + + return ret; +} + static void csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) { @@ -11610,6 +11714,12 @@ csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) return; } + if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, + pDisassocInd->peer_macaddr)) { + qdf_mem_free(cmd); + return; + } + sme_err("DISASSOCIATION from peer =" MAC_ADDRESS_STR "reason: %d status: %d session: %d", MAC_ADDR_ARRAY(pDisassocInd->peer_macaddr.bytes), pDisassocInd->reasonCode, @@ -11702,6 +11812,7 @@ csr_roam_send_disconnect_done_indication(tpAniSirGlobal mac_ctx, tSirSmeRsp roam_info.rssi = mac_ctx->peer_rssi; roam_info.tx_rate = mac_ctx->peer_txrate; roam_info.rx_rate = mac_ctx->peer_rxrate; + roam_info.rx_mc_bc_cnt = mac_ctx->rx_mc_bc_cnt; roam_info.disassoc_reason = discon_ind->reason_code; csr_roam_call_callback(mac_ctx, discon_ind->session_id, @@ -11741,6 +11852,11 @@ csr_roam_chk_lnk_deauth_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr) &sessionId); if (!QDF_IS_STATUS_SUCCESS(status)) return; + + if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId, + pDeauthInd->peer_macaddr)) + return; + /* If we are in neighbor preauth done state then on receiving * disassoc or deauth we dont roam instead we just disassoc * from current ap and then go to disconnected state @@ -14442,6 +14558,7 @@ static void csr_roam_update_connected_profile_from_new_bss(tpAniSirGlobal pMac, } } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD void csr_get_pmk_info(tpAniSirGlobal mac_ctx, uint8_t session_id, tPmkidCacheInfo *pmk_cache) { @@ -14460,7 +14577,7 @@ void csr_get_pmk_info(tpAniSirGlobal mac_ctx, uint8_t session_id, sizeof(session->psk_pmk)); pmk_cache->pmk_len = session->pmk_len; } -#ifdef WLAN_FEATURE_ROAM_OFFLOAD + QDF_STATUS csr_roam_set_psk_pmk(tpAniSirGlobal pMac, uint32_t sessionId, uint8_t *pPSK_PMK, size_t pmk_len) { @@ -15452,7 +15569,7 @@ void csr_dump_vendor_ies(uint8_t *ie, uint16_t ie_len) return; } if (elem_id == SIR_MAC_EID_VENDOR) { - pe_debug("Dumping Vendor IE of len %d", elem_len); + sme_debug("Dumping Vendor IE of len %d", elem_len); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, &ptr[2], elem_len); @@ -15495,19 +15612,21 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, uint8_t *oui_ptr; uint8_t *ie_fields = (uint8_t *)bss_desc->ieFields; - if (action_id > WMI_ACTION_OUI_MAXIMUM_ID) { - pe_debug("Invalid OUI action ID"); + if (action_id >= WMI_ACTION_OUI_MAXIMUM_ID) { + sme_debug("Invalid OUI action ID"); return false; } + sme_debug("Action ID : %d", action_id); + if (!mac_ctx->oui_info) { - pe_debug("action oui support is disabled or oui info is empty"); + sme_debug("action oui support is disabled or oui info is empty"); return false; } sme_action = mac_ctx->oui_info->action_oui[action_id]; if (!sme_action) { - pe_debug("action oui for id %d is empty", action_id); + sme_debug("action oui for id %d is empty", action_id); return false; } @@ -15516,12 +15635,10 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, qdf_mutex_acquire(&sme_action->oui_ext_list_lock); if (qdf_list_empty(oui_ext_list)) { qdf_mutex_release(&sme_action->oui_ext_list_lock); - pe_debug("OUI List Empty"); + sme_debug("OUI List Empty"); return false; } - csr_dump_vendor_ies((uint8_t *)ie_fields, ie_len); - qdf_list_peek_front(oui_ext_list, &node); while (node) { sme_ext = qdf_container_of(node, @@ -15539,7 +15656,7 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, (uint8_t *)ie_fields, ie_len); if (!oui_ptr) { - pe_debug("No matching IE found for OUI"); + sme_debug("No matching IE found for OUI"); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, extension->oui, @@ -15547,7 +15664,7 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, goto next; } - pe_debug("IE found for OUI"); + sme_debug("IE found for OUI"); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, extension->oui, @@ -15555,24 +15672,24 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, if (extension->data_length && !csr_check_for_vendor_oui_data(extension, oui_ptr)) { - pe_debug("Vendor IE Data mismatch"); + sme_debug("Vendor IE Data mismatch"); goto next; } if ((extension->info_mask & WMI_ACTION_OUI_INFO_MAC_ADDRESS) && !csr_check_for_vendor_ap_mac(extension, bss_desc->bssId)) { - pe_debug("Vendor IE MAC Mismatch"); + sme_debug("Vendor IE MAC Mismatch"); goto next; } if (!csr_check_for_vendor_ap_capabilities(extension, ie, bss_desc, dot11_mode)) { - pe_debug("Vendor IE capabilties mismatch"); + sme_debug("Vendor IE capabilties mismatch"); goto next; } - pe_debug("Vendor AP found for OUI"); + sme_debug("Vendor AP found for OUI"); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, extension->oui, extension->oui_length); qdf_mutex_release(&sme_action->oui_ext_list_lock); @@ -15614,7 +15731,7 @@ csr_check_vendor_ap_3_present(tpAniSirGlobal mac_ctx, uint8_t *ie, SIR_MAC_VENDOR_AP_3_OUI_LEN, ie, ie_len)) && (cfg_get_vendor_ie_ptr_from_oui(mac_ctx, SIR_MAC_VENDOR_AP_4_OUI, SIR_MAC_VENDOR_AP_4_OUI_LEN, ie, ie_len))) { - pe_debug("Vendor OUI 3 and Vendor OUI 4 found"); + sme_debug("Vendor OUI 3 and Vendor OUI 4 found"); ret = false; } @@ -15657,7 +15774,6 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, uint32_t value = 0, value1 = 0; QDF_STATUS packetdump_timer_status; enum hw_mode_dbs_capab hw_mode_to_use; - tDot11fIEVHTCaps *vht_caps = NULL; bool is_vendor_ap_present; struct vdev_type_nss *vdev_type_nss; @@ -15783,6 +15899,9 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, pSession->supported_nss_1x1 = true; ieLen = csr_get_ielen_from_bss_description(pBssDescription); + csr_dump_vendor_ies((uint8_t *)pBssDescription->ieFields, + ieLen); + is_vendor_ap_present = csr_check_vendor_ap_present( pMac, pBssDescription, ucDot11Mode, pIes, ieLen, @@ -15793,6 +15912,21 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, pMac, (uint8_t *)pIes, ieLen); } + /* + * For WMI_ACTION_OUI_CONNECT_1x1_WITH_1_CHAIN, the host + * sends the NSS as 1 to the FW and the FW then decides + * after receiving the first beacon after connection to + * switch to 1 Tx/Rx Chain. + */ + if (!is_vendor_ap_present) { + is_vendor_ap_present = csr_check_vendor_ap_present( + pMac, pBssDescription, + ucDot11Mode, pIes, ieLen, + WMI_ACTION_OUI_CONNECT_1x1_WITH_1_CHAIN); + if (is_vendor_ap_present) + sme_debug("1x1 with 1 Chain AP"); + } + if (pMac->roam.configParam.is_force_1x1 && pMac->lteCoexAntShare && is_vendor_ap_present) { @@ -15812,7 +15946,7 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, ucDot11Mode, pIes, ieLen, WMI_ACTION_OUI_CCKM_1X1); if (is_vendor_ap_present) { - pe_debug("vdev: %d WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM 1", + sme_debug("vdev: %d WMI_VDEV_PARAM_ABG_MODE_TX_CHAIN_NUM 1", pSession->sessionId); wma_cli_set_command( pSession->sessionId, @@ -16278,12 +16412,8 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, csr_join_req->vht_config.su_beam_formee = value; - if (pIes->VHTCaps.present) - vht_caps = &pIes->VHTCaps; - else if (pIes->vendor_vht_ie.VHTCaps.present) - vht_caps = &pIes->vendor_vht_ie.VHTCaps; /* Set BF CSN value only if SU Bformee is enabled */ - if (vht_caps && csr_join_req->vht_config.su_beam_formee) { + if (csr_join_req->vht_config.su_beam_formee) { txBFCsnValue = (uint8_t)value1; /* * Certain commercial AP display a bad behavior when @@ -16293,11 +16423,18 @@ QDF_STATUS csr_send_join_req_msg(tpAniSirGlobal pMac, uint32_t sessionId, * CSN cap of less than 4. To avoid such issues, take a * min of self and peer CSN while sending ASSOC request. */ - if (pIes->Vendor1IE.present && - vht_caps->csnofBeamformerAntSup < 4) { - if (vht_caps->csnofBeamformerAntSup) + if (txBFCsnValue < 4) { + if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) && + pIes->VHTCaps.csnofBeamformerAntSup) + txBFCsnValue = QDF_MIN(txBFCsnValue, + pIes->VHTCaps.csnofBeamformerAntSup); + else if (IS_BSS_VHT_CAPABLE( + pIes->vendor_vht_ie.VHTCaps) + && pIes->vendor_vht_ie.VHTCaps. + csnofBeamformerAntSup) txBFCsnValue = QDF_MIN(txBFCsnValue, - vht_caps->csnofBeamformerAntSup); + pIes->vendor_vht_ie. + VHTCaps.csnofBeamformerAntSup); } } csr_join_req->vht_config.csnof_beamformer_antSup = txBFCsnValue; @@ -16997,6 +17134,7 @@ QDF_STATUS csr_send_assoc_ind_to_upper_layer_cnf_msg(tpAniSirGlobal pMac, pMsg->HTCaps = pAssocInd->HTCaps; if (pAssocInd->VHTCaps.present) pMsg->VHTCaps = pAssocInd->VHTCaps; + pMsg->capability_info = pAssocInd->capability_info; msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF; msgQ.bodyptr = pMsg; @@ -20250,6 +20388,7 @@ static void csr_update_fils_params_rso(tpAniSirGlobal mac, { struct roam_fils_params *roam_fils_params; struct cds_fils_connection_info *fils_info; + uint32_t usr_name_len; if (!session->pCurRoamProfile) return; @@ -20271,11 +20410,19 @@ static void csr_update_fils_params_rso(tpAniSirGlobal mac, return; } + usr_name_len = copy_all_before_char(fils_info->keyname_nai, + roam_fils_params->username, + '@', + WMI_FILS_MAX_USERNAME_LENGTH); + + if (fils_info->key_nai_length <= usr_name_len) { + sme_err("Fils info len error: key nai len %d, user name len %d", + fils_info->key_nai_length, usr_name_len); + return; + } + + roam_fils_params->username_length = usr_name_len; req_buffer->is_fils_connection = true; - roam_fils_params->username_length = - copy_all_before_char(fils_info->keyname_nai, - roam_fils_params->username, '@', - WMI_FILS_MAX_USERNAME_LENGTH); roam_fils_params->next_erp_seq_num = (fils_info->sequence_number + 1); @@ -21390,6 +21537,10 @@ QDF_STATUS csr_roam_channel_change_req(tpAniSirGlobal pMac, ¶m.operationalRateSet, sizeof(pMsg->operational_rateset)); qdf_mem_copy(&pMsg->extended_rateset, ¶m.extendedRateSet, sizeof(pMsg->extended_rateset)); + + sme_debug("target_chan %d ch_width %d dot11mode %d", + pMsg->targetChannel, pMsg->ch_width, pMsg->dot11mode); + status = cds_send_mb_message_to_mac(pMsg); return status; diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 7591dc0a9519..678f124b6483 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -43,6 +43,7 @@ #include "wlan_hdd_main.h" #include "pld_common.h" #include "csr_internal.h" +#include "sch_api.h" #define MIN_CHN_TIME_TO_FIND_GO 100 #define MAX_CHN_TIME_TO_FIND_GO 100 @@ -1654,16 +1655,13 @@ static void csr_scan_add_result(tpAniSirGlobal pMac, struct tag_csrscan_result *pResult, tDot11fBeaconIEs *pIes, uint32_t sessionId) { - tpCsrNeighborRoamControlInfo pNeighborRoamInfo; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; struct qdf_mac_addr bssid; uint8_t channel_id = pResult->Result.BssDescriptor.channelId; + bool is_session_valid = CSR_IS_SESSION_VALID(pMac, sessionId); - if (!CSR_IS_SESSION_VALID(pMac, sessionId)) { - sme_err("Invalid session id: %d", sessionId); - return; - } - - pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; + if (is_session_valid) + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; qdf_mem_zero(&bssid.bytes, QDF_MAC_ADDR_SIZE); qdf_mem_copy(bssid.bytes, &pResult->Result.BssDescriptor.bssId, QDF_MAC_ADDR_SIZE); @@ -1674,7 +1672,8 @@ static void csr_scan_add_result(tpAniSirGlobal pMac, struct tag_csrscan_result &pResult->Result.BssDescriptor, pIes); csr_ll_insert_tail(&pMac->scan.scanResultList, &pResult->Link, LL_ACCESS_LOCK); - if (0 == pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) { + if (pNeighborRoamInfo && + 0 == pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels) { /* * Build the occupied channel list, only if * "gNeighborScanChannelList" is NOT set in the cfg.ini file @@ -2170,9 +2169,6 @@ static int32_t csr_calculate_nss_score(uint8_t sta_nss, uint8_t ap_nss, uint8_t nss; uint8_t score_pct; - if (wma_is_current_hwmode_dbs()) - sta_nss--; - nss = ap_nss; if (sta_nss < nss) nss = sta_nss; @@ -2451,8 +2447,15 @@ csr_save_scan_entry(tpAniSirGlobal pMac, pcl_chan_weight); } } - if (pFilter) + if (pFilter && pMac->roam.configParam.is_bssid_hint_priority && + !qdf_mem_cmp(pResult->Result.BssDescriptor.bssId, + pFilter->bssid_hint.bytes, QDF_MAC_ADDR_SIZE)) { + sme_debug("BSSID hint AP "MAC_ADDRESS_STR " give max score", + MAC_ADDR_ARRAY(pFilter->bssid_hint.bytes)); + pResult->bss_score = BEST_CANDIDATE_MAX_BSS_SCORE; + } else if (pFilter) { csr_calculate_bss_score(pMac, pResult, pcl_chan_weight); + } /* * No need to lock pRetList because it is locally allocated and no @@ -2464,17 +2467,7 @@ csr_save_scan_entry(tpAniSirGlobal pMac, (*count)++; return status; } - if (pFilter && - !qdf_mem_cmp(pResult->Result.BssDescriptor.bssId, - pFilter->bssid_hint.bytes, QDF_MAC_ADDR_SIZE) && - pMac->roam.configParam.is_bssid_hint_priority) { - /* bssid hint AP should be on head */ - csr_ll_insert_head(&pRetList->List, - &pResult->Link, LL_ACCESS_NOLOCK); - (*count)++; - pResult->bss_score = BEST_CANDIDATE_MAX_BSS_SCORE; - return status; - } + pTmpEntry = csr_ll_peek_head(&pRetList->List, LL_ACCESS_NOLOCK); while (pTmpEntry) { pTmpResult = GET_BASE_ADDR(pTmpEntry, struct tag_csrscan_result, @@ -3829,6 +3822,10 @@ static struct tag_csrscan_result *csr_scan_save_bss_description(tpAniSirGlobal /* figure out how big the BSS description is (the BSSDesc->length does * NOT include the size of the length field itself). */ + if (CSR_SCAN_IS_OVER_BSS_LIMIT(pMac)) { + sme_debug("BSS Limit reached"); + return NULL; + } cbBSSDesc = pBSSDescription->length + sizeof(pBSSDescription->length); cbAllocated = sizeof(struct tag_csrscan_result) + cbBSSDesc; @@ -3844,10 +3841,7 @@ static struct tag_csrscan_result *csr_scan_save_bss_description(tpAniSirGlobal bssId)); qdf_mem_copy(&pCsrBssDescription->Result.BssDescriptor, pBSSDescription, cbBSSDesc); - if (NULL != pCsrBssDescription->Result.pvIes) { - QDF_ASSERT(pCsrBssDescription->Result.pvIes == NULL); - return NULL; - } + csr_scan_add_result(pMac, pCsrBssDescription, pIes, sessionId); } @@ -4072,6 +4066,7 @@ void csr_apply_channel_power_info_to_fw(tpAniSirGlobal mac_ctx, sme_err("11D channel list is empty"); } csr_set_cfg_country_code(mac_ctx, countryCode); + sch_edca_profile_update_all(mac_ctx); } #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR @@ -4260,6 +4255,7 @@ QDF_STATUS csr_set_country_code(tpAniSirGlobal pMac, uint8_t *pCountry) pCountry, WNI_CFG_COUNTRY_CODE_LEN); csr_set_cfg_country_code(pMac, pCountry); + sch_edca_profile_update_all(pMac); } } return status; diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 5f9edf88c93c..aadf6ea5f2b9 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -926,6 +926,7 @@ QDF_STATUS csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId, tPmkidCacheInfo *pPMKIDCache, uint32_t numItems, bool update_entire_cache); +#ifdef WLAN_FEATURE_ROAM_OFFLOAD /* * csr_get_pmk_info(): store PMK in pmk_cache * @mac_ctx: pointer to global structure for MAC @@ -940,7 +941,6 @@ QDF_STATUS csr_roam_set_pmkid_cache(tpAniSirGlobal pMac, uint32_t sessionId, void csr_get_pmk_info(tpAniSirGlobal mac_ctx, uint8_t session_id, tPmkidCacheInfo *pmk_cache); -#ifdef WLAN_FEATURE_ROAM_OFFLOAD /* * csr_roam_set_psk_pmk() - * store PSK/PMK diff --git a/core/sme/src/rrm/sme_rrm.c b/core/sme/src/rrm/sme_rrm.c index 35890bded9f3..f595e06b8de4 100644 --- a/core/sme/src/rrm/sme_rrm.c +++ b/core/sme/src/rrm/sme_rrm.c @@ -532,14 +532,16 @@ static QDF_STATUS sme_rrm_send_scan_result(tpAniSirGlobal mac_ctx, if (scan_type == eSIR_PASSIVE_SCAN) { session = CSR_GET_SESSION(mac_ctx, session_id); - if (csr_is_conn_state_connected_infra(mac_ctx, - session_id) && - (NULL != session->pConnectBssDesc) && - (csr_is_duplicate_bss_description(mac_ctx, - &scan_results->BssDescriptor, - session->pConnectBssDesc))) { - is_conn_bss_found = true; - sme_debug("Connected BSS in scan results"); + if (session) { + if (csr_is_conn_state_connected_infra(mac_ctx, + session_id) && + (NULL != session->pConnectBssDesc) && + (csr_is_duplicate_bss_description(mac_ctx, + &scan_results->BssDescriptor, + session->pConnectBssDesc))) { + is_conn_bss_found = true; + sme_debug("Connected BSS in scan results"); + } } } next_result = sme_scan_result_get_next(mac_ctx, result_handle); diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 0b69941a8455..196768f433cb 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -565,9 +565,6 @@ static const t_probeTime_dwellTime }; typedef void (*txFailIndCallback)(uint8_t *peer_mac, uint8_t seqNo); -typedef void (*encrypt_decrypt_cb)(struct sir_encrypt_decrypt_rsp_params - *encrypt_decrypt_rsp_params); - typedef void (*tp_wma_packetdump_cb)(qdf_nbuf_t netbuf, uint8_t status, uint8_t vdev_id, uint8_t type); diff --git a/core/wma/inc/wma_if.h b/core/wma/inc/wma_if.h index e4ea2849c827..658277ec5f0c 100644 --- a/core/wma/inc/wma_if.h +++ b/core/wma/inc/wma_if.h @@ -719,7 +719,7 @@ typedef struct sBeaconGenParams { */ typedef struct { tSirMacAddr bssId; - uint8_t *beacon; + uint8_t beacon[SIR_MAX_BEACON_SIZE]; uint32_t beaconLength; uint32_t timIeOffset; uint16_t p2pIeOffset; @@ -730,13 +730,13 @@ typedef struct { /** * struct tSendProbeRespParams - send probe response parameters * @bssId: BSSID - * @pProbeRespTemplate: probe response template + * @probeRespTemplate: probe response template * @probeRespTemplateLen: probe response template length * @ucProxyProbeReqValidIEBmap: valid IE bitmap */ typedef struct sSendProbeRespParams { tSirMacAddr bssId; - uint8_t *pProbeRespTemplate; + uint8_t probeRespTemplate[SIR_MAX_PROBE_RESP_SIZE]; uint32_t probeRespTemplateLen; uint32_t ucProxyProbeReqValidIEBmap[8]; } tSendProbeRespParams, *tpSendProbeRespParams; diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 2594a8aaea97..23c60673ed19 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -122,11 +122,6 @@ #define MAX_NUM_HW_MODE 0xff #define MAX_NUM_PHY 0xff -enum sar_version { - SAR_VERSION_1, - SAR_VERSION_2 -}; - /** * struct index_data_rate_type - non vht data rate type * @mcs_index: mcs rate index @@ -1233,13 +1228,13 @@ QDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle, /** * wma_sar_rsp_evt_handler() - process sar response event from FW. - * @handle: wma handle + * @scn_handle: scn handle * @event: event buffer * @len: buffer length * * Return: 0 for success or error code */ -int wma_sar_rsp_evt_handler(void *handle, uint8_t *event, uint32_t len); +int wma_sar_rsp_evt_handler(ol_scn_t scn_handle, uint8_t *event, uint32_t len); #ifdef FEATURE_WLAN_CH_AVOID int wma_channel_avoid_evt_handler(void *handle, uint8_t *event, diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h index cda306b551f5..30d4a8211f22 100644 --- a/core/wma/inc/wma_tgt_cfg.h +++ b/core/wma/inc/wma_tgt_cfg.h @@ -19,6 +19,8 @@ #ifndef WMA_TGT_CFG_H #define WMA_TGT_CFG_H +#include "wma_sar_public_structs.h" + /** * struct wma_tgt_services - target services * @sta_power_save: sta power save @@ -169,6 +171,7 @@ struct board_info { * @bool is_ra_rate_limit_enabled: RA filter support * @tx_bfee_8ss_enabled: Tx Beamformee support for 8x8 * @rcpi_enabled: for checking rcpi support + * @sar_version: Version of SAR supported by firmware */ struct wma_tgt_cfg { uint32_t target_fw_version; @@ -202,5 +205,6 @@ struct wma_tgt_cfg { bool rcpi_enabled; uint32_t hw_bd_id; struct board_info hw_bd_info; + enum sar_version sar_version; }; #endif /* WMA_TGT_CFG_H */ diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 97b31fe3ae97..31550a4fa467 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -1111,7 +1111,7 @@ QDF_STATUS wma_get_peer_info(WMA_HANDLE handle, WMITLV_TAG_STRUC_wmi_request_stats_cmd_fixed_param, WMITLV_GET_STRUCT_TLVLEN(wmi_request_stats_cmd_fixed_param)); - cmd->stats_id = WMI_REQUEST_PEER_STAT; + cmd->stats_id = WMI_REQUEST_PEER_STAT | WMI_REQUEST_PEER_EXTD_STAT; cmd->vdev_id = peer_info_req->sessionid; WMI_CHAR_ARRAY_TO_MAC_ADDR(peer_info_req->peer_macaddr.bytes, &cmd->peer_macaddr); @@ -4745,6 +4745,11 @@ int wma_wow_wakeup_host_event(void *handle, uint8_t *event, int tlv_ok_status; pdev = cds_get_context(QDF_MODULE_ID_TXRX); + if (!pdev) { + WMA_LOGE("Invalid pdev"); + return -EINVAL; + } + param_buf = (WMI_WOW_WAKEUP_HOST_EVENTID_param_tlvs *) event; if (!param_buf) { WMA_LOGE("Invalid wow wakeup host event buf"); @@ -7263,6 +7268,7 @@ static QDF_STATUS wma_send_gtk_offload_req(tp_wma_handle wma, uint8_t vdev_id, enable_offload = params->ulFlags; offload_params.kek_len = params->kek_len; + offload_params.is_fils_connection = params->is_fils_connection; /* send the wmi command */ status = wmi_unified_send_gtk_offload_cmd(wma->wmi_handle, @@ -8227,11 +8233,27 @@ QDF_STATUS wma_set_led_flashing(tp_wma_handle wma_handle, } #endif /* WLAN_FEATURE_GPIO_LED_FLASHING */ -int wma_sar_rsp_evt_handler(void *handle, uint8_t *event, uint32_t len) +int wma_sar_rsp_evt_handler(ol_scn_t handle, uint8_t *event, uint32_t len) { + tp_wma_handle wma_handle; + wmi_unified_t wmi_handle; QDF_STATUS status; - status = wmi_unified_extract_sar2_result_event(handle, + WMA_LOGD(FL("handle:%pK event:%pK len:%u"), handle, event, len); + + wma_handle = handle; + if (!wma_handle) { + WMA_LOGE(FL("NULL wma_handle")); + return QDF_STATUS_E_INVAL; + } + + wmi_handle = wma_handle->wmi_handle; + if (!wmi_handle) { + WMA_LOGE(FL("NULL wmi_handle")); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_extract_sar2_result_event(wmi_handle, event, len); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE(FL("Event extract failure: %d"), status); @@ -10903,11 +10925,16 @@ int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data, } data_event = param_buf->fixed_param; + /* initialize the memory to zero for encrypt_decrypt_rsp_params */ + qdf_mem_zero(&encrypt_decrypt_rsp_params, + sizeof(encrypt_decrypt_rsp_params)); encrypt_decrypt_rsp_params.vdev_id = data_event->vdev_id; encrypt_decrypt_rsp_params.status = data_event->status; - if (data_event->data_length > param_buf->num_enc80211_frame) { + if ((data_event->data_length > param_buf->num_enc80211_frame) || + (data_event->data_length > WMI_SVC_MSG_MAX_SIZE - WMI_TLV_HDR_SIZE - + sizeof(*data_event))) { WMA_LOGE("FW msg data_len %d more than TLV hdr %d", data_event->data_length, param_buf->num_enc80211_frame); @@ -10926,7 +10953,8 @@ int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data, encrypt_decrypt_rsp_params.data = buf_ptr; } - pmac->sme.encrypt_decrypt_cb(pmac->hHdd, &encrypt_decrypt_rsp_params); + pmac->sme.encrypt_decrypt_cb(pmac->sme.encrypt_decrypt_context, + &encrypt_decrypt_rsp_params); return 0; } @@ -11338,6 +11366,11 @@ int wma_pdev_div_info_evt_handler(void *handle, u_int8_t *event_buf, return -EINVAL; } + if (!pmac->sme.pchain_rssi_ind_cb) { + WMA_LOGE("%s: callback not registered", __func__); + return -EINVAL; + } + param_buf = (WMI_PDEV_DIV_RSSI_ANTID_EVENTID_param_tlvs *) event_buf; if (!param_buf) { WMA_LOGE(FL("Invalid rssi antid event buffer")); @@ -11368,7 +11401,8 @@ int wma_pdev_div_info_evt_handler(void *handle, u_int8_t *event_buf, qdf_mem_copy(chain_rssi_result.ant_id, event->ant_id, sizeof(event->ant_id)); - pmac->sme.pchain_rssi_ind_cb(pmac->hHdd, &chain_rssi_result); + pmac->sme.pchain_rssi_ind_cb(pmac->hHdd, &chain_rssi_result, + pmac->sme.pchain_rssi_ind_ctx); return 0; } @@ -11400,7 +11434,10 @@ void wma_spectral_scan_config(WMA_HANDLE wma_handle, if (wma == NULL) return; - + if (!wma_is_vdev_valid(req->vdev_id)) { + WMA_LOGE(FL("Invalid vdev id")); + return; + } /* save the copy of the config params */ qdf_mem_copy(&wma->ss_configs, req, sizeof(*req)); @@ -11550,6 +11587,13 @@ QDF_STATUS wma_send_dhcp_ind(uint16_t type, uint8_t device_mode, { QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; tAniDHCPInd *msg; + tp_wma_handle 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; + } msg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd)); if (NULL == msg) { @@ -11564,8 +11608,7 @@ QDF_STATUS wma_send_dhcp_ind(uint16_t type, uint8_t device_mode, qdf_mem_copy(msg->adapterMacAddr.bytes, mac_addr, QDF_MAC_ADDR_SIZE); qdf_mem_copy(msg->peerMacAddr.bytes, peer_mac_addr, QDF_MAC_ADDR_SIZE); - qdf_status = wma_process_dhcp_ind(cds_get_context(QDF_MODULE_ID_WMA), - (tAniDHCPInd *)msg); + qdf_status = wma_process_dhcp_ind(wma_handle, (tAniDHCPInd *)msg); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { QDF_TRACE(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_ERROR, "%s: Failed to send DHCP indication", __func__); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 73603727f412..24652057d687 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -832,6 +832,8 @@ static void wma_set_modulated_dtim(tp_wma_handle wma, &wma->interfaces[vdev_id]; bool prev_dtim_enabled; uint32_t listen_interval; + uint32_t beacon_interval_mod; + uint32_t max_mod_dtim; QDF_STATUS ret; iface->alt_modulated_dtim = privcmd->param_value; @@ -846,22 +848,41 @@ static void wma_set_modulated_dtim(tp_wma_handle wma, if ((true == iface->alt_modulated_dtim_enabled) || (true == prev_dtim_enabled)) { - listen_interval = iface->alt_modulated_dtim - * iface->dtimPeriod; + beacon_interval_mod = iface->beaconInterval / 100; + if (!beacon_interval_mod) + beacon_interval_mod = 1; - ret = wma_vdev_set_param(wma->wmi_handle, - privcmd->param_vdev_id, - WMI_VDEV_PARAM_LISTEN_INTERVAL, - listen_interval); + if (iface->dtimPeriod) + max_mod_dtim = wma->staMaxLIModDtim + / (iface->dtimPeriod*beacon_interval_mod); + else + max_mod_dtim = wma->staMaxLIModDtim/beacon_interval_mod; + + if (!max_mod_dtim) + max_mod_dtim = 1; + + if (iface->alt_modulated_dtim > max_mod_dtim) { + WMA_LOGE("User ModDtim(%d) exceeding ceiling limit(%d)", + iface->alt_modulated_dtim, max_mod_dtim); + listen_interval = max_mod_dtim * iface->dtimPeriod; + } else { + listen_interval = iface->alt_modulated_dtim + * iface->dtimPeriod; + } + + WMA_LOGD("Setting Listen Interval %d for vdev id %d", + listen_interval, vdev_id); + ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_LISTEN_INTERVAL, + listen_interval); if (QDF_IS_STATUS_ERROR(ret)) /* Even if it fails, continue */ WMA_LOGW("Failed to set listen interval %d", listen_interval); - ret = wma_vdev_set_param(wma->wmi_handle, - privcmd->param_vdev_id, - WMI_VDEV_PARAM_DTIM_POLICY, - NORMAL_DTIM); + ret = wma_vdev_set_param(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_DTIM_POLICY, + NORMAL_DTIM); if (QDF_IS_STATUS_ERROR(ret)) WMA_LOGE("Failed to Set to Normal DTIM policy"); } @@ -4785,6 +4806,15 @@ static void wma_update_ra_rate_limit(tp_wma_handle wma_handle, } #endif +static void wma_update_sar_version(tp_wma_handle wma_handle, + struct wma_tgt_cfg *cfg) +{ + struct extended_caps *phy_caps; + + phy_caps = &wma_handle->phy_caps; + cfg->sar_version = phy_caps->sar_capability.active_version; +} + /** * wma_update_hdd_cfg() - update HDD config * @wma_handle: wma handle @@ -4852,6 +4882,7 @@ static void wma_update_hdd_cfg(tp_wma_handle wma_handle) tgt_cfg.apf_enabled = wma_handle->apf_enabled; tgt_cfg.rcpi_enabled = wma_handle->rcpi_enabled; wma_update_ra_rate_limit(wma_handle, &tgt_cfg); + wma_update_sar_version(wma_handle, &tgt_cfg); tgt_cfg.fine_time_measurement_cap = wma_handle->fine_time_measurement_cap; tgt_cfg.wmi_max_len = wmi_get_max_msg_len(wma_handle->wmi_handle) @@ -7160,8 +7191,8 @@ static QDF_STATUS wma_get_chain_rssi(tp_wma_handle wma_handle, cmd = (wmi_pdev_div_get_rssi_antid_fixed_param *)buf_ptr; WMITLV_SET_HDR(&cmd->tlv_header, - WMITLV_TAG_STRUC_wmi_peer_antdiv_info_req_cmd_fixed_param, - WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_div_get_rssi_antid_fixed_param)); + WMITLV_TAG_STRUC_wmi_pdev_div_get_rssi_antid_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_pdev_div_get_rssi_antid_fixed_param)); cmd->pdev_id = 0; WMI_CHAR_ARRAY_TO_MAC_ADDR(req_params->peer_macaddr.bytes, &cmd->macaddr); diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 2c0c3ebb2a68..64fec8cb3412 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2293,7 +2293,7 @@ static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma, WMA_LOGD(FL("Send probe response template for vdev %d"), vdev_id); - frm = probe_rsp_info->pProbeRespTemplate; + frm = probe_rsp_info->probeRespTemplate; /* * Make the TSF offset negative so probe response in the same @@ -2305,7 +2305,7 @@ static int wmi_unified_probe_rsp_tmpl_send(tp_wma_handle wma, wh = (struct ieee80211_frame *)frm; A_MEMCPY(&wh[1], &adjusted_tsf_le, sizeof(adjusted_tsf_le)); - params.pProbeRespTemplate = probe_rsp_info->pProbeRespTemplate; + params.pProbeRespTemplate = probe_rsp_info->probeRespTemplate; params.probeRespTemplateLen = probe_rsp_info->probeRespTemplateLen; qdf_mem_copy(params.bssId, probe_rsp_info->bssId, IEEE80211_ADDR_LEN); @@ -2530,7 +2530,8 @@ int wma_tbttoffset_update_event_handler(void *handle, uint8_t *event, qdf_spin_lock_bh(&bcn->lock); qdf_mem_zero(&bcn_info, sizeof(bcn_info)); - bcn_info.beacon = qdf_nbuf_data(bcn->buf); + qdf_mem_copy(bcn_info.beacon, qdf_nbuf_data(bcn->buf), + bcn->len); bcn_info.p2pIeOffset = bcn->p2p_ie_offset; bcn_info.beaconLength = bcn->len; bcn_info.timIeOffset = bcn->tim_ie_offset; @@ -2585,7 +2586,7 @@ void wma_send_probe_rsp_tmpl(tp_wma_handle wma, } probe_rsp = (struct sAniProbeRspStruct *) - (probe_rsp_info->pProbeRespTemplate); + (probe_rsp_info->probeRespTemplate); if (!probe_rsp) { WMA_LOGE(FL("probe_rsp is NULL")); return; @@ -2938,6 +2939,29 @@ void wma_process_update_opmode(tp_wma_handle wma_handle, } /** + * wma_update_txrx_chainmask() - process txrx chainmask + * @num_rf_chains: rf chains + * @cmd_value: rx nss value + * + * Return: none + */ +static void wma_update_txrx_chainmask(int num_rf_chains, int *cmd_value) +{ + int tmp; + + tmp = WMA_MAX_RF_CHAINS(num_rf_chains); + if (*cmd_value > tmp) { + WMA_LOGE("%s: exceed the maximum! Request %d, Update %d", + __func__, *cmd_value, tmp); + *cmd_value = tmp; + } else if (*cmd_value < WMA_MIN_RF_CHAINS) { + WMA_LOGE("%s: less than the minimum! Request %d Update %d", + __func__, *cmd_value, WMA_MIN_RF_CHAINS); + *cmd_value = WMA_MIN_RF_CHAINS; + } +} + +/** * wma_process_update_rx_nss() - process update RX NSS cmd from UMAC * @wma_handle: wma handle * @update_rx_nss: rx nss value @@ -2951,6 +2975,8 @@ void wma_process_update_rx_nss(tp_wma_handle wma_handle, &wma_handle->interfaces[update_rx_nss->smesessionId]; int rx_nss = update_rx_nss->rxNss; + wma_update_txrx_chainmask(wma_handle->num_rf_chains, &rx_nss); + if (rx_nss > WMA_MAX_NSS) rx_nss = WMA_MAX_NSS; @@ -3257,6 +3283,11 @@ int wma_process_bip(tp_wma_handle wma_handle, uint8_t *efrm; efrm = qdf_nbuf_data(wbuf) + qdf_nbuf_len(wbuf); + /* Check if frame is invalid length */ + if (efrm - (uint8_t *)wh < sizeof(*wh) + sizeof(struct ieee80211_mmie)) { + WMA_LOGE(FL("Invalid frame length")); + return -EINVAL; + } if (iface->key.key_cipher == WMI_CIPHER_AES_CMAC) { key_id = (uint16_t)*(efrm - cds_get_mmie_size() + 2); diff --git a/core/wma/src/wma_sar_public_structs.h b/core/wma/src/wma_sar_public_structs.h index 00b9e06d243b..f2b330ba3f8e 100644 --- a/core/wma/src/wma_sar_public_structs.h +++ b/core/wma/src/wma_sar_public_structs.h @@ -21,6 +21,11 @@ struct sar_limit_event; +enum sar_version { + SAR_VERSION_1, + SAR_VERSION_2 +}; + /** * typedef wma_sar_cb() - SAR callback function * @context: Opaque context provided by caller in the original request diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 71e90cd43e3a..2d13ecee93e7 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -2262,6 +2262,7 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, NULL, &scan_params); if (roam_req->reason == REASON_ROAM_STOP_ALL || + roam_req->reason == REASON_DISCONNECTED || roam_req->reason == REASON_ROAM_SYNCH_FAILED) { mode = WMI_ROAM_SCAN_MODE_NONE; } else { @@ -2541,6 +2542,35 @@ void wma_process_roam_synch_fail(WMA_HANDLE handle, } /** + * wma_free_roam_synch_frame_ind() - Free the bcn_probe_rsp, reassoc_req, + * reassoc_rsp recieved as part of the ROAM_SYNC_FRAME event + * + * @iface - interaface corresponding to a vdev + * + * This API is used to free the buffer allocated during the ROAM_SYNC_FRAME + * event + * + */ +static void wma_free_roam_synch_frame_ind(struct wma_txrx_node *iface) +{ + if (iface->roam_synch_frame_ind.bcn_probe_rsp) { + qdf_mem_free(iface->roam_synch_frame_ind.bcn_probe_rsp); + iface->roam_synch_frame_ind.bcn_probe_rsp_len = 0; + iface->roam_synch_frame_ind.bcn_probe_rsp = NULL; + } + if (iface->roam_synch_frame_ind.reassoc_req) { + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req); + iface->roam_synch_frame_ind.reassoc_req_len = 0; + iface->roam_synch_frame_ind.reassoc_req = NULL; + } + if (iface->roam_synch_frame_ind.reassoc_rsp) { + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp); + iface->roam_synch_frame_ind.reassoc_rsp_len = 0; + iface->roam_synch_frame_ind.reassoc_rsp = NULL; + } +} + +/** * wma_fill_data_synch_frame_event() - Fill the the roam sync data buffer using * synch frame event data * @wma: Global WMA Handle @@ -2684,12 +2714,14 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, wmi_key_material *key; wmi_roam_fils_synch_tlv_param *fils_info; struct wma_txrx_node *iface = NULL; + int status = -EINVAL; synch_event = param_buf->fixed_param; roam_synch_ind_ptr->roamedVdevId = synch_event->vdev_id; roam_synch_ind_ptr->authStatus = synch_event->auth_status; roam_synch_ind_ptr->roamReason = synch_event->roam_reason; roam_synch_ind_ptr->rssi = synch_event->rssi; + iface = &wma->interfaces[synch_event->vdev_id]; WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid, roam_synch_ind_ptr->bssid.bytes); WMA_LOGD(FL("LFR3:- BSSID:- "MAC_ADDRESS_STR" roamedVdevId %d authStatus %d roamReason %d %s rssi %d isBeacon %d"), @@ -2703,11 +2735,10 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context, roam_synch_ind_ptr, NULL, SIR_ROAMING_DEREGISTER_STA))) { WMA_LOGE("LFR3: CSR Roam synch cb failed"); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } - iface = &wma->interfaces[synch_event->vdev_id]; - /* * If lengths of bcn_probe_rsp, reassoc_req and reassoc_rsp are zero in * synch_event driver would have received bcn_probe_rsp, reassoc_req @@ -2720,19 +2751,22 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, WMA_LOGE("LFR3: bcn_probe_rsp is NULL"); QDF_ASSERT(iface->roam_synch_frame_ind. bcn_probe_rsp != NULL); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } if (!iface->roam_synch_frame_ind.reassoc_rsp) { WMA_LOGE("LFR3: reassoc_rsp is NULL"); QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_rsp != NULL); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } if (!iface->roam_synch_frame_ind.reassoc_req) { WMA_LOGE("LFR3: reassoc_req is NULL"); QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_req != NULL); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } wma_fill_data_synch_frame_event(wma, roam_synch_ind_ptr, iface); } else { @@ -2768,7 +2802,8 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, __func__, fils_info->kek_len, fils_info->pmk_len); - return -EINVAL; + wma_free_roam_synch_frame_ind(iface); + return status; } roam_synch_ind_ptr->kek_len = fils_info->kek_len; @@ -2791,6 +2826,7 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma, roam_synch_ind_ptr->update_erp_next_seq_num, roam_synch_ind_ptr->next_erp_seq_num); } + wma_free_roam_synch_frame_ind(iface); return 0; } @@ -3160,25 +3196,25 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, WMA_LOGD("LFR3:Synch Frame event"); if (!event) { WMA_LOGE("event param null"); - goto cleanup_label; + return status; } param_buf = (WMI_ROAM_SYNCH_FRAME_EVENTID_param_tlvs *) event; if (!param_buf) { WMA_LOGE("received null buf from target"); - goto cleanup_label; + return status; } synch_frame_event = param_buf->fixed_param; if (!synch_frame_event) { WMA_LOGE("received null event data from target"); - goto cleanup_label; + return status; } if (synch_frame_event->vdev_id >= wma->max_bssid) { WMA_LOGE("received invalid vdev_id %d", synch_frame_event->vdev_id); - goto cleanup_label; + return status; } vdev_id = synch_frame_event->vdev_id; @@ -3186,7 +3222,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, if (wma_is_roam_synch_in_progress(wma, vdev_id)) { WMA_LOGE("Ignoring this event as it is unexpected"); - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } WMA_LOGD("LFR3: Received ROAM_SYNCH_FRAME_EVENT"); @@ -3202,6 +3239,9 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, iface->roam_synch_frame_ind.is_beacon = synch_frame_event->is_beacon; + if (iface->roam_synch_frame_ind.bcn_probe_rsp) + qdf_mem_free(iface->roam_synch_frame_ind. + bcn_probe_rsp); iface->roam_synch_frame_ind.bcn_probe_rsp = qdf_mem_malloc(iface->roam_synch_frame_ind. bcn_probe_rsp_len); @@ -3210,7 +3250,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, QDF_ASSERT(iface->roam_synch_frame_ind. bcn_probe_rsp != NULL); status = -ENOMEM; - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } qdf_mem_copy(iface->roam_synch_frame_ind. bcn_probe_rsp, @@ -3222,6 +3263,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, iface->roam_synch_frame_ind.reassoc_req_len = synch_frame_event->reassoc_req_len; + if (iface->roam_synch_frame_ind.reassoc_req) + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req); iface->roam_synch_frame_ind.reassoc_req = qdf_mem_malloc(iface->roam_synch_frame_ind. reassoc_req_len); @@ -3230,7 +3273,8 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_req != NULL); status = -ENOMEM; - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } qdf_mem_copy(iface->roam_synch_frame_ind.reassoc_req, param_buf->reassoc_req_frame, @@ -3238,9 +3282,18 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, } if (synch_frame_event->reassoc_rsp_len) { + if (!iface->roam_synch_frame_ind.bcn_probe_rsp || + !iface->roam_synch_frame_ind.reassoc_req) { + WMA_LOGE("failed: No probe or reassoc rsp"); + wma_free_roam_synch_frame_ind(iface); + return status; + } iface->roam_synch_frame_ind.reassoc_rsp_len = synch_frame_event->reassoc_rsp_len; + if (iface->roam_synch_frame_ind.reassoc_rsp) + qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp); + iface->roam_synch_frame_ind.reassoc_rsp = qdf_mem_malloc(iface->roam_synch_frame_ind. reassoc_rsp_len); @@ -3249,29 +3302,14 @@ int wma_roam_synch_frame_event_handler(void *handle, uint8_t *event, QDF_ASSERT(iface->roam_synch_frame_ind. reassoc_rsp != NULL); status = -ENOMEM; - goto cleanup_label; + wma_free_roam_synch_frame_ind(iface); + return status; } qdf_mem_copy(iface->roam_synch_frame_ind.reassoc_rsp, param_buf->reassoc_rsp_frame, iface->roam_synch_frame_ind.reassoc_rsp_len); } return 0; - -cleanup_label: - if (iface && (iface->roam_synch_frame_ind.bcn_probe_rsp)) { - qdf_mem_free(iface->roam_synch_frame_ind. - bcn_probe_rsp); - iface->roam_synch_frame_ind.bcn_probe_rsp = NULL; - } - if (iface && (iface->roam_synch_frame_ind.reassoc_req)) { - qdf_mem_free(iface->roam_synch_frame_ind.reassoc_req); - iface->roam_synch_frame_ind.reassoc_req = NULL; - } - if (iface && (iface->roam_synch_frame_ind.reassoc_rsp)) { - qdf_mem_free(iface->roam_synch_frame_ind.reassoc_rsp); - iface->roam_synch_frame_ind.reassoc_rsp = NULL; - } - return status; } #define RSN_CAPS_SHIFT 16 @@ -5415,12 +5453,14 @@ int wma_extscan_change_results_event_handler(void *handle, src_rssi[count++]; } } - dest_ap += dest_ap->numOfRssi * sizeof(int32_t); + dest_ap = (tSirWifiSignificantChange *)((char *)dest_ap + + dest_ap->numOfRssi * sizeof(int32_t) + + sizeof(*dest_ap)); src_chglist++; } dest_chglist->requestId = event->request_id; dest_chglist->moreData = moredata; - dest_chglist->numResults = event->total_entries; + dest_chglist->numResults = numap; pMac->sme.pExtScanIndCb(pMac->hHdd, eSIR_EXTSCAN_SIGNIFICANT_WIFI_CHANGE_RESULTS_IND, diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index c3fe6290a18a..1b3b58828e14 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1406,7 +1406,8 @@ static int wma_unified_link_peer_stats_event_handler(void *handle, */ pMac->sme.pLinkLayerStatsIndCallback(pMac->hHdd, WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + link_stats_results, + pMac->sme.ll_stats_context); qdf_mem_free(link_stats_results); return 0; @@ -1601,8 +1602,9 @@ post_stats: * used to retrieve the correct HDD context */ mac->sme.pLinkLayerStatsIndCallback(mac->hHdd, - WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + WMA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results, + mac->sme.ll_stats_context); wma_unified_radio_tx_mem_free(handle); return 0; @@ -1813,7 +1815,8 @@ static int wma_unified_link_radio_stats_event_handler(void *handle, pMac->sme.pLinkLayerStatsIndCallback(pMac->hHdd, WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + link_stats_results, + pMac->sme.ll_stats_context); wma_unified_radio_tx_mem_free(handle); return 0; @@ -2291,7 +2294,8 @@ int wma_unified_link_iface_stats_event_handler(void *handle, */ pMac->sme.pLinkLayerStatsIndCallback(pMac->hHdd, WMA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); + link_stats_results, + pMac->sme.ll_stats_context); qdf_mem_free(link_stats_results); return 0; @@ -3007,6 +3011,7 @@ int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event) */ static void wma_handle_sta_peer_info(uint32_t num_peer_stats, wmi_peer_stats *peer_stats, + wmi_peer_extd_stats *peer_extd_stats, struct qdf_mac_addr peer_macaddr, uint8_t *sapaddr) { @@ -3029,6 +3034,8 @@ static void wma_handle_sta_peer_info(uint32_t num_peer_stats, break; } peer_stats = peer_stats + 1; + if (peer_extd_stats) + peer_extd_stats = peer_extd_stats + 1; } peer_info = qdf_mem_malloc(sizeof(*peer_info) + sizeof(peer_info->info[0])); @@ -3049,6 +3056,12 @@ static void wma_handle_sta_peer_info(uint32_t num_peer_stats, peer_stats->peer_rssi, peer_stats->peer_tx_rate, peer_stats->peer_rx_rate); + if (peer_extd_stats) { + peer_info->info[0].rx_mc_bc_cnt = + peer_extd_stats->rx_mc_bc_cnt; + WMA_LOGD("rx_mc_bc_cnt %u", + peer_info->info[0].rx_mc_bc_cnt); + } } else { WMA_LOGE("%s: no match mac address", __func__); peer_info->count = 0; @@ -3074,6 +3087,12 @@ static void wma_handle_sta_peer_info(uint32_t num_peer_stats, peer_stats->peer_rssi, peer_stats->peer_tx_rate, peer_stats->peer_rx_rate); + if (peer_extd_stats) { + peer_info->info[j].rx_mc_bc_cnt = + peer_extd_stats->rx_mc_bc_cnt; + WMA_LOGD("rx_mc_bc_cnt %u", + peer_info->info[j].rx_mc_bc_cnt); + } if (!qdf_mem_cmp(peer_info->info[j].peer_macaddr.bytes, sapaddr, QDF_MAC_ADDR_SIZE)) { peer_info->count = peer_info->count - 1; @@ -3081,6 +3100,8 @@ static void wma_handle_sta_peer_info(uint32_t num_peer_stats, j++; } peer_stats = peer_stats + 1; + if (peer_extd_stats) + peer_extd_stats = peer_extd_stats + 1; } WMA_LOGD("WDA send peer num %d", peer_info->count); } @@ -3099,6 +3120,31 @@ static void wma_handle_sta_peer_info(uint32_t num_peer_stats, } /** + * wma_get_peer_extd_stats_loc() - Gets the extended peer info + * location in stats response buffer + * @event: WMI stats event + * @temp: Pointer to the buffer pointing at peer stats + * + * This function will calculate the extended peer stats location + * in the stats response buffer. + * + * Return: pointer to extended peer info in the response buffer + */ +static wmi_peer_extd_stats *wma_get_peer_extd_stats_loc( + wmi_stats_event_fixed_param *event, uint8_t *temp) +{ + uint8_t *peer_extd_stats = temp; + + peer_extd_stats += event->num_peer_stats * sizeof(wmi_peer_stats) + + event->num_bcnflt_stats * sizeof(wmi_bcnfilter_stats_t) + + event->num_chan_stats * sizeof(wmi_chan_stats) + + event->num_mib_stats * sizeof(wmi_mib_stats) + + event->num_bcn_stats * sizeof(wmi_bcn_stats); + + return (wmi_peer_extd_stats *)peer_extd_stats; +} + +/** * wma_stats_event_handler() - stats event handler * @handle: wma handle * @cmd_param_info: data from event @@ -3115,6 +3161,7 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info, wmi_pdev_stats *pdev_stats; wmi_vdev_stats *vdev_stats; wmi_peer_stats *peer_stats; + wmi_rssi_stats *rssi_stats; wmi_per_chain_rssi_stats *rssi_event; struct wma_txrx_node *node; @@ -3132,11 +3179,19 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info, } event = param_buf->fixed_param; temp = (uint8_t *) param_buf->data; - if ((event->num_pdev_stats + event->num_vdev_stats + - event->num_peer_stats) > param_buf->num_data) { - WMA_LOGE("%s: Invalid num_pdev_stats:%d or num_vdev_stats:%d or num_peer_stats:%d", - __func__, event->num_pdev_stats, event->num_vdev_stats, - event->num_peer_stats); + + buf_len = event->num_pdev_stats * sizeof(wmi_pdev_stats) + + event->num_vdev_stats * sizeof(wmi_vdev_stats) + + event->num_peer_stats * sizeof(wmi_peer_stats) + + event->num_bcnflt_stats * sizeof(wmi_bcnfilter_stats_t) + + event->num_chan_stats * sizeof(wmi_chan_stats) + + event->num_mib_stats * sizeof(wmi_mib_stats) + + event->num_bcn_stats * sizeof(wmi_bcn_stats) + + event->num_peer_extd_stats * sizeof(wmi_peer_extd_stats); + + if (buf_len != param_buf->num_data) { + WMA_LOGE("Invalid Buffer len %d received, Expected %d", + buf_len, param_buf->num_data); return -EINVAL; } @@ -3206,9 +3261,16 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info, } if (event->num_peer_stats > 0) { + wmi_peer_extd_stats *peer_extd_stats = NULL; + + if (event->num_peer_extd_stats == event->num_peer_stats) { + peer_extd_stats = wma_get_peer_extd_stats_loc(event, + temp); + } if (wma->get_sta_peer_info == true) { wma_handle_sta_peer_info(event->num_peer_stats, (wmi_peer_stats *)temp, + peer_extd_stats, wma->peer_macaddr, wma->myaddr); } else { diff --git a/uapi/linux/qca_vendor.h b/uapi/linux/qca_vendor.h index bbbd831a6209..6638e054c802 100644 --- a/uapi/linux/qca_vendor.h +++ b/uapi/linux/qca_vendor.h @@ -630,9 +630,10 @@ enum qca_wlan_vendor_attr_get_station_info { QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD, -#endif + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT, + /* keep last */ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX = |
