qcacld-3.0: Handle Vdev restart Failure in STA mode

When switch channel failed,  need handle it gracefully,
pass failure to PE and disconnect current session.

Change-Id: If489e519a1784dabf630d5bde34ef8de56abf5e1
CRs-Fixed: 2360726
This commit is contained in:
Jianmin Zhu 2018-12-04 18:52:54 +08:00 • committed by nshrivas
commit 3c50e40af5
5 changed files with 57 additions and 34 deletions

View file

@ -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 */

View file

@ -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

View file

@ -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,

View file

@ -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) {

View file

@ -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) {