diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index 26816ed0df9f..f40b2d1ceaee 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -375,6 +375,8 @@ struct addstafor_sessioncmd { struct delstafor_sessionCmd { /* Session self mac addr */ tSirMacAddr selfMacAddr; + csr_session_close_cb session_close_cb; + void *context; }; struct csr_neighbor_roamconfig { diff --git a/core/sme/inc/sme_inside.h b/core/sme/inc/sme_inside.h index 8107c90deab4..4d1db471895d 100644 --- a/core/sme/inc/sme_inside.h +++ b/core/sme/inc/sme_inside.h @@ -216,6 +216,18 @@ void csr_roam_wm_status_change_complete(tpAniSirGlobal mac_ctx, uint8_t session_id); void csr_roam_process_wm_status_change_command(tpAniSirGlobal pMac, tSmeCmd *pCommand); +/** + * csr_process_del_sta_session_command() - Post WMA_DEL_STA_SELF_REQ to wma + * + * @mac_ctx: global mac context + * @sme_command: received Delete Self station request command + * + * This API sends the WMA_DEL_STA_SELF_REQ msg to WMA. + * + * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE + */ +QDF_STATUS csr_process_del_sta_session_command(tpAniSirGlobal mac_ctx, + tSmeCmd *sme_command); void csr_reinit_roam_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); void csr_reinit_wm_status_change_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand); QDF_STATUS csr_roam_send_set_key_cmd(tpAniSirGlobal mac_ctx, diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 486fa051bdc6..6c8f946832d1 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -51,6 +51,7 @@ typedef enum eSmeCommandType { eSmeCsrCommandMask = 0x10000, eSmeCommandRoam, eSmeCommandWmStatusChange, + e_sme_command_del_sta_session, #ifdef FEATURE_WLAN_TDLS /* * eSmeTdlsCommandMask = 0x80000, diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index afabd5c2ee88..594a225aeaf9 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -371,6 +371,11 @@ static void dump_csr_command_info(tpAniSirGlobal pMac, tSmeCmd *pCmd) pCmd->u.wmStatusChangeCmd.Type); break; + case e_sme_command_del_sta_session: + sme_debug("Issue del STA command for session:%d", + pCmd->sessionId); + break; + default: sme_debug("default: Unhandled command %d", pCmd->command); @@ -500,6 +505,9 @@ QDF_STATUS sme_ser_handle_active_cmd(struct wlan_serialization_command *cmd) csr_roam_process_wm_status_change_command(mac_ctx, sme_cmd); break; + case e_sme_command_del_sta_session: + csr_process_del_sta_session_command(mac_ctx, sme_cmd); + break; case eSmeCommandAddTs: case eSmeCommandDelTs: #ifndef WLAN_MDM_CODE_REDUCTION_OPT diff --git a/core/sme/src/common/sme_trace.c b/core/sme/src/common/sme_trace.c index 7d2d710005e7..621bd9b2acf2 100644 --- a/core/sme/src/common/sme_trace.c +++ b/core/sme/src/common/sme_trace.c @@ -162,6 +162,7 @@ static uint8_t *sme_trace_get_command_string(uint32_t command) CASE_RETURN_STRING(eSmeCsrCommandMask); CASE_RETURN_STRING(eSmeCommandRoam); CASE_RETURN_STRING(eSmeCommandWmStatusChange); + CASE_RETURN_STRING(e_sme_command_del_sta_session); #ifdef FEATURE_WLAN_TDLS CASE_RETURN_STRING(eSmeCommandTdlsSendMgmt); CASE_RETURN_STRING(eSmeCommandTdlsAddPeer); diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 158c3b9f39bc..28cb2693b3cd 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -13319,6 +13319,41 @@ end: } } +QDF_STATUS csr_process_del_sta_session_command(tpAniSirGlobal mac_ctx, + tSmeCmd *sme_command) +{ + struct del_sta_self_params *del_sta_self_req; + struct scheduler_msg msg = {0}; + QDF_STATUS status; + + del_sta_self_req = qdf_mem_malloc(sizeof(struct del_sta_self_params)); + if (NULL == del_sta_self_req) { + sme_err(" mem alloc failed for tDelStaSelfParams"); + return QDF_STATUS_E_NOMEM; + } + + qdf_mem_copy(del_sta_self_req->self_mac_addr, + sme_command->u.delStaSessionCmd.selfMacAddr, + sizeof(tSirMacAddr)); + + del_sta_self_req->session_id = sme_command->sessionId; + del_sta_self_req->sme_callback = + sme_command->u.delStaSessionCmd.session_close_cb; + del_sta_self_req->sme_ctx = sme_command->u.delStaSessionCmd.context; + msg.type = WMA_DEL_STA_SELF_REQ; + msg.reserved = 0; + msg.bodyptr = del_sta_self_req; + msg.bodyval = 0; + + sme_debug("sending WMA_DEL_STA_SELF_REQ"); + status = wma_post_ctrl_msg(mac_ctx, &msg); + if (status != QDF_STATUS_SUCCESS) { + sme_err("wma_post_ctrl_msg failed"); + qdf_mem_free(del_sta_self_req); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; +} /** * csr_compute_mode_and_band() - computes dot11mode @@ -17262,56 +17297,29 @@ QDF_STATUS csr_process_del_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg) static QDF_STATUS -csr_issue_del_sta_for_session_req(tpAniSirGlobal pMac, uint32_t sessionId, - tSirMacAddr sessionMacAddr, +csr_issue_del_sta_for_session_req(tpAniSirGlobal mac_ctx, uint32_t session_id, + tSirMacAddr session_mac_addr, csr_session_close_cb callback, - void *pContext) + void *context) { - struct del_sta_self_params *del_sta_self_req; - struct scheduler_msg msg = {0}; - tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA); - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_SUCCESS; + tSmeCmd *sme_command; - if (!wma_handle) { - sme_err("wma handle is NULL"); - return QDF_STATUS_E_INVAL; + sme_command = csr_get_command_buffer(mac_ctx); + if (NULL == sme_command) { + status = QDF_STATUS_E_RESOURCES; + } else { + sme_command->command = e_sme_command_del_sta_session; + sme_command->sessionId = (uint8_t)session_id; + sme_command->u.delStaSessionCmd.session_close_cb = callback; + sme_command->u.delStaSessionCmd.context = context; + qdf_mem_copy(sme_command->u.delStaSessionCmd.selfMacAddr, + session_mac_addr, sizeof(tSirMacAddr)); + status = csr_queue_sme_command(mac_ctx, sme_command, true); + if (!QDF_IS_STATUS_SUCCESS(status)) + sme_err("fail to send message status = %d", status); } - - /* Need to wait for all peer delete command sent to FW - * before sending VDEV delete command - * otherwise it will cause FW assert - * Need to do this before sending to scheduler queue - * otherwise the scheduler thread will be blocked - * and fail to handle the VDEV stop timeout callback - * in which peer delete command will also be sent - */ - wma_vdev_wait_for_peer_delete_completion(wma_handle, sessionId); - - del_sta_self_req = qdf_mem_malloc(sizeof(struct del_sta_self_params)); - if (NULL == del_sta_self_req) { - sme_err(" mem alloc failed for tDelStaSelfParams"); - return QDF_STATUS_E_NOMEM; - } - - qdf_mem_copy(del_sta_self_req->self_mac_addr, - sessionMacAddr, sizeof(tSirMacAddr)); - - del_sta_self_req->session_id = sessionId; - del_sta_self_req->sme_callback = callback; - del_sta_self_req->sme_ctx = pContext; - msg.type = WMA_DEL_STA_SELF_REQ; - msg.reserved = 0; - msg.bodyptr = del_sta_self_req; - msg.bodyval = 0; - - sme_debug("sending WMA_DEL_STA_SELF_REQ"); - status = wma_post_ctrl_msg(pMac, &msg); - if (status != QDF_STATUS_SUCCESS) { - sme_err("wma_post_ctrl_msg failed"); - qdf_mem_free(del_sta_self_req); - return QDF_STATUS_E_FAILURE; - } - return QDF_STATUS_SUCCESS; + return status; } void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId) @@ -20247,6 +20255,9 @@ enum wlan_serialization_cmd_type csr_get_cmd_type(tSmeCmd *sme_cmd) case eSmeCommandWmStatusChange: cmd_type = WLAN_SER_CMD_WM_STATUS_CHANGE; break; + case e_sme_command_del_sta_session: + cmd_type = WLAN_SER_CMD_DEL_STA_SESSION; + break; case eSmeCommandAddTs: cmd_type = WLAN_SER_CMD_ADDTS; break; diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index ae441d3c0436..3f66cae06372 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1092,8 +1092,6 @@ struct wma_txrx_node { uint32_t nwType; void *staKeyParams; uint32_t peer_count; - qdf_atomic_t fw_peer_count; - qdf_event_t fw_peer_delete_completion; bool roam_synch_in_progress; void *plink_status_req; void *psnr_req; diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 38ffb4b2517b..826eca6a2611 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -587,7 +587,6 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, goto out; } - QDF_BUG(qdf_atomic_read(&iface->fw_peer_count) == 0); status = wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id); if (QDF_IS_STATUS_ERROR(status)) { @@ -595,8 +594,6 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, goto out; } - qdf_event_destroy(&iface->fw_peer_delete_completion); - WMA_LOGD("vdev_id:%hu vdev_hdl:%pK", vdev_id, iface->handle); if (!generate_rsp) { WMA_LOGE("Call txrx detach w/o callback for vdev %d", vdev_id); @@ -701,60 +698,10 @@ static void wma_force_vdev_cleanup(tp_wma_handle wma_handle, uint8_t vdev_id) wma_peer_remove_for_vdev_callback, wma_handle); - qdf_atomic_init(&iface->fw_peer_count); - qdf_event_destroy(&iface->fw_peer_delete_completion); - VDEV_DETACH: wma_cdp_vdev_detach(soc, wma_handle, vdev_id); } -#define WMA_WAIT_PEER_DELETE_COMPLETION_TIMEOUT (WMA_VDEV_STOP_REQUEST_TIMEOUT+ 1000) - -/** - * wma_vdev_wait_for_peer_delete_completion(): wait for all peers of the vdev - * to be deleted except vdev type is P2P device. - * @wma_handle: wma handle - * @vdev_id: vdev id - * - * Return: None - */ -void wma_vdev_wait_for_peer_delete_completion(tp_wma_handle wma_handle, - uint8_t vdev_id) -{ - struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; - - /* Do NOT wait when SSR is in progress - * since all WMI commands will be ignored and not sent to FW - */ - if (cds_is_driver_recovering()) { - WMA_LOGD("%s: SSR is in progress", __func__); - return; - } - - if (!iface || !iface->vdev_active) { - WMA_LOGE("%s: iface of vdev-%d is not available", - __func__, vdev_id); - return; - } - - /* For P2P Device, firstly it will delete the last peer in - * wma vdev detach, so not wait before deliver - * WMA_DEL_STA_SELF_REQ. Secondly, no throughput case run on - * P2P device, and no need to take care the case which no - * vdev stop response from FW. - */ - if (((iface->type == WMI_VDEV_TYPE_AP) && - (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) || - (cds_is_fw_down())) { - WMA_LOGD("%s: type %d P2P devices or firmware is down, do not wait", - __func__, iface->type); - return; - } - - qdf_wait_for_event_completion(&iface->fw_peer_delete_completion, - WMA_WAIT_PEER_DELETE_COMPLETION_TIMEOUT); -} - static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype) { switch (vdev_type) { @@ -1518,12 +1465,6 @@ void wma_remove_peer(tp_wma_handle wma, uint8_t *bssid, __func__, qdf_status); /* Clear default bit and set to NOT_START_UNMAP */ bitmap = 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER; - } else { - qdf_atomic_dec(&wma->interfaces[vdev_id].fw_peer_count); - WMA_LOGD("%s: vdev-%d fw_peer_count %d", __func__, vdev_id, - qdf_atomic_read(&wma->interfaces[vdev_id].fw_peer_count)); - if (qdf_atomic_read(&wma->interfaces[vdev_id].fw_peer_count) == 0) - qdf_event_set(&wma->interfaces[vdev_id].fw_peer_delete_completion); } peer_detach: @@ -1784,11 +1725,6 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev, 1 << CDP_PEER_DO_NOT_START_UNMAP_TIMER); wlan_objmgr_peer_obj_delete(obj_peer); goto err; - } else { - qdf_atomic_inc(&wma->interfaces[vdev_id].fw_peer_count); - WMA_LOGD("%s: vdev-%d fw_peer_count %d", __func__, vdev_id, - qdf_atomic_read(&wma->interfaces[vdev_id].fw_peer_count)); - qdf_event_reset(&wma->interfaces[vdev_id].fw_peer_delete_completion); } WMA_LOGD("%s: Created peer %pK with peer_addr %pM vdev_id %d, peer_count - %d", @@ -2519,15 +2455,6 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, self_sta_req->sub_type; qdf_atomic_init(&wma_handle->interfaces [self_sta_req->session_id].bss_status); - qdf_atomic_init(&wma_handle->interfaces - [self_sta_req->session_id].fw_peer_count); - status = qdf_event_create(&wma_handle->interfaces - [self_sta_req->session_id].fw_peer_delete_completion); - if (status != QDF_STATUS_SUCCESS) { - WMA_LOGE("%s: Failed to create fw_peer_delete_completion", __func__); - goto end; - } - qdf_event_set(&wma_handle->interfaces[vdev_id].fw_peer_delete_completion); if (wma_vdev_uses_self_peer(self_sta_req->type, self_sta_req->sub_type)) { @@ -5710,10 +5637,6 @@ void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params) } iface->peer_count--; - WMA_LOGD("%s: Reset FW peer count", __func__); - qdf_atomic_init(&iface->fw_peer_count); - qdf_event_set(&iface->fw_peer_delete_completion); - WMA_LOGI("%s: Removed peer %pK with peer_addr %pM vdevid %d peer_count %d", __func__, peer, params->bssid, params->smesessionId, iface->peer_count);