diff options
41 files changed, 729 insertions, 170 deletions
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/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index caf037042acf..1a35d567b371 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; } @@ -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 @@ -8865,7 +8903,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 +8917,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 +8941,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; } @@ -11077,3 +11122,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/dp/htt/htt_h2t.c b/core/dp/htt/htt_h2t.c index 90258509093f..a684b7b0b178 100644 --- a/core/dp/htt/htt_h2t.c +++ b/core/dp/htt/htt_h2t.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 @@ -758,7 +758,7 @@ int htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev, uint32_t stats_type_upload_mask, uint32_t stats_type_reset_mask, - uint8_t cfg_stat_type, uint32_t cfg_val, uint64_t cookie) + uint8_t cfg_stat_type, uint32_t cfg_val, uint8_t cookie) { struct htt_htc_pkt *pkt; qdf_nbuf_t msg; @@ -821,11 +821,11 @@ htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev, /* cookie LSBs */ msg_word++; - *msg_word = cookie & 0xffffffff; + *msg_word = cookie; /* cookie MSBs */ msg_word++; - *msg_word = cookie >> 32; + *msg_word = 0; SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt, htt_h2t_send_complete_free_netbuf, 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/htt/htt_t2h.c b/core/dp/htt/htt_t2h.c index 96630a703169..53a5636dc1bf 100644 --- a/core/dp/htt/htt_t2h.c +++ b/core/dp/htt/htt_t2h.c @@ -385,11 +385,10 @@ static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg, } case HTT_T2H_MSG_TYPE_STATS_CONF: { - uint64_t cookie; + uint8_t cookie; uint8_t *stats_info_list; cookie = *(msg_word + 1); - cookie |= ((uint64_t) (*(msg_word + 2))) << 32; stats_info_list = (uint8_t *) (msg_word + 3); htc_pm_runtime_put(pdev->htc_pdev); diff --git a/core/dp/ol/inc/ol_htt_api.h b/core/dp/ol/inc/ol_htt_api.h index 9d115e9a305c..11edcdb1170c 100644 --- a/core/dp/ol/inc/ol_htt_api.h +++ b/core/dp/ol/inc/ol_htt_api.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 @@ -155,7 +155,7 @@ htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev, uint32_t stats_type_upload_mask, uint32_t stats_type_reset_mask, uint8_t cfg_stats_type, - uint32_t cfg_val, uint64_t cookie); + uint32_t cfg_val, uint8_t cookie); /** * @brief Get the fields from HTT T2H stats upload message's stats info header diff --git a/core/dp/ol/inc/ol_txrx_htt_api.h b/core/dp/ol/inc/ol_txrx_htt_api.h index da5b066a742d..3a9ee439c8e3 100644 --- a/core/dp/ol/inc/ol_txrx_htt_api.h +++ b/core/dp/ol/inc/ol_txrx_htt_api.h @@ -595,7 +595,7 @@ ol_rx_pn_ind_handler(ol_txrx_pdev_handle pdev, */ void ol_txrx_fw_stats_handler(ol_txrx_pdev_handle pdev, - uint64_t cookie, uint8_t *stats_info_list); + uint8_t cookie, uint8_t *stats_info_list); /** * @brief Process a tx inspect message sent by the target. diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 3e9ebd2ca56e..3e15d69f4131 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -1459,6 +1459,7 @@ ol_txrx_pdev_attach(ol_pdev_handle ctrl_pdev, TXRX_STATS_INIT(pdev); ol_txrx_tso_stats_init(pdev); + ol_txrx_fw_stats_desc_pool_init(pdev, FW_STATS_DESC_POOL_SIZE); TAILQ_INIT(&pdev->vdev_list); TAILQ_INIT(&pdev->roam_stale_peer_list); @@ -1524,6 +1525,7 @@ fail2: fail1: ol_txrx_tso_stats_deinit(pdev); + ol_txrx_fw_stats_desc_pool_deinit(pdev); qdf_mem_free(pdev); fail0: @@ -2307,6 +2309,7 @@ void ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev) htt_pdev_free(pdev->htt_pdev); ol_txrx_peer_find_detach(pdev); ol_txrx_tso_stats_deinit(pdev); + ol_txrx_fw_stats_desc_pool_deinit(pdev); ol_txrx_pdev_txq_log_destroy(pdev); ol_txrx_pdev_grp_stat_destroy(pdev); @@ -4132,20 +4135,171 @@ void ol_txrx_fw_stats_cfg(ol_txrx_vdev_handle vdev, uint8_t cfg_stats_type, uint32_t cfg_val) { - uint64_t dummy_cookie = 0; + uint8_t dummy_cookie = 0; htt_h2t_dbg_stats_get(vdev->pdev->htt_pdev, 0 /* upload mask */, 0 /* reset mask */, cfg_stats_type, cfg_val, dummy_cookie); } +/** + * ol_txrx_fw_stats_desc_pool_init() - Initialize the fw stats descriptor pool + * @pdev: handle to ol txrx pdev + * @pool_size: Size of fw stats descriptor pool + * + * Return: 0 for success, error code on failure. + */ +int ol_txrx_fw_stats_desc_pool_init(struct ol_txrx_pdev_t *pdev, + uint8_t pool_size) +{ + int i; + + if (!pdev) { + ol_txrx_err("%s: pdev is NULL", __func__); + return -EINVAL; + } + pdev->ol_txrx_fw_stats_desc_pool.pool = qdf_mem_malloc(pool_size * + sizeof(struct ol_txrx_fw_stats_desc_elem_t)); + if (!pdev->ol_txrx_fw_stats_desc_pool.pool) { + ol_txrx_err("%s: failed to allocate desc pool", __func__); + return -ENOMEM; + } + pdev->ol_txrx_fw_stats_desc_pool.freelist = + &pdev->ol_txrx_fw_stats_desc_pool.pool[0]; + pdev->ol_txrx_fw_stats_desc_pool.pool_size = pool_size; + + for (i = 0; i < (pool_size - 1); i++) { + pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.desc_id = i; + pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.req = NULL; + pdev->ol_txrx_fw_stats_desc_pool.pool[i].next = + &pdev->ol_txrx_fw_stats_desc_pool.pool[i + 1]; + } + pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.desc_id = i; + pdev->ol_txrx_fw_stats_desc_pool.pool[i].desc.req = NULL; + pdev->ol_txrx_fw_stats_desc_pool.pool[i].next = NULL; + qdf_spinlock_create(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock); + qdf_atomic_init(&pdev->ol_txrx_fw_stats_desc_pool.initialized); + qdf_atomic_set(&pdev->ol_txrx_fw_stats_desc_pool.initialized, 1); + return 0; +} + +/** + * ol_txrx_fw_stats_desc_pool_deinit() - Deinitialize the + * fw stats descriptor pool + * @pdev: handle to ol txrx pdev + * + * Return: None + */ +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; + } + if (!qdf_atomic_read(&pdev->ol_txrx_fw_stats_desc_pool.initialized)) { + ol_txrx_err("%s: Pool is not initialized", __func__); + return; + } + if (!pdev->ol_txrx_fw_stats_desc_pool.pool) { + ol_txrx_err("%s: Pool is not allocated", __func__); + return; + } + + 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; + + pdev->ol_txrx_fw_stats_desc_pool.freelist = NULL; + pdev->ol_txrx_fw_stats_desc_pool.pool_size = 0; + qdf_spin_unlock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock); +} + +/** + * ol_txrx_fw_stats_desc_alloc() - Get fw stats descriptor from fw stats + * free descriptor pool + * @pdev: handle to ol txrx pdev + * + * Return: pointer to fw stats descriptor, NULL on failure + */ +struct ol_txrx_fw_stats_desc_t + *ol_txrx_fw_stats_desc_alloc(struct ol_txrx_pdev_t *pdev) +{ + struct ol_txrx_fw_stats_desc_t *desc = NULL; + + qdf_spin_lock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock); + if (!qdf_atomic_read(&pdev->ol_txrx_fw_stats_desc_pool.initialized)) { + qdf_spin_unlock_bh(&pdev-> + ol_txrx_fw_stats_desc_pool.pool_lock); + ol_txrx_err("%s: Pool deinitialized", __func__); + return NULL; + } + if (pdev->ol_txrx_fw_stats_desc_pool.freelist) { + desc = &pdev->ol_txrx_fw_stats_desc_pool.freelist->desc; + pdev->ol_txrx_fw_stats_desc_pool.freelist = + pdev->ol_txrx_fw_stats_desc_pool.freelist->next; + } + qdf_spin_unlock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock); + + if (desc) + ol_txrx_dbg("%s: desc_id %d allocated", + __func__, desc->desc_id); + else + ol_txrx_err("%s: fw stats descriptors are exhausted", __func__); + + return desc; +} + +/** + * ol_txrx_fw_stats_desc_get_req() - Put fw stats descriptor + * back into free pool + * @pdev: handle to ol txrx pdev + * @fw_stats_desc: fw_stats_desc_get descriptor + * + * Return: pointer to request + */ +struct ol_txrx_stats_req_internal + *ol_txrx_fw_stats_desc_get_req(struct ol_txrx_pdev_t *pdev, + unsigned char desc_id) +{ + struct ol_txrx_fw_stats_desc_elem_t *desc_elem; + struct ol_txrx_stats_req_internal *req; + + qdf_spin_lock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock); + if (!qdf_atomic_read(&pdev->ol_txrx_fw_stats_desc_pool.initialized)) { + qdf_spin_unlock_bh(&pdev-> + ol_txrx_fw_stats_desc_pool.pool_lock); + ol_txrx_err("%s: Desc ID %u Pool deinitialized", + __func__, desc_id); + return NULL; + } + desc_elem = &pdev->ol_txrx_fw_stats_desc_pool.pool[desc_id]; + req = desc_elem->desc.req; + desc_elem->desc.req = NULL; + desc_elem->next = + pdev->ol_txrx_fw_stats_desc_pool.freelist; + pdev->ol_txrx_fw_stats_desc_pool.freelist = desc_elem; + qdf_spin_unlock_bh(&pdev->ol_txrx_fw_stats_desc_pool.pool_lock); + return req; +} + A_STATUS ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev, struct ol_txrx_stats_req *req, bool per_vdev, bool response_expected) { struct ol_txrx_pdev_t *pdev = vdev->pdev; - uint64_t cookie; + uint8_t cookie = FW_STATS_DESC_POOL_SIZE; struct ol_txrx_stats_req_internal *non_volatile_req; + struct ol_txrx_fw_stats_desc_t *desc = NULL; + struct ol_txrx_fw_stats_desc_elem_t *elem = NULL; if (!pdev || req->stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS || @@ -4165,11 +4319,16 @@ ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev, struct ol_txrx_stats_req *req, non_volatile_req->base = *req; non_volatile_req->serviced = 0; non_volatile_req->offset = 0; - - /* use the non-volatile request object's address as the cookie */ - cookie = ol_txrx_stats_ptr_to_u64(non_volatile_req); - if (response_expected) { + desc = ol_txrx_fw_stats_desc_alloc(pdev); + if (!desc) { + qdf_mem_free(non_volatile_req); + return A_ERROR; + } + + /* use the desc id as the cookie */ + cookie = desc->desc_id; + desc->req = non_volatile_req; qdf_spin_lock_bh(&pdev->req_list_spinlock); TAILQ_INSERT_TAIL(&pdev->req_list, non_volatile_req, req_list_elem); pdev->req_list_depth++; @@ -4183,9 +4342,28 @@ ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev, struct ol_txrx_stats_req *req, cookie)) { if (response_expected) { qdf_spin_lock_bh(&pdev->req_list_spinlock); - TAILQ_REMOVE(&pdev->req_list, non_volatile_req, req_list_elem); + TAILQ_REMOVE(&pdev->req_list, non_volatile_req, + req_list_elem); pdev->req_list_depth--; qdf_spin_unlock_bh(&pdev->req_list_spinlock); + if (desc) { + qdf_spin_lock_bh(&pdev-> + ol_txrx_fw_stats_desc_pool. + pool_lock); + desc->req = NULL; + elem = container_of(desc, + struct + ol_txrx_fw_stats_desc_elem_t, + desc); + elem->next = + pdev->ol_txrx_fw_stats_desc_pool. + freelist; + pdev->ol_txrx_fw_stats_desc_pool. + freelist = elem; + qdf_spin_unlock_bh(&pdev-> + ol_txrx_fw_stats_desc_pool. + pool_lock); + } } qdf_mem_free(non_volatile_req); @@ -4200,7 +4378,7 @@ ol_txrx_fw_stats_get(ol_txrx_vdev_handle vdev, struct ol_txrx_stats_req *req, void ol_txrx_fw_stats_handler(ol_txrx_pdev_handle pdev, - uint64_t cookie, uint8_t *stats_info_list) + uint8_t cookie, uint8_t *stats_info_list) { enum htt_dbg_stats_type type; enum htt_dbg_stats_status status; @@ -4210,8 +4388,16 @@ ol_txrx_fw_stats_handler(ol_txrx_pdev_handle pdev, int more = 0; int found = 0; - req = ol_txrx_u64_to_stats_ptr(cookie); - + if (cookie >= FW_STATS_DESC_POOL_SIZE) { + ol_txrx_err("%s: Cookie is not valid", __func__); + return; + } + req = ol_txrx_fw_stats_desc_get_req(pdev, (uint8_t)cookie); + if (!req) { + ol_txrx_err("%s: Request not retrieved for cookie %u", __func__, + (uint8_t)cookie); + return; + } qdf_spin_lock_bh(&pdev->req_list_spinlock); TAILQ_FOREACH(tmp, &pdev->req_list, req_list_elem) { if (req == tmp) { diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h index c9fd6e0ae761..6c2c0c6d2a6b 100644 --- a/core/dp/txrx/ol_txrx.h +++ b/core/dp/txrx/ol_txrx.h @@ -69,6 +69,9 @@ ol_tx_desc_pool_size_hl(ol_pdev_handle ctrl_pdev); #define OL_TX_DESC_POOL_SIZE_MAX_HL 5000 #endif +#ifndef FW_STATS_DESC_POOL_SIZE +#define FW_STATS_DESC_POOL_SIZE 10 +#endif #ifdef CONFIG_PER_VDEV_TX_DESC_POOL #define TXRX_HL_TX_FLOW_CTRL_VDEV_LOW_WATER_MARK 400 @@ -197,4 +200,13 @@ void ol_txrx_update_mac_id(uint8_t vdev_id, uint8_t mac_id); void ol_txrx_peer_detach_force_delete(ol_txrx_peer_handle peer); void peer_unmap_timer_handler(unsigned long data); +int ol_txrx_fw_stats_desc_pool_init(struct ol_txrx_pdev_t *pdev, + uint8_t pool_size); +void ol_txrx_fw_stats_desc_pool_deinit(struct ol_txrx_pdev_t *pdev); +struct ol_txrx_fw_stats_desc_t + *ol_txrx_fw_stats_desc_alloc(struct ol_txrx_pdev_t + *pdev); +struct ol_txrx_stats_req_internal *ol_txrx_fw_stats_desc_get_req(struct + ol_txrx_pdev_t *pdev, uint8_t desc_id); + #endif /* _OL_TXRX__H_ */ diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index 572c048f9c02..c7b14901ebdb 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -547,6 +547,15 @@ struct ol_txrx_stats_req_internal { int offset; }; +struct ol_txrx_fw_stats_desc_t { + struct ol_txrx_stats_req_internal *req; + unsigned char desc_id; +}; + +struct ol_txrx_fw_stats_desc_elem_t { + struct ol_txrx_fw_stats_desc_elem_t *next; + struct ol_txrx_fw_stats_desc_t desc; +}; /* * As depicted in the diagram below, the pdev contains an array of @@ -659,6 +668,14 @@ struct ol_txrx_pdev_t { qdf_atomic_t target_tx_credit; qdf_atomic_t orig_target_tx_credit; + struct { + uint16_t pool_size; + struct ol_txrx_fw_stats_desc_elem_t *pool; + struct ol_txrx_fw_stats_desc_elem_t *freelist; + qdf_spinlock_t pool_lock; + qdf_atomic_t initialized; + } ol_txrx_fw_stats_desc_pool; + /* Peer mac address to staid mapping */ struct ol_mac_addr mac_to_staid[WLAN_MAX_STA_COUNT + 3]; diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 288f06a5ef1e..9b3eceadcde2 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -52,7 +52,6 @@ #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> /** Number of Tx Queues */ @@ -1636,6 +1635,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) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 8aa30132d3de..2254c4a7e916 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1841,6 +1841,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 +1875,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"); @@ -6266,7 +6271,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_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 9b99ed4c38ef..c6012b50d73c 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1919,9 +1919,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); } @@ -14522,6 +14521,17 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, return -EINVAL; } + pConfig = pHddCtx->config; + wdev = ndev->ieee80211_ptr; + + /* Reset the current device mode bit mask */ + cds_clear_concurrency_mode(pAdapter->device_mode); + + /* + * must be called after cds_clear_concurrency_mode's invocation so the + * current adapter's old device mode mapping is removed from our + * internal records. + */ if (!cds_allow_concurrency( wlan_hdd_convert_nl_iftype_to_hdd_type(type), 0, HW_MODE_20_MHZ)) { @@ -14529,12 +14539,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, return -EINVAL; } - pConfig = pHddCtx->config; - wdev = ndev->ieee80211_ptr; - - /* Reset the current device mode bit mask */ - cds_clear_concurrency_mode(pAdapter->device_mode); - hdd_update_tdls_ct_and_teardown_links(pHddCtx); if ((pAdapter->device_mode == QDF_STA_MODE) || (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) || @@ -15385,6 +15389,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*/ @@ -18363,8 +18372,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,7 +18384,20 @@ 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( @@ -18391,14 +18415,6 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, } } - /*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 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_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c index 7f8b1c35ad3b..4f52f5c2ba3e 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); diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 474c7fd7935c..0a6b0fa800ed 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -549,7 +549,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 +564,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; } @@ -8172,8 +8176,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) == @@ -8718,6 +8724,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 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..3c68149f2eb8 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -521,8 +521,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 @@ -1676,6 +1674,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) { @@ -2799,6 +2802,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 +2822,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 +3260,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); @@ -4556,6 +4564,9 @@ QDF_STATUS hdd_close_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, 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); hdd_cleanup_adapter(hdd_ctx, adapterNode->pAdapter, rtnl_held); @@ -5037,11 +5048,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 +5100,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); diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 5004526df150..41a996b7f613 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -2031,7 +2031,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_scan.c b/core/hdd/src/wlan_hdd_scan.c index 87dcbaf315c1..34a6df903d24 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, @@ -3941,6 +3947,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 +3956,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_stats.c b/core/hdd/src/wlan_hdd_stats.c index 51e305c7630c..eb0076a065a3 100644 --- a/core/hdd/src/wlan_hdd_stats.c +++ b/core/hdd/src/wlan_hdd_stats.c @@ -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)) { @@ -1355,9 +1366,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; diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index ca758c9c571a..49d7e9d0c8eb 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -5620,7 +5620,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); 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..d50e7e8f467a 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -12232,6 +12232,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/qwlan_version.h b/core/mac/inc/qwlan_version.h index 04f7d4afb774..94752da8eae7 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 "Y" +#define QWLAN_VERSION_BUILD 61 -#define QWLAN_VERSIONSTR "5.1.1.60W" +#define QWLAN_VERSIONSTR "5.1.1.61Y" #endif /* QWLAN_VERSION_H */ 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..4aabe564137e 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -1685,7 +1685,7 @@ lim_populate_peer_rate_set(tpAniSirGlobal pMac, } } else tempRateSet2.numRates = 0; - if ((tempRateSet.numRates + tempRateSet2.numRates) > + if ((tempRateSet.numRates + tempRateSet2.numRates) >= SIR_MAC_RATESET_EID_MAX) { pe_err("more than 12 rates in CFG"); return eSIR_FAILURE; 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..661d8e395bf1 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 @@ -1841,6 +1841,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_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/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..0bd401b86677 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 @@ -1709,9 +1709,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; } @@ -5083,7 +5083,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 +5125,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 +5143,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/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 90a656c91498..dd8f72cd38f4 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -18948,7 +18948,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 +19088,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; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 4fd0aed708ee..5a3af9a9c0c5 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -1644,6 +1644,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 +2300,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 +5377,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 +6287,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 +6305,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 +6329,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 +6416,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 +6435,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 @@ -15495,7 +15554,7 @@ 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) { + if (action_id >= WMI_ACTION_OUI_MAXIMUM_ID) { pe_debug("Invalid OUI action ID"); return false; } @@ -15657,7 +15716,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; @@ -16278,12 +16336,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 +16347,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; @@ -20250,6 +20311,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 +20333,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); diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 7591dc0a9519..1702a3b94d55 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -2170,9 +2170,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; 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/src/wma_features.c b/core/wma/src/wma_features.c index 97b31fe3ae97..c915eec134a6 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -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"); @@ -10907,7 +10912,9 @@ int wma_encrypt_decrypt_msg_handler(void *handle, uint8_t *data, 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); @@ -11550,6 +11557,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 +11578,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..c3906c25dfff 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -7160,8 +7160,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_scan_roam.c b/core/wma/src/wma_scan_roam.c index 71e90cd43e3a..d29fcff4d431 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 { @@ -5415,12 +5416,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, |
