diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 35b8252819be..1791f4a63744 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -1573,6 +1573,7 @@ typedef struct sSirSmeSwitchChannelInd { uint16_t newChannelId; struct ch_params chan_params; struct qdf_mac_addr bssid; /* BSSID */ + QDF_STATUS status; } tSirSmeSwitchChannelInd, *tpSirSmeSwitchChannelInd; /* / Definition for MIC failure indication */ 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 66e1f48473a4..871e773993fb 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 @@ -4792,6 +4792,20 @@ QDF_STATUS lim_sta_mlme_vdev_disconnect_bss(struct vdev_mlme_obj *vdev_mlme, } return QDF_STATUS_SUCCESS; } + +static void lim_process_disconnect_sta(struct pe_session *session, + struct scheduler_msg *msg) +{ + if (wlan_vdev_mlme_get_substate(session->vdev) == + WLAN_VDEV_SS_START_RESTART_PROGRESS) + wlan_vdev_mlme_sm_deliver_evt(session->vdev, + WLAN_VDEV_SM_EV_RESTART_REQ_FAIL, + sizeof(*msg), msg); + else + wlan_vdev_mlme_sm_deliver_evt(session->vdev, + WLAN_VDEV_SM_EV_DOWN, + sizeof(*msg), msg); +} #endif static void lim_process_sme_disassoc_cnf(struct mac_context *mac_ctx, @@ -4801,7 +4815,6 @@ static void lim_process_sme_disassoc_cnf(struct mac_context *mac_ctx, tSirSmeDisassocCnf sme_disassoc_cnf; struct pe_session *session; uint8_t session_id; - QDF_STATUS status; qdf_mem_copy(&sme_disassoc_cnf, msg->bodyptr, sizeof(struct sSirSmeDisassocCnf)); @@ -4810,15 +4823,11 @@ static void lim_process_sme_disassoc_cnf(struct mac_context *mac_ctx, sme_disassoc_cnf.bssid.bytes, &session_id); - if (LIM_IS_STA_ROLE(session)) { - status = wlan_vdev_mlme_sm_deliver_evt(session->vdev, - WLAN_VDEV_SM_EV_DOWN, - sizeof(*msg), - msg); - } else { + if (LIM_IS_STA_ROLE(session)) + lim_process_disconnect_sta(session, msg); + else __lim_process_sme_disassoc_cnf(mac_ctx, (uint32_t *)msg->bodyptr); - } #else __lim_process_sme_disassoc_cnf(mac_ctx, (uint32_t *)msg->bodyptr); #endif @@ -4831,22 +4840,17 @@ static void lim_process_sme_disassoc_req(struct mac_context *mac_ctx, tSirSmeDisassocReq disassoc_req; struct pe_session *session; uint8_t session_id; - QDF_STATUS status; qdf_mem_copy(&disassoc_req, msg->bodyptr, sizeof(tSirSmeDisassocReq)); session = pe_find_session_by_bssid(mac_ctx, disassoc_req.bssid.bytes, &session_id); - if (LIM_IS_STA_ROLE(session)) { - status = wlan_vdev_mlme_sm_deliver_evt(session->vdev, - WLAN_VDEV_SM_EV_DOWN, - sizeof(*msg), - msg); - } else { + if (LIM_IS_STA_ROLE(session)) + lim_process_disconnect_sta(session, msg); + else __lim_process_sme_disassoc_req(mac_ctx, (uint32_t *)msg->bodyptr); - } #else __lim_process_sme_disassoc_req(mac_ctx, (uint32_t *)msg->bodyptr); #endif @@ -4859,22 +4863,17 @@ static void lim_process_sme_deauth_req(struct mac_context *mac_ctx, tSirSmeDeauthReq sme_deauth_req; struct pe_session *session; uint8_t session_id; - QDF_STATUS status; qdf_mem_copy(&sme_deauth_req, msg->bodyptr, sizeof(tSirSmeDeauthReq)); session = pe_find_session_by_bssid(mac_ctx, sme_deauth_req.bssid.bytes, &session_id); - if (LIM_IS_STA_ROLE(session)) { - status = wlan_vdev_mlme_sm_deliver_evt(session->vdev, - WLAN_VDEV_SM_EV_DOWN, - sizeof(*msg), - msg); - } else { + if (LIM_IS_STA_ROLE(session)) + lim_process_disconnect_sta(session, msg); + else __lim_process_sme_deauth_req(mac_ctx, (uint32_t *)msg->bodyptr); - } #else __lim_process_sme_deauth_req(mac_ctx, (uint32_t *)msg->bodyptr); #endif diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index f9339f975caa..98719b61d871 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -2054,7 +2054,7 @@ static void __lim_process_channel_switch_timeout(struct mac_context *mac) #ifdef CONFIG_VDEV_SM void lim_process_channel_switch_timeout(struct mac_context *mac_ctx) { - tpPESession session_entry = NULL; + struct pe_session *session_entry = NULL; QDF_STATUS status; session_entry = pe_find_session_by_session_id( @@ -2321,13 +2321,16 @@ void lim_switch_channel_cback(struct mac_context *mac, QDF_STATUS status, pSirSmeSwitchChInd->chan_params.center_freq_seg1 = pe_session->gLimChannelSwitch.ch_center_freq_seg1; - pe_debug("session: %d chan: %d width: %d sec offset: %d seg0: %d seg1: %d", + pSirSmeSwitchChInd->status = status; + pe_debug( + "session: %d chan: %d width: %d sec offset: %d seg0: %d seg1: %d status %d", pSirSmeSwitchChInd->sessionId, pSirSmeSwitchChInd->newChannelId, pSirSmeSwitchChInd->chan_params.ch_width, pSirSmeSwitchChInd->chan_params.sec_ch_offset, pSirSmeSwitchChInd->chan_params.center_freq_seg0, - pSirSmeSwitchChInd->chan_params.center_freq_seg1); + pSirSmeSwitchChInd->chan_params.center_freq_seg1, + status); qdf_mem_copy(pSirSmeSwitchChInd->bssid.bytes, pe_session->bssId, QDF_MAC_ADDR_SIZE); @@ -2339,6 +2342,9 @@ void lim_switch_channel_cback(struct mac_context *mac, QDF_STATUS status, sys_process_mmh_msg(mac, &mmhMsg); #ifdef CONFIG_VDEV_SM + if (QDF_IS_STATUS_ERROR(status)) + return; + evt_status = wlan_vdev_mlme_sm_deliver_evt( pe_session->vdev, WLAN_VDEV_SM_EV_START_SUCCESS, diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 0dbdfba9b916..049ed3238b1d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -11254,6 +11254,15 @@ csr_roam_chk_lnk_swt_ch_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr) sme_err("session %d not found", sessionId); return; } + +#ifdef CONFIG_VDEV_SM + if (QDF_IS_STATUS_ERROR(pSwitchChnInd->status)) { + sme_err("Channel switch failed"); + csr_roam_disconnect_internal(mac_ctx, sessionId, + eCSR_DISCONNECT_REASON_DEAUTH); + return; + } +#endif session->connectedProfile.operationChannel = (uint8_t) pSwitchChnInd->newChannelId; if (session->pConnectBssDesc) { diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 627b933ae20b..75aed014fe61 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1402,6 +1402,16 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, wma->interfaces[resp_event->vdev_id].is_channel_switch = false; } +#else + /* Indicate channel switch failure to LIM */ + if (QDF_IS_STATUS_ERROR(params->status) && + (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id) || + mlme_is_chan_switch_in_progress(iface->vdev))) { + mlme_set_chan_switch_in_progress(iface->vdev, false); + wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, + (void *)params, 0); + goto error; + } #endif if ((QDF_IS_STATUS_SUCCESS(resp_event->status) && (resp_event->resp_type == WMI_VDEV_RESTART_RESP_EVENT) && @@ -1484,7 +1494,9 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, #endif ucfg_ocb_config_channel(wma->pdev); } - +#ifdef CONFIG_VDEV_SM +error: +#endif if ((wma->interfaces[resp_event->vdev_id].type == WMI_VDEV_TYPE_AP) && wma_is_vdev_up(resp_event->vdev_id)) wma_set_sap_keepalive(wma, resp_event->vdev_id); @@ -3763,14 +3775,10 @@ void wma_vdev_resp_timer(void *data) } else { #ifdef CONFIG_VDEV_SM iface = &wma->interfaces[tgt_req->vdev_id]; - - wlan_vdev_mlme_sm_deliver_evt(iface->vdev, - WLAN_VDEV_SM_EV_RESTART_RESP, - sizeof(*params), params); -#else + mlme_set_chan_switch_in_progress(iface->vdev, false); +#endif wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP, (void *)params, 0); -#endif } #ifndef CONFIG_VDEV_SM if (wma->interfaces[tgt_req->vdev_id].is_channel_switch) {