diff options
24 files changed, 804 insertions, 231 deletions
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h index 807e4aa64779..1ecabb01b6c8 100644 --- a/core/cds/inc/cds_api.h +++ b/core/cds/inc/cds_api.h @@ -213,6 +213,8 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context); */ void cds_flush_cache_rx_queue(void); +QDF_STATUS cds_post_disable(v_CONTEXT_t cds_context); + QDF_STATUS cds_close(v_CONTEXT_t cds_context); void cds_core_return_msg(void *pVContext, p_cds_msg_wrapper pMsgWrapper); diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h index 9739ec4126ca..0fcb95f2db23 100644 --- a/core/cds/inc/cds_sched.h +++ b/core/cds/inc/cds_sched.h @@ -321,8 +321,6 @@ typedef struct _cds_context_type { bool do_hw_mode_change; bool enable_fatal_event; struct cds_config_info *cds_cfg; - /* WAR: Is cds disabled */ - bool is_cds_disabled; } cds_context_type, *p_cds_contextType; /*--------------------------------------------------------------------------- diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 26c01c1a412f..ff84def298ec 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -245,6 +245,14 @@ QDF_STATUS cds_open(void) QDF_ASSERT(0); goto err_msg_queue; } + + if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( + &cds_ctx->qdf_conc_list_lock))) { + cds_err("Failed to init qdf_conc_list_lock"); + QDF_ASSERT(0); + goto err_msg_queue; + } + /* Now Open the CDS Scheduler */ if (pHddCtx->driver_status == DRIVER_MODULES_UNINITIALIZED || @@ -258,7 +266,7 @@ QDF_STATUS cds_open(void) QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, "%s: Failed to open CDS Scheduler", __func__); QDF_ASSERT(0); - goto err_msg_queue; + goto err_concurrency_lock; } } @@ -415,6 +423,9 @@ err_bmi_close: err_sched_close: cds_sched_close(gp_cds_context); +err_concurrency_lock: + qdf_mutex_destroy(&cds_ctx->qdf_conc_list_lock); + err_msg_queue: cds_mq_deinit(&gp_cds_context->freeVosMq); @@ -688,9 +699,6 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context) wma_setneedshutdown(cds_context); } - hif_disable_isr(((cds_context_type *) cds_context)->pHIFContext); - hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext); - handle = cds_get_context(QDF_MODULE_ID_PE); if (!handle) { cds_err("Invalid PE context return!"); @@ -708,27 +716,51 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context) QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); } - gp_cds_context->is_cds_disabled = 1; return qdf_status; } +#ifdef HIF_USB +static inline void cds_suspend_target(tp_wma_handle wma_handle) +{ + QDF_STATUS status; + /* Suspend the target and disable interrupt */ + status = wma_suspend_target(wma_handle, 0); + if (status) + cds_err("Failed to suspend target, status = %d", status); +} +#else +static inline void cds_suspend_target(tp_wma_handle wma_handle) +{ + QDF_STATUS status; + /* Suspend the target and disable interrupt */ + status = wma_suspend_target(wma_handle, 1); + if (status) + cds_err("Failed to suspend target, status = %d", status); +} +#endif /* HIF_USB */ + /** - * cds_close() - close cds module + * cds_post_disable() - post disable cds module * @cds_context: CDS context * * Return: QDF status */ -QDF_STATUS cds_close(v_CONTEXT_t cds_context) +QDF_STATUS cds_post_disable(v_CONTEXT_t cds_context) { - QDF_STATUS qdf_status; tp_wma_handle wma_handle; - + struct hif_opaque_softc *hif_ctx; wma_handle = cds_get_context(QDF_MODULE_ID_WMA); if (!wma_handle) { cds_err("Failed to get wma_handle!"); return QDF_STATUS_E_INVAL; } + hif_ctx = cds_get_context(QDF_MODULE_ID_HIF); + if (!hif_ctx) { + cds_err("Failed to get hif_handle!"); + return QDF_STATUS_E_INVAL; + } + /* * With new state machine changes cds_close can be invoked without * cds_disable. So, send the following clean up prerequisites to fw, @@ -738,23 +770,27 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context) * - Clean up CE tasklets. */ - if (!gp_cds_context->is_cds_disabled) { - cds_info("send denint sequence to firmware"); - if (!cds_is_driver_recovering()) { -#ifdef HIF_USB - /* Suspend the target and enable interrupt */ - if (wma_suspend_target(wma_handle, 0)) - cds_err("Failed to suspend target"); -#else - /* Suspend the target and disable interrupt */ - if (wma_suspend_target(wma_handle, 1)) - cds_err("Failed to suspend target"); -#endif /* HIF_USB */ - } - hif_disable_isr( - ((cds_context_type *) cds_context)->pHIFContext); - hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext); - } + cds_info("send denint sequence to firmware"); + if (!cds_is_driver_recovering()) + cds_suspend_target(wma_handle); + hif_disable_isr(hif_ctx); + hif_reset_soc(hif_ctx); + + return QDF_STATUS_SUCCESS; +} + +/** + * cds_close() - close cds module + * @cds_context: CDS context + * + * This API allows user to close modules registered + * with connectivity device services. + * + * Return: QDF status + */ +QDF_STATUS cds_close(v_CONTEXT_t cds_context) +{ + QDF_STATUS qdf_status; qdf_status = wma_wmi_work_close(cds_context); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { @@ -824,13 +860,18 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context) QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); } + if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy( + &gp_cds_context->qdf_conc_list_lock))) { + cds_err("Failed to destroy qdf_conc_list_lock"); + QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); + } + cds_shutdown_notifier_purge(); cds_deinit_log_completion(); cds_deinit_ini_config(); qdf_timer_module_deinit(); - gp_cds_context->is_cds_disabled = 0; return QDF_STATUS_SUCCESS; } diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 254d782ccfa4..0940968ed4cb 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -1962,12 +1962,21 @@ next_action_three_connection_table[CDS_MAX_TWO_CONNECTION_MODE] uint32_t cds_get_connection_count(void) { uint32_t conn_index, count = 0; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return count; + } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if (conc_connection_list[conn_index].in_use) count++; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return count; } @@ -2173,6 +2182,14 @@ uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode, uint32_t *list) { uint32_t conn_index = 0, count = 0; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return count; + } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if ((conc_connection_list[conn_index].mode == mode) && @@ -2182,6 +2199,7 @@ uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode, count++; } } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return count; } @@ -2201,7 +2219,15 @@ static void cds_store_and_del_conn_info(enum cds_con_mode mode, { uint32_t conn_index = 0; bool found = false; + cds_context_type *cds_ctx; + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return; + } + + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (mode == conc_connection_list[conn_index].mode) { found = true; @@ -2211,12 +2237,14 @@ static void cds_store_and_del_conn_info(enum cds_con_mode mode, } if (!found) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("Mode:%d not available in the conn info", mode); return; } /* Storing the STA entry which will be temporarily deleted */ *info = conc_connection_list[conn_index]; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); /* Deleting the STA entry */ cds_decr_connection_count(info->vdev_id); @@ -2240,6 +2268,13 @@ static void cds_restore_deleted_conn_info( struct cds_conc_connection_info *info) { uint32_t conn_index; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return; + } conn_index = cds_get_connection_count(); if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) { @@ -2248,7 +2283,9 @@ static void cds_restore_deleted_conn_info( return; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); conc_connection_list[conn_index] = *info; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_info("Restored the deleleted conn info, vdev:%d, index:%d", info->vdev_id, conn_index); @@ -2297,8 +2334,8 @@ static void cds_update_hw_mode_conn_info(uint32_t num_vdev_mac_entries, conc_connection_list[conn_index].mac); } } - cds_dump_connection_status_info(); qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + cds_dump_connection_status_info(); } /** @@ -2763,8 +2800,18 @@ static uint32_t cds_dump_current_concurrency_one_connection(char *cc_mode, uint32_t length) { uint32_t count = 0; + enum cds_con_mode mode; + cds_context_type *cds_ctx; - switch (conc_connection_list[0].mode) { + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return count; + } + + mode = conc_connection_list[0].mode; + + switch (mode) { case CDS_STA_MODE: count = strlcat(cc_mode, "STA", length); @@ -2786,7 +2833,7 @@ static uint32_t cds_dump_current_concurrency_one_connection(char *cc_mode, length); break; default: - cds_err("unexpected mode %d", conc_connection_list[0].mode); + cds_err("unexpected mode %d", mode); break; } return count; @@ -2806,8 +2853,18 @@ static uint32_t cds_dump_current_concurrency_two_connection(char *cc_mode, uint32_t length) { uint32_t count = 0; + enum cds_con_mode mode; + cds_context_type *cds_ctx; - switch (conc_connection_list[1].mode) { + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return count; + } + + mode = conc_connection_list[1].mode; + + switch (mode) { case CDS_STA_MODE: count = cds_dump_current_concurrency_one_connection( cc_mode, length); @@ -2839,7 +2896,7 @@ static uint32_t cds_dump_current_concurrency_two_connection(char *cc_mode, length); break; default: - cds_err("unexpected mode %d", conc_connection_list[1].mode); + cds_err("unexpected mode %d", mode); break; } return count; @@ -2859,8 +2916,18 @@ static uint32_t cds_dump_current_concurrency_three_connection(char *cc_mode, uint32_t length) { uint32_t count = 0; + enum cds_con_mode mode; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return count; + } + + mode = conc_connection_list[2].mode; - switch (conc_connection_list[2].mode) { + switch (mode) { case CDS_STA_MODE: count = cds_dump_current_concurrency_two_connection( cc_mode, length); @@ -2892,7 +2959,7 @@ static uint32_t cds_dump_current_concurrency_three_connection(char *cc_mode, length); break; default: - cds_err("unexpected mode %d", conc_connection_list[2].mode); + cds_err("unexpected mode %d", mode); break; } return count; @@ -2911,8 +2978,16 @@ static void cds_dump_dbs_concurrency(char *cc_mode, uint32_t length) { char buf[4] = {0}; uint8_t mac = 0; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return; + } strlcat(cc_mode, " DBS", length); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (conc_connection_list[0].mac == conc_connection_list[1].mac) { if (conc_connection_list[0].chan == @@ -2950,6 +3025,7 @@ static void cds_dump_dbs_concurrency(char *cc_mode, uint32_t length) length); mac = conc_connection_list[1].mac; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); snprintf(buf, sizeof(buf), "%d ", mac); strlcat(cc_mode, buf, length); } @@ -2967,6 +3043,13 @@ static void cds_dump_current_concurrency(void) uint32_t num_connections = 0; char cc_mode[CDS_MAX_CON_STRING_LEN] = {0}; uint32_t count = 0; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return; + } num_connections = cds_get_connection_count(); @@ -2979,6 +3062,7 @@ static void cds_dump_current_concurrency(void) case 2: count = cds_dump_current_concurrency_two_connection( cc_mode, sizeof(cc_mode)); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (conc_connection_list[0].chan == conc_connection_list[1].chan) { strlcat(cc_mode, " SCC", sizeof(cc_mode)); @@ -2987,24 +3071,29 @@ static void cds_dump_current_concurrency(void) strlcat(cc_mode, " MCC", sizeof(cc_mode)); } else strlcat(cc_mode, " DBS", sizeof(cc_mode)); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("%s", cc_mode); break; case 3: count = cds_dump_current_concurrency_three_connection( cc_mode, sizeof(cc_mode)); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if ((conc_connection_list[0].chan == conc_connection_list[1].chan) && (conc_connection_list[0].chan == conc_connection_list[2].chan)){ + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); strlcat(cc_mode, " SCC", sizeof(cc_mode)); } else if ((conc_connection_list[0].mac == conc_connection_list[1].mac) && (conc_connection_list[0].mac == conc_connection_list[2].mac)) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); strlcat(cc_mode, " MCC on single MAC", sizeof(cc_mode)); } else { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_dump_dbs_concurrency(cc_mode, sizeof(cc_mode)); } cds_err("%s", cc_mode); @@ -3084,6 +3173,7 @@ void cds_dump_concurrency_info(void) uint8_t staChannel = 0, p2pChannel = 0, apChannel = 0; const char *p2pMode = "DEV"; hdd_context_t *hdd_ctx; + cds_context_type *cds_ctx; #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL uint8_t targetChannel = 0; uint8_t preAdapterChannel = 0; @@ -3100,6 +3190,12 @@ void cds_dump_concurrency_info(void) return; } + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return; + } + status = hdd_get_front_adapter(hdd_ctx, &adapterNode); while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) { adapter = adapterNode->pAdapter; @@ -3345,7 +3441,9 @@ void cds_dump_concurrency_info(void) status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext); adapterNode = pNext; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); hdd_ctx->mcc_mode = cds_current_concurrency_is_mcc(); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } #ifdef FEATURE_WLAN_TDLS @@ -3671,21 +3769,24 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode, cds_info("No.# of active sessions for mode %d = %d", mode, hdd_ctx->no_of_active_sessions[mode]); - /* * Get PCL logic makes use of the connection info structure. * Let us set the PCL to the FW before updating the connection * info structure about the new connection. */ if (mode == QDF_STA_MODE) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); /* Set PCL of STA to the FW */ cds_pdev_set_pcl(mode); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); cds_info("Set PCL of STA to FW"); } cds_incr_connection_count(session_id); if ((cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_set_pcl_for_existing_combo(CDS_STA_MODE); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); } /* set tdls connection tracker state */ @@ -3711,6 +3812,13 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void) uint8_t mac = 0; struct sir_hw_mode_params hw_mode; QDF_STATUS status = QDF_STATUS_E_FAILURE; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + goto done; + } if (wma_is_hw_dbs_capable() == false) { cds_err("driver isn't dbs capable, no further action needed"); @@ -3727,6 +3835,7 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void) goto done; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); /* Are both mac's still in use */ for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { @@ -3739,13 +3848,17 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void) if ((conc_connection_list[conn_index].mac == 0) && conc_connection_list[conn_index].in_use) { mac |= CDS_MAC0; - if (CDS_MAC0_AND_MAC1 == mac) + if (CDS_MAC0_AND_MAC1 == mac) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); goto done; + } } else if ((conc_connection_list[conn_index].mac == 1) && conc_connection_list[conn_index].in_use) { mac |= CDS_MAC1; - if (CDS_MAC0_AND_MAC1 == mac) + if (CDS_MAC0_AND_MAC1 == mac) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); goto done; + } } } /* Let's request for single MAC mode */ @@ -3756,9 +3869,11 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void) if ((conc_connection_list[conn_index].original_nss == 2) && conc_connection_list[conn_index].in_use) { upgrade = CDS_SINGLE_MAC_UPGRADE; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); goto done; } } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); done: return upgrade; @@ -3792,7 +3907,6 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, cds_info("get pcl for existing conn:%d", mode); - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (cds_mode_specific_connection_count(mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ cds_store_and_del_conn_info(mode, &info); @@ -3802,7 +3916,6 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, /* Restore the connection info */ cds_restore_deleted_conn_info(&info); } - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } @@ -3843,7 +3956,6 @@ void cds_decr_session_set_pcl(enum tQDF_ADAPTER_MODE mode, * given to the FW. After setting the PCL, we need to restore * the entry that we have saved before. */ - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); cds_set_pcl_for_existing_combo(CDS_STA_MODE); /* do we need to change the HW mode */ if (cds_need_opportunistic_upgrade()) { @@ -3856,7 +3968,6 @@ void cds_decr_session_set_pcl(enum tQDF_ADAPTER_MODE mode, if (!QDF_IS_STATUS_SUCCESS(qdf_status)) cds_err("Failed to start dbs opportunistic timer"); } - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return; } @@ -3877,7 +3988,6 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode, uint8_t session_id) { hdd_context_t *hdd_ctx; - cds_context_type *cds_ctx; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -3885,17 +3995,6 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode, return; } - cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); - if (!cds_ctx) { - cds_err("Invalid CDS Context"); - return; - } - - /* - * Need to aquire mutex as entire functionality in this function - * is in critical section - */ - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); switch (mode) { case QDF_STA_MODE: case QDF_P2P_CLIENT_MODE: @@ -3919,7 +4018,6 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode, cds_dump_current_concurrency(); - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } /** @@ -3941,7 +4039,6 @@ static void cds_dbs_opportunistic_timer_handler(void *data) return; } - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); /* if we still need it */ action = cds_need_opportunistic_upgrade(); cds_info("action:%d", action); @@ -3954,7 +4051,6 @@ static void cds_dbs_opportunistic_timer_handler(void *data) cds_next_actions(0, action, SIR_UPDATE_REASON_OPPORTUNISTIC); } - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } @@ -3984,13 +4080,6 @@ QDF_STATUS cds_deinit_policy_mgr(void) QDF_ASSERT(0); } - if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy( - &cds_ctx->qdf_conc_list_lock))) { - cds_err("Failed to destroy qdf_conc_list_lock"); - status = QDF_STATUS_E_FAILURE; - QDF_ASSERT(0); - } - if (QDF_TIMER_STATE_RUNNING == qdf_mc_timer_get_current_state( &cds_ctx->dbs_opportunistic_timer)) { @@ -4047,13 +4136,6 @@ QDF_STATUS cds_init_policy_mgr(struct cds_sme_cbacks *sme_cbacks) /* init conc_connection_list */ qdf_mem_zero(conc_connection_list, sizeof(conc_connection_list)); - if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( - &cds_ctx->qdf_conc_list_lock))) { - cds_err("Failed to init qdf_conc_list_lock"); - /* Lets us not proceed further */ - return QDF_STATUS_E_FAILURE; - } - sme_register_hw_mode_trans_cb(hdd_ctx->hHal, cds_hw_mode_transition_cb); status = qdf_mc_timer_init(&cds_ctx->dbs_opportunistic_timer, @@ -4097,6 +4179,14 @@ QDF_STATUS cds_init_policy_mgr(struct cds_sme_cbacks *sme_cbacks) static uint32_t cds_get_connection_for_vdev_id(uint32_t vdev_id) { uint32_t conn_index = 0; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return conn_index; + } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if ((conc_connection_list[conn_index].vdev_id == vdev_id) && @@ -4104,6 +4194,7 @@ static uint32_t cds_get_connection_for_vdev_id(uint32_t vdev_id) break; } } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return conn_index; } @@ -4317,9 +4408,9 @@ QDF_STATUS cds_update_connection_info(uint32_t vdev_id) } conn_index++; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); if (!found) { /* err msg */ - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("can't find vdev_id %d in conc_connection_list", vdev_id); return status; @@ -4329,7 +4420,6 @@ QDF_STATUS cds_update_connection_info(uint32_t vdev_id) if (NULL == wma_conn_table_entry) { /* err msg*/ - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("can't find vdev_id %d in WMA table", vdev_id); return status; } @@ -4358,7 +4448,6 @@ QDF_STATUS cds_update_connection_info(uint32_t vdev_id) wma_conn_table_entry->mac_id, chain_mask, nss, vdev_id, true); - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return QDF_STATUS_SUCCESS; } @@ -4378,7 +4467,15 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id) QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t conn_index = 0, next_conn_index = 0; bool found = false; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return status; + } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (vdev_id == conc_connection_list[conn_index].vdev_id) { /* debug msg */ @@ -4390,6 +4487,7 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id) if (!found) { cds_err("can't find vdev_id %d in conc_connection_list", vdev_id); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } next_conn_index = conn_index + 1; @@ -4417,6 +4515,7 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id) /* clean up the entry */ qdf_mem_zero(&conc_connection_list[next_conn_index - 1], sizeof(*conc_connection_list)); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return QDF_STATUS_SUCCESS; } @@ -4449,6 +4548,13 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t conn_index = 0, num_channels = 0; uint32_t weight1, weight2; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return status; + } if ((NULL == channels) || (NULL == len)) { cds_err("channels or len is NULL"); @@ -4481,6 +4587,7 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (CDS_PCL_ORDER_NONE == order) { while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && CDS_IS_DFS_CH( @@ -4555,6 +4662,7 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, cds_err("unknown order %d", order); status = QDF_STATUS_E_FAILURE; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } @@ -5010,6 +5118,14 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, uint8_t cds_get_channel(enum cds_con_mode mode, uint32_t *vdev_id) { uint32_t idx = 0; + uint8_t chan; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return 0; + } if (mode >= CDS_MAX_NUM_OF_MODE) { cds_err("incorrect mode"); @@ -5017,11 +5133,16 @@ uint8_t cds_get_channel(enum cds_con_mode mode, uint32_t *vdev_id) } for (idx = 0; idx < MAX_NUMBER_OF_CONC_CONNECTIONS; idx++) { + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if ((conc_connection_list[idx].mode == mode) && (!vdev_id || (*vdev_id == conc_connection_list[idx].vdev_id)) - && conc_connection_list[idx].in_use) - return conc_connection_list[idx].chan; + && conc_connection_list[idx].in_use) { + chan = conc_connection_list[idx].chan; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + return chan; + } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } return 0; } @@ -5177,6 +5298,14 @@ static bool cds_disallow_mcc(uint8_t channel) { uint32_t index = 0; bool match = false; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return match; + } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); while (CONC_CONNECTION_LIST_VALID_INDEX(index)) { if (wma_is_hw_dbs_capable() == false) { if (conc_connection_list[index].chan != @@ -5193,6 +5322,7 @@ static bool cds_disallow_mcc(uint8_t channel) } index++; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return match; } @@ -5212,7 +5342,15 @@ static bool cds_allow_new_home_channel(uint8_t channel, uint32_t num_connections) { bool status = true; + cds_context_type *cds_ctx; + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return false; + } + + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if ((num_connections == 2) && (conc_connection_list[0].chan != conc_connection_list[1].chan) && @@ -5237,6 +5375,7 @@ static bool cds_allow_new_home_channel(uint8_t channel, status = false; } } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } @@ -5256,11 +5395,19 @@ bool cds_is_ibss_conn_exist(uint8_t *ibss_channel) uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; bool status = false; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return status; + } if (NULL == ibss_channel) { cds_err("Null pointer error"); return false; } count = cds_mode_specific_connection_count(CDS_IBSS_MODE, list); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (count == 0) { /* No IBSS connection */ status = false; @@ -5272,6 +5419,7 @@ bool cds_is_ibss_conn_exist(uint8_t *ibss_channel) cds_notice("Multiple IBSS connections, picking first one"); status = true; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } @@ -5288,7 +5436,15 @@ static bool cds_vht160_conn_exist(void) { uint32_t conn_index; bool status = false; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return status; + } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if (conc_connection_list[conn_index].in_use && @@ -5300,6 +5456,7 @@ static bool cds_vht160_conn_exist(void) break; } } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } @@ -5322,17 +5479,27 @@ static bool cds_is_5g_channel_allowed(uint8_t channel, uint32_t *list, enum cds_con_mode mode) { uint32_t index = 0, count = 0; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return false; + } count = cds_mode_specific_connection_count(mode, list); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); while (index < count) { if (CDS_IS_DFS_CH(conc_connection_list[list[index]].chan) && CDS_IS_CHANNEL_5GHZ(channel) && (channel != conc_connection_list[list[index]].chan)) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("don't allow MCC if SAP/GO on DFS channel"); return false; } index++; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return true; } @@ -5373,7 +5540,6 @@ bool cds_allow_concurrency(enum cds_con_mode mode, return status; } - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); qdf_mem_zero(&pcl, sizeof(pcl)); ret = cds_get_pcl(mode, pcl.pcl_list, &pcl.pcl_len, @@ -5452,8 +5618,10 @@ bool cds_allow_concurrency(enum cds_con_mode mode, cds_err("No IBSS, we have concurrent connections already"); goto done; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (CDS_STA_MODE != conc_connection_list[0].mode) { cds_err("No IBSS, we've a non-STA connection"); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); goto done; } /* @@ -5465,9 +5633,11 @@ bool cds_allow_concurrency(enum cds_con_mode mode, (conc_connection_list[0].chan != channel) && CDS_IS_SAME_BAND_CHANNELS( conc_connection_list[0].chan, channel)) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("No IBSS + STA MCC"); goto done; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } else if (num_connections) { cds_err("No IBSS, we have one connection already"); goto done; @@ -5488,9 +5658,11 @@ bool cds_allow_concurrency(enum cds_con_mode mode, cds_err("No 2nd STA, we already have IBSS concurrency"); goto done; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (channel && (CDS_IS_DFS_CH(conc_connection_list[0].chan)) && (CDS_IS_CHANNEL_5GHZ(channel))) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel"); goto done; } @@ -5503,8 +5675,10 @@ bool cds_allow_concurrency(enum cds_con_mode mode, CDS_IS_SAME_BAND_CHANNELS( conc_connection_list[0].chan, channel)) { cds_err("No IBSS + STA MCC"); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); goto done; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } else { cds_err("No STA, we have IBSS connection already"); goto done; @@ -5516,14 +5690,17 @@ bool cds_allow_concurrency(enum cds_con_mode mode, index = 0; count = cds_mode_specific_connection_count( CDS_P2P_GO_MODE, list); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); while (index < count) { if (CDS_IS_SAME_BAND_CHANNELS(channel, conc_connection_list[list[index]].chan)) { cds_err("Don't allow P2P GO on same band"); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); goto done; } index++; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } /* don't allow concurrency on vht160 or vht 80+80 */ @@ -5543,7 +5720,6 @@ bool cds_allow_concurrency(enum cds_con_mode mode, status = true; done: - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } @@ -5587,7 +5763,15 @@ 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_one_connection_mode index = CDS_MAX_ONE_CONNECTION_MODE; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return index; + } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (CDS_STA_MODE == conc_connection_list[0].mode) { if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) { if (CDS_ONE_ONE == conc_connection_list[0].chain_mask) @@ -5654,6 +5838,7 @@ enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(void) conc_connection_list[0].mode, conc_connection_list[0].chan, conc_connection_list[0].chain_mask, index); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return index; } @@ -5672,7 +5857,15 @@ 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) { enum cds_one_connection_mode index = CDS_MAX_TWO_CONNECTION_MODE; + cds_context_type *cds_ctx; + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return index; + } + + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); /* P2P Client + SAP */ if (((CDS_P2P_CLIENT_MODE == conc_connection_list[0].mode) && (CDS_SAP_MODE == conc_connection_list[1].mode)) || @@ -5999,6 +6192,7 @@ enum cds_two_connection_mode cds_get_third_connection_pcl_table_index(void) conc_connection_list[0].chan, conc_connection_list[1].chan, conc_connection_list[0].chain_mask, index); + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return index; } @@ -6093,7 +6287,6 @@ QDF_STATUS cds_current_connections_update(uint32_t session_id, else band = CDS_BAND_5; - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); num_connections = cds_get_connection_count(); cds_debug("num_connections=%d channel=%d", @@ -6139,7 +6332,6 @@ QDF_STATUS cds_current_connections_update(uint32_t session_id, reason, session_id); done: - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return status; } @@ -6178,17 +6370,14 @@ static void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id, /* * Check if we are ok to request for HW mode change now */ - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); conn_index = cds_get_connection_for_vdev_id(vdev_id); if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("connection not found for vdev %d", vdev_id); return; } cds_debug("nss update successful for vdev:%d", vdev_id); cds_next_actions(vdev_id, next_action, reason); - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return; } @@ -6217,6 +6406,15 @@ static QDF_STATUS cds_complete_action(uint8_t new_nss, uint8_t next_action, uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint32_t conn_index = 0; hdd_context_t *hdd_ctx; + uint32_t vdev_id; + uint32_t original_nss; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return status; + } hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -6237,23 +6435,25 @@ static QDF_STATUS cds_complete_action(uint8_t new_nss, uint8_t next_action, count = cds_mode_specific_connection_count( CDS_P2P_GO_MODE, list); for (index = 0; index < count; index++) { - conn_index = cds_get_connection_for_vdev_id( - conc_connection_list[list[index]].vdev_id); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); + vdev_id = conc_connection_list[list[index]].vdev_id; + original_nss = conc_connection_list[list[index]].original_nss; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + conn_index = cds_get_connection_for_vdev_id(vdev_id); if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { cds_err("connection not found for vdev %d", - conc_connection_list[list[index]].vdev_id); + vdev_id); continue; } - if (2 == conc_connection_list[list[index]].original_nss) { + if (2 == original_nss) { status = sme_nss_update_request(hdd_ctx->hHal, - conc_connection_list - [list[index]].vdev_id, new_nss, + vdev_id, new_nss, cds_nss_update_cb, next_action, hdd_ctx, reason); if (!QDF_IS_STATUS_SUCCESS(status)) { cds_err("sme_nss_update_request() failed for vdev %d", - conc_connection_list[list[index]].vdev_id); + vdev_id); } } } @@ -6261,22 +6461,24 @@ static QDF_STATUS cds_complete_action(uint8_t new_nss, uint8_t next_action, count = cds_mode_specific_connection_count( CDS_SAP_MODE, list); for (index = 0; index < count; index++) { - conn_index = cds_get_connection_for_vdev_id( - conc_connection_list[list[index]].vdev_id); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); + vdev_id = conc_connection_list[list[index]].vdev_id; + original_nss = conc_connection_list[list[index]].original_nss; + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + conn_index = cds_get_connection_for_vdev_id(vdev_id); if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { cds_err("connection not found for vdev %d", - conc_connection_list[list[index]].vdev_id); + vdev_id); continue; } - if (2 == conc_connection_list[list[index]].original_nss) { + if (2 == original_nss) { status = sme_nss_update_request(hdd_ctx->hHal, - conc_connection_list - [list[index]].vdev_id, new_nss, + vdev_id, new_nss, cds_nss_update_cb, next_action, hdd_ctx, reason); if (!QDF_IS_STATUS_SUCCESS(status)) { cds_err("sme_nss_update_request() failed for vdev %d", - conc_connection_list[list[index]].vdev_id); + vdev_id); } } } @@ -7739,9 +7941,9 @@ QDF_STATUS cds_update_connection_info_utfw( } conn_index++; } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); if (!found) { /* err msg */ - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("can't find vdev_id %d in conc_connection_list", vdev_id); return status; @@ -7752,7 +7954,6 @@ QDF_STATUS cds_update_connection_info_utfw( cds_get_mode(type, sub_type), channelid, HW_MODE_20_MHZ, mac_id, chain_mask, 0, vdev_id, true); - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return QDF_STATUS_SUCCESS; } @@ -7779,11 +7980,9 @@ QDF_STATUS cds_incr_connection_count_utfw( return status; } - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); conn_index = cds_get_connection_count(); if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) { /* err msg */ - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_err("exceeded max connection limit %d", MAX_NUMBER_OF_CONC_CONNECTIONS); return status; @@ -7794,7 +7993,6 @@ QDF_STATUS cds_incr_connection_count_utfw( cds_get_mode(type, sub_type), channelid, HW_MODE_20_MHZ, mac_id, chain_mask, 0, vdev_id, true); - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); return QDF_STATUS_SUCCESS; } @@ -7821,9 +8019,7 @@ QDF_STATUS cds_decr_connection_count_utfw(uint32_t del_all, return QDF_STATUS_E_FAILURE; } } else { - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); cds_decr_connection_count(vdev_id); - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } return QDF_STATUS_SUCCESS; @@ -8193,6 +8389,14 @@ static enum cds_conc_next_action cds_get_current_pref_hw_mode(void) struct sir_hw_mode_params hw_mode; QDF_STATUS status; hdd_context_t *hdd_ctx; + enum cds_conc_next_action next_action; + cds_context_type *cds_ctx; + + cds_ctx = cds_get_context(QDF_MODULE_ID_QDF); + if (!cds_ctx) { + cds_err("Invalid CDS Context"); + return CDS_NOP; + } hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -8208,6 +8412,7 @@ static enum cds_conc_next_action cds_get_current_pref_hw_mode(void) num_connections = cds_get_connection_count(); + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); cds_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d", conc_connection_list[0].chan, conc_connection_list[1].chan, conc_connection_list[2].chan, num_connections, hw_mode.dbs_cap); @@ -8218,34 +8423,45 @@ static enum cds_conc_next_action cds_get_current_pref_hw_mode(void) switch (num_connections) { case 1: /* The driver would already be in the required hw mode */ - return CDS_NOP; + next_action = CDS_NOP; + break; case 2: band1 = cds_chan_to_band(conc_connection_list[0].chan); band2 = cds_chan_to_band(conc_connection_list[1].chan); if ((band1 == band2) && (hw_mode.dbs_cap)) - return CDS_SINGLE_MAC_UPGRADE; + next_action = CDS_SINGLE_MAC_UPGRADE; else if ((band1 != band2) && (!hw_mode.dbs_cap)) - return CDS_DBS_DOWNGRADE; + next_action = CDS_DBS_DOWNGRADE; else - return CDS_NOP; + next_action = CDS_NOP; + + break; case 3: band1 = cds_chan_to_band(conc_connection_list[0].chan); band2 = cds_chan_to_band(conc_connection_list[1].chan); band3 = cds_chan_to_band(conc_connection_list[2].chan); if (((band1 == band2) && (band2 == band3)) && - (hw_mode.dbs_cap)) - return CDS_SINGLE_MAC_UPGRADE; - else if (((band1 != band2) || (band2 != band3) || - (band1 != band3)) && (!hw_mode.dbs_cap)) - return CDS_DBS_DOWNGRADE; - else - return CDS_NOP; + (hw_mode.dbs_cap)) { + next_action = CDS_SINGLE_MAC_UPGRADE; + } else if (((band1 != band2) || (band2 != band3) || + (band1 != band3)) && + (!hw_mode.dbs_cap)) { + next_action = CDS_DBS_DOWNGRADE; + } else { + next_action = CDS_NOP; + } + break; default: cds_err("unexpected num_connections value %d", num_connections); - return CDS_NOP; + next_action = CDS_NOP; + break; } + + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); + return next_action; + } /** @@ -8815,7 +9031,6 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight) qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN, WEIGHT_OF_DISALLOWED_CHANNELS); - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); if (cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0) { /* * Store the STA mode's parameter and temporarily delete it @@ -8824,7 +9039,6 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight) * allowing to detect the disallowed channels. */ cds_store_and_del_conn_info(CDS_STA_MODE, &info); - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); /* * There is a small window between releasing the above lock * and acquiring the same in cds_allow_concurrency, below! @@ -8838,11 +9052,9 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight) } } - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); /* Restore the connection info */ cds_restore_deleted_conn_info(&info); } - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); for (i = 0; i < weight->saved_num_chan; i++) { for (j = 0; j < weight->pcl_len; j++) { @@ -8890,8 +9102,6 @@ QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id) return status; } - qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); - action = cds_get_current_pref_hw_mode(); if ((action != CDS_DBS_DOWNGRADE) && @@ -8926,7 +9136,6 @@ QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id) goto done; } done: - qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); /* success must be returned only when a set hw mode was done */ return status; } @@ -8950,6 +9159,7 @@ void cds_dump_connection_status_info(void) return; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { cds_debug("%d: use:%d vdev:%d mode:%d mac:%d chan:%d orig chainmask:%d orig nss:%d bw:%d", i, conc_connection_list[i].in_use, @@ -8961,6 +9171,7 @@ void cds_dump_connection_status_info(void) conc_connection_list[i].original_nss, conc_connection_list[i].bw); } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); } /** @@ -9160,14 +9371,17 @@ void cds_checkn_update_hw_mode_single_mac_mode(uint8_t channel) return; } + qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { if (conc_connection_list[i].in_use) if (!CDS_IS_SAME_BAND_CHANNELS(channel, conc_connection_list[i].chan)) { + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); cds_info("DBS required"); return; } } + qdf_mutex_release(&cds_ctx->qdf_conc_list_lock); if (QDF_TIMER_STATE_RUNNING == cds_ctx->dbs_opportunistic_timer.state) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index fb95d3be3e45..9c5d3bc2b7c3 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -6437,7 +6437,7 @@ nla_put_failure: static int hdd_get_bpf_offload(hdd_context_t *hdd_ctx) { unsigned long rc; - struct hdd_bpf_context *context; + static struct hdd_bpf_context *context; QDF_STATUS status; int ret; diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c index 5140ad92c132..b389d4edd310 100644 --- a/core/hdd/src/wlan_hdd_ext_scan.c +++ b/core/hdd/src/wlan_hdd_ext_scan.c @@ -2549,6 +2549,13 @@ __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy, maxChannels = nla_get_u32(tb [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]); + + if (maxChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) { + hdd_err("Max channels %d exceeded Valid channel list len %d", + maxChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN); + return -EINVAL; + } + hdd_notice("Req Id: %u Wifi band: %d Max channels: %d", requestId, wifiBand, maxChannels); status = sme_get_valid_channels_by_band((tHalHandle) (pHddCtx->hHal), diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index b12f4cba749c..683b17a8c5f3 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -198,7 +198,7 @@ QDF_STATUS hdd_get_tsm_stats(hdd_adapter_t *adapter, QDF_STATUS hstatus; QDF_STATUS vstatus = QDF_STATUS_SUCCESS; unsigned long rc; - struct statsContext context; + static struct statsContext context; hdd_context_t *hdd_ctx = NULL; if (NULL == adapter) { @@ -2422,7 +2422,7 @@ static int wlan_hdd_get_link_status(hdd_adapter_t *adapter) hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct statsContext context; + static struct statsContext context; QDF_STATUS hstatus; unsigned long rc; diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index b42df3a390ea..5f4703e07178 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -1608,6 +1608,13 @@ static void hdd_ipa_uc_offload_enable_disable(hdd_adapter_t *adapter, return; } + if (wlan_hdd_validate_session_id(adapter->sessionId)) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, + "invalid session id: %d, offload_type=%d, enable=%d", + adapter->sessionId, offload_type, enable); + return; + } + qdf_mem_zero(&ipa_offload_enable_disable, sizeof(ipa_offload_enable_disable)); ipa_offload_enable_disable.offload_type = offload_type; @@ -1876,6 +1883,97 @@ void hdd_ipa_uc_force_pipe_shutdown(hdd_context_t *hdd_ctx) } /** + * hdd_ipa_msg_free_fn() - Free an IPA message + * @buff: pointer to the IPA message + * @len: length of the IPA message + * @type: type of IPA message + * + * Return: None + */ +static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type) +{ + HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "msg type:%d, len:%d", type, len); + ghdd_ipa->stats.num_free_msg++; + qdf_mem_free(buff); +} + + +/** + * hdd_ipa_send_disconnect() - ipa send disconnect clients + * adapter: pointer to hdd adapter + * Send disconnect evnt to IPA driver during SSR + * + * Return: 0 - Success + */ +static int hdd_ipa_send_disconnect(hdd_adapter_t *adapter) +{ + struct ipa_msg_meta meta; + struct ipa_wlan_msg *msg; + int ret = 0; + int i; + + for (i = 0; i < WLAN_MAX_STA_COUNT; i++) { + if (qdf_is_macaddr_broadcast(&adapter->aStaInfo[i].macAddrSTA)) + continue; + if ((adapter->aStaInfo[i].isUsed) && + (!adapter->aStaInfo[i].isDeauthInProgress)) { + meta.msg_len = sizeof(struct ipa_wlan_msg); + msg = qdf_mem_malloc(meta.msg_len); + if (msg == NULL) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, + "msg allocation failed"); + return -ENOMEM; + } + meta.msg_type = WLAN_CLIENT_DISCONNECT; + strlcpy(msg->name, adapter->dev->name, + IPA_RESOURCE_NAME_MAX); + memcpy(msg->mac_addr, adapter->aStaInfo[i].macAddrSTA.bytes, + ETH_ALEN); + HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d", + msg->name, meta.msg_type); + ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn); + if (ret) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, + "%s: Evt: %d fail:%d", + msg->name, meta.msg_type, ret); + qdf_mem_free(msg); + return ret; + } + } + } + + return ret; +} + +/** + * hdd_ipa_uc_disconnect_client() - disconnect ipa sap clients + * hdd_ctx: pointer to hdd context + * Send disconnect evnt to IPA driver during SSR + * + * Return: 0 - Success + */ +static int hdd_ipa_uc_disconnect_client(hdd_context_t *hdd_ctx) +{ + hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL; + QDF_STATUS status; + hdd_adapter_t *adapter; + int ret = 0; + + + status = hdd_get_front_adapter(hdd_ctx, &adapter_node); + while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (adapter->device_mode == QDF_SAP_MODE) + hdd_ipa_send_disconnect(adapter); + status = hdd_get_next_adapter( + hdd_ctx, adapter_node, &next); + adapter_node = next; + } + + return ret; +} + +/** * hdd_ipa_uc_ssr_deinit() - handle ipa deinit for SSR * * Deinit basic IPA UC host side to be in sync reloaded FW during @@ -1892,6 +1990,8 @@ int hdd_ipa_uc_ssr_deinit(void) if ((!hdd_ipa) || (!hdd_ipa_uc_is_enabled(hdd_ipa->hdd_ctx))) return 0; + /* send disconnect to ipa driver for connected clients */ + hdd_ipa_uc_disconnect_client(hdd_ipa->hdd_ctx); /* Clean up HDD IPA interfaces */ for (idx = 0; (hdd_ipa->num_iface > 0) && (idx < HDD_IPA_MAX_IFACE); idx++) { @@ -3537,21 +3637,6 @@ end: return ret; } -/** - * hdd_ipa_msg_free_fn() - Free an IPA message - * @buff: pointer to the IPA message - * @len: length of the IPA message - * @type: type of IPA message - * - * Return: None - */ -static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type) -{ - hddLog(LOG1, "msg type:%d, len:%d", type, len); - ghdd_ipa->stats.num_free_msg++; - qdf_mem_free(buff); -} - #ifndef QCA_LL_TX_FLOW_CONTROL_V2 /** * hdd_ipa_send_mcc_scc_msg() - send IPA WLAN_SWITCH_TO_MCC/SCC message @@ -3834,7 +3919,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, if (ret) { HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d, Interface setup failed", - msg_ex->name, meta.msg_type); + adapter->dev->name, type); qdf_mutex_release(&hdd_ipa->event_lock); goto end; } @@ -3859,7 +3944,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, if (!hdd_ipa->sta_connected) { HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d, STA already disconnected", - msg_ex->name, meta.msg_type); + adapter->dev->name, type); qdf_mutex_release(&hdd_ipa->event_lock); return -EINVAL; } @@ -3898,7 +3983,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, if (!adapter->ipa_context) { HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d, SAP already disconnected", - msg_ex->name, meta.msg_type); + adapter->dev->name, type); qdf_mutex_release(&hdd_ipa->event_lock); return -EINVAL; } @@ -3938,7 +4023,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, if (!hdd_ipa_uc_is_enabled(hdd_ipa->hdd_ctx)) { HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED", - adapter->dev->name, meta.msg_type); + adapter->dev->name, type); return 0; } @@ -4019,7 +4104,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, if (ret) { HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d : %d", - msg_ex->name, meta.msg_type, ret); + adapter->dev->name, type, ret); qdf_mem_free(msg_ex); return ret; } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index e5c6d9f993e1..5ba5817050b0 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -7852,9 +7852,17 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx) goto done; } + qdf_status = cds_post_disable(hdd_ctx->pcds_context); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + hdd_err("Failed to process post CDS disable Modules! :%d", + qdf_status); + ret = -EINVAL; + QDF_ASSERT(0); + } qdf_status = cds_close(hdd_ctx->pcds_context); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_warn("Failed to stop CDS:%d", qdf_status); + ret = -EINVAL; QDF_ASSERT(0); } /* Clean up message queues of TX, RX and MC thread */ diff --git a/core/hdd/src/wlan_hdd_memdump.c b/core/hdd/src/wlan_hdd_memdump.c index 195d066018b2..b8765153d373 100644 --- a/core/hdd/src/wlan_hdd_memdump.c +++ b/core/hdd/src/wlan_hdd_memdump.c @@ -242,6 +242,8 @@ static int __wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy, return -ENOMEM; } hdd_ctx->dump_loc_paddr = paddr; + } else { + paddr = hdd_ctx->dump_loc_paddr; } mutex_unlock(&hdd_ctx->memdump_lock); diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 199fc4668d5b..f056d383937a 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1461,6 +1461,7 @@ QDF_STATUS hdd_wlan_shutdown(void) cds_clear_concurrent_session_count(); hdd_cleanup_scan_queue(pHddCtx); + hdd_ipa_uc_ssr_deinit(); hdd_reset_all_adapters(pHddCtx); /* Flush cached rx frame queue */ @@ -1468,7 +1469,6 @@ QDF_STATUS hdd_wlan_shutdown(void) /* De-register the HDD callbacks */ hdd_deregister_cb(pHddCtx); - hdd_ipa_uc_ssr_deinit(); cds_sched_context = get_cds_sched_ctxt(); diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index ff756b89f10b..cffa762b6476 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -1222,7 +1222,7 @@ static void hdd_get_snr_cb(int8_t snr, uint32_t staId, void *pContext) */ QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value) { - struct statsContext context; + static struct statsContext context; hdd_context_t *pHddCtx; hdd_station_ctx_t *pHddStaCtx; QDF_STATUS hstatus; @@ -1308,7 +1308,7 @@ QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value) */ QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr) { - struct statsContext context; + static struct statsContext context; hdd_context_t *pHddCtx; hdd_station_ctx_t *pHddStaCtx; QDF_STATUS hstatus; @@ -1455,7 +1455,7 @@ QDF_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter, struct qdf_mac_addr macAddress) { QDF_STATUS status; unsigned long rc; - struct linkspeedContext context; + static struct linkspeedContext context; tSirLinkSpeedInfo *linkspeed_req; if (NULL == pAdapter) { @@ -3649,7 +3649,7 @@ QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter) hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); QDF_STATUS hstatus; unsigned long rc; - struct statsContext context; + static struct statsContext context; if (NULL == pAdapter) { hdd_err("pAdapter is NULL"); @@ -5138,7 +5138,7 @@ static void hdd_get_temperature_cb(int temperature, void *pContext) int wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, int *temperature) { QDF_STATUS status; - struct statsContext tempContext; + static struct statsContext tempContext; unsigned long rc; ENTER(); diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index b5f90d497a4b..547c64d223e0 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -41,9 +41,9 @@ #define QWLAN_VERSION_MAJOR 5 #define QWLAN_VERSION_MINOR 1 #define QWLAN_VERSION_PATCH 0 -#define QWLAN_VERSION_EXTRA "B" +#define QWLAN_VERSION_EXTRA "N" #define QWLAN_VERSION_BUILD 36 -#define QWLAN_VERSIONSTR "5.1.0.36B" +#define QWLAN_VERSIONSTR "5.1.0.36N" #endif /* QWLAN_VERSION_H */ diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index abf78f39bea7..79657e25cdca 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -455,10 +455,6 @@ #define SIR_MAC_CISCO_OUI "\x00\x40\x96" #define SIR_MAC_CISCO_OUI_SIZE 3 -/* WFA vendor specific TPC OUI */ -#define SIR_MAC_WFA_TPC_OUI "\x00\x50\xF2\x08\x00" -#define SIR_MAC_WFA_TPC_OUI_SIZE 5 - /* min size of wme oui header: oui(3) + type + subtype + version */ #define SIR_MAC_OUI_WME_HDR_MIN 6 diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c index d2889095b1b9..d25e61e2c4f1 100644 --- a/core/mac/src/pe/lim/lim_process_action_frame.c +++ b/core/mac/src/pe/lim/lim_process_action_frame.c @@ -60,6 +60,8 @@ #define BA_DEFAULT_TX_BUFFER_SIZE 64 +static last_processed_msg rrm_link_action_frm; + /* Note: The test passes if the STAUT stops sending any frames, and no further frames are transmitted on this channel by the station when the AP has sent the last 6 beacons, with the channel switch information elements as seen @@ -1406,7 +1408,7 @@ err: qdf_mem_free(frm); } -static void +static tSirRetStatus __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, tpPESession psessionEntry) { @@ -1420,7 +1422,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); if (psessionEntry == NULL) { - return; + return eSIR_FAILURE; } /**Unpack the received frame */ @@ -1435,7 +1437,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, PELOG2(sir_dump_buf (pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen); ) - return; + return eSIR_FAILURE; } else if (DOT11F_WARNED(nStatus)) { lim_log(pMac, LOGW, FL @@ -1447,7 +1449,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, } /* Call rrm function to handle the request. */ - rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm, + return rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm, psessionEntry); } @@ -1912,9 +1914,19 @@ void lim_process_action_frame(tpAniSirGlobal mac_ctx, session); break; case SIR_MAC_RRM_LINK_MEASUREMENT_REQ: - __lim_process_link_measurement_req(mac_ctx, + if (!lim_is_valid_frame( + &rrm_link_action_frm, + rx_pkt_info)) + break; + + if (__lim_process_link_measurement_req( + mac_ctx, (uint8_t *)rx_pkt_info, - session); + session) == eSIR_SUCCESS) + lim_update_last_processed_frame( + &rrm_link_action_frm, + rx_pkt_info); + break; case SIR_MAC_RRM_NEIGHBOR_RPT: __lim_process_neighbor_report(mac_ctx, diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 2343bdd28cb9..fcf99578396b 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -1229,13 +1229,9 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac, tSirMsgQ msg; uint16_t i, len; uint16_t addn_ie_len = 0; - uint8_t *vendor_tpc_ie; tSirRetStatus status, rc = eSIR_SUCCESS; tDot11fIEExtCap extracted_extcap = {0}; bool extcap_present = true; - uint32_t lim_11h_enable = WNI_CFG_11H_ENABLED_STADEF; - - wlan_cfg_get_int(pMac, WNI_CFG_11H_ENABLED, &lim_11h_enable); if (pScanReq->uIEFieldLen) { status = lim_strip_extcap_update_struct(pMac, @@ -1266,10 +1262,6 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac, len = sizeof(tSirScanOffloadReq) + (pScanReq->channelList.numChannels - 1) + pScanReq->uIEFieldLen; - if (lim_11h_enable) { - addn_ie_len += DOT11F_IE_WFATPC_MAX_LEN + 2; - len += DOT11F_IE_WFATPC_MAX_LEN + 2; - } pScanOffloadReq = qdf_mem_malloc(len); if (NULL == pScanOffloadReq) { @@ -1342,30 +1334,6 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac, (uint8_t *) pScanReq + pScanReq->uIEFieldOffset, pScanReq->uIEFieldLen); - if (lim_11h_enable) { - tDot11fIEWFATPC wfa_tpc; - vendor_tpc_ie = (uint8_t *) pScanOffloadReq + - pScanOffloadReq->uIEFieldOffset + - pScanOffloadReq->uIEFieldLen; - populate_dot11f_wfatpc(pMac, &wfa_tpc, - rrm_get_mgmt_tx_power(pMac, NULL), 0); - vendor_tpc_ie[0] = DOT11F_EID_WFATPC; - vendor_tpc_ie[1] = DOT11F_IE_WFATPC_MAX_LEN; - qdf_mem_copy(&vendor_tpc_ie[2], SIR_MAC_WFA_TPC_OUI, - SIR_MAC_WFA_TPC_OUI_SIZE); - qdf_mem_copy(&vendor_tpc_ie[SIR_MAC_WFA_TPC_OUI_SIZE + 2], - ((uint8_t *)&wfa_tpc) + 1, - DOT11F_IE_WFATPC_MAX_LEN - SIR_MAC_WFA_TPC_OUI_SIZE); - pScanOffloadReq->uIEFieldLen += DOT11F_IE_WFATPC_MAX_LEN + 2; - if (pScanReq->uIEFieldLen) - lim_strip_ie(pMac, - (uint8_t *) pScanReq + pScanReq->uIEFieldOffset, - &pScanReq->uIEFieldLen, - DOT11F_EID_WFATPC, ONE_BYTE, - SIR_MAC_WFA_TPC_OUI, SIR_MAC_WFA_TPC_OUI_SIZE, - NULL); - } - rc = wma_post_ctrl_msg(pMac, &msg); if (rc != eSIR_SUCCESS) { lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure")); diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 0518ae8fe92d..ba731b8ff299 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -7218,3 +7218,76 @@ void lim_send_set_dtim_period(tpAniSirGlobal mac_ctx, uint8_t dtim_period, qdf_mem_free(dtim_params); } } + +/** + * lim_is_valid_frame(): validate RX frame using last processed frame details + * to find if it is duplicate frame. + * + * @last_processed_frm: last processed frame pointer. + * @pRxPacketInfo: RX packet. + * + * Frame treat as duplicate: + * if retry bit is set and + * if source address and seq number matches with the last processed frame + * + * Return: false if duplicate frame, else true. + */ +bool lim_is_valid_frame(last_processed_msg *last_processed_frm, + uint8_t *pRxPacketInfo) +{ + uint16_t seq_num; + tpSirMacMgmtHdr pHdr; + + if (!pRxPacketInfo) { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, + FL("Invalid RX frame")); + return false; + } + + pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo); + + if (pHdr->fc.retry == 0) + return true; + + seq_num = (((pHdr->seqControl.seqNumHi << + HIGH_SEQ_NUM_OFFSET) | + pHdr->seqControl.seqNumLo)); + + if (last_processed_frm->seq_num == seq_num && + qdf_mem_cmp(last_processed_frm->sa, pHdr->sa, ETH_ALEN) == 0) { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, + FL("Duplicate frame from "MAC_ADDRESS_STR " Seq Number %d"), + MAC_ADDR_ARRAY(pHdr->sa), seq_num); + return false; + } + return true; +} + +/** + * lim_update_last_processed_frame(): update new processed frame info to cache. + * + * @last_processed_frm: last processed frame pointer. + * @pRxPacketInfo: Successfully processed RX packet. + * + * Return: None. + */ +void lim_update_last_processed_frame(last_processed_msg *last_processed_frm, + uint8_t *pRxPacketInfo) +{ + uint16_t seq_num; + tpSirMacMgmtHdr pHdr; + + if (!pRxPacketInfo) { + QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR, + FL("Invalid RX frame")); + return; + } + + pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo); + seq_num = (((pHdr->seqControl.seqNumHi << + HIGH_SEQ_NUM_OFFSET) | + pHdr->seqControl.seqNumLo)); + + qdf_mem_copy(last_processed_frm->sa, pHdr->sa, ETH_ALEN); + last_processed_frm->seq_num = seq_num; +} diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index 5ad6bd0921e4..5c6d26b57fa7 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -79,7 +79,16 @@ typedef union uPmfSaQueryTimerId { } tPmfSaQueryTimerId, *tpPmfSaQueryTimerId; #endif +typedef struct last_processed_frame { + tSirMacAddr sa; + uint16_t seq_num; +} last_processed_msg; + /* LIM utility functions */ +bool lim_is_valid_frame(last_processed_msg *last_processed_frm, + uint8_t *pRxPacketInfo); +void lim_update_last_processed_frame(last_processed_msg *last_processed_frm, + uint8_t *pRxPacketInfo); void limGetBssidFromPkt(tpAniSirGlobal, uint8_t *, uint8_t *, uint32_t *); char *lim_dot11_reason_str(uint16_t reasonCode); char *lim_mlm_state_str(tLimMlmStates state); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index cbb373b7f91e..741ae26eb185 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2294,14 +2294,22 @@ QDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal, { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); QDF_STATUS status = QDF_STATUS_SUCCESS; - tpCsrNeighborRoamControlInfo pNeighborRoamInfo - = &pMac->roam.neighborRoamInfo[sessionId]; - tpCsrChannelInfo curchnl_list_info - = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + tpCsrChannelInfo curchnl_list_info = NULL; uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; uint8_t newChannelList[128] = { 0 }; uint8_t i = 0, j = 0; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; + curchnl_list_info = + &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo; + status = sme_acquire_global_lock(&pMac->sme); if (!QDF_IS_STATUS_SUCCESS(status)) { if (pMac->roam.configParam.isRoamOffloadScanEnabled) @@ -5663,6 +5671,7 @@ QDF_STATUS sme_dhcp_start_ind(tHalHandle hHal, sme_release_global_lock(&pMac->sme); return QDF_STATUS_E_FAILURE; } + pSession->dhcp_done = false; pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd)); if (NULL == pMsg) { @@ -5734,6 +5743,7 @@ QDF_STATUS sme_dhcp_stop_ind(tHalHandle hHal, sme_release_global_lock(&pMac->sme); return QDF_STATUS_E_FAILURE; } + pSession->dhcp_done = true; pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd)); if (NULL == pMsg) { @@ -8752,6 +8762,12 @@ QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId, tpAniSirGlobal pMac = PMAC_STRUCT(hHal); QDF_STATUS status = QDF_STATUS_SUCCESS; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -8765,6 +8781,7 @@ QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId, pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff; sme_release_global_lock(&pMac->sme); } + if (pMac->roam.configParam.isRoamOffloadScanEnabled) { csr_roam_offload_scan(pMac, sessionId, ROAM_SCAN_OFFLOAD_UPDATE_CFG, @@ -8827,6 +8844,12 @@ QDF_STATUS sme_update_wes_mode(tHalHandle hHal, bool isWESModeEnabled, tpAniSirGlobal pMac = PMAC_STRUCT(hHal); QDF_STATUS status = QDF_STATUS_SUCCESS; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -8863,6 +8886,13 @@ QDF_STATUS sme_set_roam_scan_control(tHalHandle hHal, uint8_t sessionId, MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0)); + + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -9389,6 +9419,13 @@ QDF_STATUS sme_set_delay_before_vdev_stop(tHalHandle hal, { tpAniSirGlobal pMac = PMAC_STRUCT(hal); QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (session_id >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), session_id); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SME, @@ -9440,6 +9477,12 @@ QDF_STATUS sme_set_neighbor_scan_refresh_period tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { pNeighborRoamConfig = @@ -9553,6 +9596,12 @@ QDF_STATUS sme_update_empty_scan_refresh_period(tHalHandle hHal, uint8_t session tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { pNeighborRoamConfig = @@ -9601,6 +9650,12 @@ QDF_STATUS sme_set_neighbor_scan_min_chan_time(tHalHandle hHal, tpAniSirGlobal pMac = PMAC_STRUCT(hHal); QDF_STATUS status = QDF_STATUS_SUCCESS; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -9644,6 +9699,12 @@ QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionI tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { pNeighborRoamConfig = @@ -9683,6 +9744,13 @@ QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionI uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId) { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return 0; + } + return pMac->roam.neighborRoamInfo[sessionId].cfgParams. minChannelScanTime; } @@ -9697,6 +9765,13 @@ uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId) uint32_t sme_get_neighbor_roam_state(tHalHandle hHal, uint8_t sessionId) { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return 0; + } + return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState; } @@ -9803,6 +9878,13 @@ uint32_t sme_get_lim_mlm_session_state(tHalHandle hHal, uint8_t sessionId) uint16_t sme_get_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId) { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return 0; + } + return pMac->roam.neighborRoamInfo[sessionId].cfgParams. maxChannelScanTime; } @@ -9827,6 +9909,12 @@ QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId, tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL; tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { pNeighborRoamConfig = @@ -9867,6 +9955,13 @@ QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId, uint16_t sme_get_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId) { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return 0; + } + return pMac->roam.neighborRoamInfo[sessionId].cfgParams. neighborScanPeriod; } @@ -9904,14 +9999,19 @@ QDF_STATUS sme_change_roam_scan_channel_list(tHalHandle hHal, uint8_t sessionId, { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); QDF_STATUS status = QDF_STATUS_SUCCESS; - tpCsrNeighborRoamControlInfo pNeighborRoamInfo = - &pMac->roam.neighborRoamInfo[sessionId]; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; uint8_t newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 }; uint8_t i = 0, j = 0; tCsrChannelInfo *chan_info; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; status = sme_acquire_global_lock(&pMac->sme); if (!QDF_IS_STATUS_SUCCESS(status)) { if (pMac->roam.configParam.isRoamOffloadScanEnabled) @@ -9980,10 +10080,16 @@ QDF_STATUS sme_get_roam_scan_channel_list(tHalHandle hHal, int i = 0; uint8_t *pOutPtr = pChannelList; tpAniSirGlobal pMac = PMAC_STRUCT(hHal); - tpCsrNeighborRoamControlInfo pNeighborRoamInfo = - &pMac->roam.neighborRoamInfo[sessionId]; + tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL; QDF_STATUS status = QDF_STATUS_SUCCESS; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + + pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId]; status = sme_acquire_global_lock(&pMac->sme); if (!QDF_IS_STATUS_SUCCESS(status)) return status; @@ -13093,6 +13199,12 @@ QDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal, uint8_t sessionId, tpAniSirGlobal pMac = PMAC_STRUCT(hHal); QDF_STATUS status = QDF_STATUS_SUCCESS; + if (sessionId >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), sessionId); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, @@ -15671,6 +15783,12 @@ QDF_STATUS sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle, tpCsrNeighborRoamControlInfo nr_info = NULL; uint32_t reason = 0; + if (session_id >= CSR_ROAM_SESSION_MAX) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid sme session id: %d"), session_id); + return QDF_STATUS_E_INVAL; + } + status = sme_acquire_global_lock(&mac_ctx->sme); if (QDF_IS_STATUS_SUCCESS(status)) { nr_config = &mac_ctx->roam.configParam.neighborRoamConfig; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 2f412bd5de34..9f74eca9186d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -7619,8 +7619,6 @@ QDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId, sme_bss_type_to_string(pProfile->BSSType), pProfile->BSSType, pProfile->AuthType.authType[0], pProfile->EncryptionType.encryptionType[0]); - /* Reset dhcp_done for the fresh connection */ - pSession->dhcp_done = false; csr_roam_cancel_roaming(pMac, sessionId); csr_scan_remove_fresh_scan_command(pMac, sessionId); csr_scan_abort_all_scans(pMac, eCSR_SCAN_ABORT_DEFAULT); diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 8f8a4d9d1c0e..0b2f12ed87d5 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -1165,10 +1165,10 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params) { ol_txrx_pdev_handle pdev; ol_txrx_vdev_handle vdev; - ol_txrx_peer_handle peer; - uint8_t vdev_id, peer_id; + uint8_t vdev_id; bool roam_synch_in_progress = false; QDF_STATUS status; + struct wma_target_req *msg; params->status = true; WMA_LOGD("%s: state %d selfmac %pM", __func__, @@ -1215,16 +1215,28 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params) ol_txrx_vdev_pause(wma->interfaces[vdev_id].handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); wma->interfaces[vdev_id].pause_bitmap |= (1 << PAUSE_TYPE_HOST); - if (wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id)) { - WMA_LOGP("%s: %d Failed to send vdev stop", - __func__, __LINE__); + + msg = wma_fill_vdev_req(wma, vdev_id, + WMA_SET_LINK_STATE, + WMA_TARGET_REQ_TYPE_VDEV_STOP, params, + WMA_VDEV_STOP_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP(FL("Failed to fill vdev request for vdev_id %d"), + vdev_id); + status = QDF_STATUS_E_NOMEM; } - peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); - if (peer) { - WMA_LOGP("%s: Deleting peer %pM vdev id %d", - __func__, params->bssid, vdev_id); - wma_remove_peer(wma, params->bssid, vdev_id, peer, - roam_synch_in_progress); + if (wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id)) { + WMA_LOGP("%s: %d Failed to send vdev stop vdev %d", + __func__, __LINE__, vdev_id); + } else { + WMA_LOGP("%s: %d vdev stop sent vdev %d", + __func__, __LINE__, vdev_id); + /* + * Remove peer, Vdev down and sending set link + * response will be handled in vdev stop response + * handler + */ + return; } } out: diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 138958cf6a0d..ed4b923d9e64 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1499,6 +1499,24 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info, resp_event->vdev_id); wma_vdev_detach(wma, iface->del_staself_req, 1); } + } else if (req_msg->msg_type == WMA_SET_LINK_STATE) { + tpLinkStateParams params = + (tpLinkStateParams) req_msg->user_data; + + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); + if (peer) { + WMA_LOGP(FL("Deleting peer %pM vdev id %d"), + params->bssid, req_msg->vdev_id); + wma_remove_peer(wma, params->bssid, req_msg->vdev_id, + peer, false); + } + if (wmi_unified_vdev_down_send(wma->wmi_handle, + req_msg->vdev_id) != + QDF_STATUS_SUCCESS) { + WMA_LOGE("Failed to send vdev down cmd: vdev %d", + req_msg->vdev_id); + } + wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0); } free_req_msg: qdf_mc_timer_destroy(&req_msg->event_timeout); @@ -2596,6 +2614,27 @@ void wma_vdev_resp_timer(void *data) } else if (tgt_req->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART) { WMA_LOGE("Hidden ssid vdev restart Timed Out; vdev_id: %d, type = %d", tgt_req->vdev_id, tgt_req->type); + } else if (tgt_req->msg_type == WMA_SET_LINK_STATE) { + tpLinkStateParams params = + (tpLinkStateParams) tgt_req->user_data; + + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); + if (peer) { + WMA_LOGP(FL("Deleting peer %pM vdev id %d"), + params->bssid, tgt_req->vdev_id); + wma_remove_peer(wma, params->bssid, tgt_req->vdev_id, + peer, false); + } + if (wmi_unified_vdev_down_send(wma->wmi_handle, + tgt_req->vdev_id) != + QDF_STATUS_SUCCESS) { + WMA_LOGE("Failed to send vdev down cmd: vdev %d", + tgt_req->vdev_id); + } + params->status = QDF_STATUS_E_TIMEOUT; + WMA_LOGA("%s: WMA_SET_LINK_STATE timedout vdev %d", __func__, + tgt_req->vdev_id); + wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0); } free_tgt_req: qdf_mc_timer_destroy(&tgt_req->event_timeout); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 8db6b3b52926..91e4fc6be238 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3191,19 +3191,6 @@ QDF_STATUS wma_stop(void *cds_ctx, uint8_t reason) WMA_LOGE("Failed to destroy the log completion timer"); } - /* There's no need suspend target which is already down during SSR. */ - if (!cds_is_driver_recovering()) { -#ifdef HIF_USB - /* Suspend the target and enable interrupt */ - if (wma_suspend_target(wma_handle, 0)) - WMA_LOGE("Failed to suspend target"); -#else - /* Suspend the target and disable interrupt */ - if (wma_suspend_target(wma_handle, 1)) - WMA_LOGE("Failed to suspend target"); -#endif /* HIF_USB */ - } - /* clean up ll-queue for all vdev */ for (i = 0; i < wma_handle->max_bssid; i++) { if (wma_handle->interfaces[i].handle && diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index f5273850f7dd..37a242410b46 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1696,6 +1696,10 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info, if (rssi_event->num_per_chain_rssi_stats > 0) { temp = (uint8_t *) rssi_event; temp += sizeof(*rssi_event); + + /* skip past struct array tlv header */ + temp += WMI_TLV_HDR_SIZE; + for (i = 0; i < rssi_event->num_per_chain_rssi_stats; i++) { |
