diff options
| author | Rajkumar Manoharan <rmanohar@qti.qualcomm.com> | 2014-01-05 18:52:02 -0800 |
|---|---|---|
| committer | Prakash Dhavali <pdhavali@codeaurora.org> | 2014-01-17 21:45:54 -0800 |
| commit | bcedb835f59d582b9182d926542104219b8c68fd (patch) | |
| tree | 7c61541076e32c6ce79bc632b2868d821fa88ce6 | |
| parent | 47f2f12c263187a4a1df4fd0d8596a03fb066325 (diff) | |
qcacld: Defer vdev deletion until del_bss is completed
During p2p operation, when the GO (remote peer) is initiating
disconnect, disassoc notification is immediately informed to
wpa_supplicant whereas LIM is still in progress of deleting bss.
At the mean time, supplicant is proceeding with changing interface
type to p2p-device that will issue delete_sta_self request. This
vdev delete request is received even before vdev is stopped and
attached bss peer is removed by delete_bss_req. This is causing
target assert due to wrong wmi sequence. Fix this by caching the
vdev delete request and call it once delete_bss is completed.
.
Change-Id: I87b6e48cecf8e05d43a10b5234cec1bb24fe37e7
CRs-Fixed: 592120
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 31 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.h | 5 |
2 files changed, 35 insertions, 1 deletions
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 79e702d11c09..b0f009423c85 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -158,10 +158,10 @@ static void wma_send_beacon_tmpl(WMA_HANDLE handle, static void wma_data_tx_ack_comp_hdlr(void *wma_context, adf_nbuf_t netbuf, int32_t status); +#endif static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle, tpDelStaSelfParams pdel_sta_self_req_param, u_int8_t generateRsp); -#endif static struct wma_target_req * wma_fill_vdev_req(tp_wma_handle wma, u_int8_t vdev_id, u_int32_t msg_type, u_int8_t type, void *params); @@ -865,6 +865,7 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, #ifdef QCA_IBSS_SUPPORT tDelStaSelfParams del_sta_param; #endif + struct wma_txrx_node *iface; param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info; if (!param_buf) { @@ -895,6 +896,11 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, __func__, params->bssid); wma_remove_peer(wma, params->bssid, resp_event->vdev_id, peer); wmi_unified_vdev_down_send(wma->wmi_handle, resp_event->vdev_id); + iface = &wma->interfaces[resp_event->vdev_id]; + if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) { + WMA_LOGD("%s: P2P BSS is stopped", __func__); + iface->bss_status = WMA_BSS_STATUS_STOPPED; + } #ifndef QCA_WIFI_ISOC bcn = wma->interfaces[resp_event->vdev_id].beacon; @@ -922,6 +928,10 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, params->status = VOS_STATUS_SUCCESS; wma_send_msg(wma, WDA_DELETE_BSS_RSP, (void *)params, 0); + if (iface->del_staself_req) { + WMA_LOGD("%s: scheduling defered deletion", __func__); + wma_vdev_detach(wma, iface->del_staself_req, 1); + } } vos_timer_destroy(&req_msg->event_timeout); vos_mem_free(req_msg); @@ -2555,6 +2565,12 @@ static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle, pdel_sta_self_req_param->selfMacAddr, vdev_id, peer); } + if ((iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) && + (iface->bss_status == WMA_BSS_STATUS_STARTED)) { + WMA_LOGD("P2P BSS is not yet stopped. Defering vdev deletion"); + iface->del_staself_req = pdel_sta_self_req_param; + return status; + } /* remove the interface from ath_dev */ if (wma_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id)) { @@ -4923,9 +4939,14 @@ void wma_vdev_resp_timer(void *data) } else if (tgt_req->msg_type == WDA_DELETE_BSS_REQ) { tpDeleteBssParams params = (tpDeleteBssParams)tgt_req->user_data; + struct wma_txrx_node *iface = &wma->interfaces[tgt_req->vdev_id]; peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); wma_remove_peer(wma, params->bssid, tgt_req->vdev_id, peer); wmi_unified_vdev_down_send(wma->wmi_handle, tgt_req->vdev_id); + if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) { + WMA_LOGD("%s: P2P BSS is stopped", __func__); + iface->bss_status = WMA_BSS_STATUS_STOPPED; + } #ifdef QCA_IBSS_SUPPORT if (wma_is_vdev_in_ibss_mode(wma, params->sessionId)) { del_sta_param.sessionId = params->sessionId; @@ -4937,6 +4958,10 @@ void wma_vdev_resp_timer(void *data) params->status = VOS_STATUS_E_TIMEOUT; WMA_LOGA("%s: WDA_DELETE_BSS_REQ timedout", __func__); wma_send_msg(wma, WDA_DELETE_BSS_RSP, (void *)params, 0); + if (iface->del_staself_req) { + WMA_LOGD("%s: scheduling defered deletion", __func__); + wma_vdev_detach(wma, iface->del_staself_req, 1); + } } else if (tgt_req->msg_type == WDA_DEL_STA_SELF_REQ) { struct wma_txrx_node *iface = (struct wma_txrx_node *)tgt_req->user_data; @@ -7247,6 +7272,10 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) status = VOS_STATUS_E_FAILURE; } + if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) { + WMA_LOGD("%s: P2P BSS is started", __func__); + iface->bss_status = WMA_BSS_STATUS_STARTED; + } /* Sta is now associated, configure various params */ /* SM power save, configure the h/w as configured diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 23ff92a32097..4de7bd4fc0ac 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -364,6 +364,10 @@ typedef struct { u_int8_t ipn[CMAC_IPN_LEN]; } wma_igtk_key_t; #endif + +#define WMA_BSS_STATUS_STARTED 0x1 +#define WMA_BSS_STATUS_STOPPED 0x2 + struct wma_txrx_node { u_int8_t addr[ETH_ALEN]; u_int8_t bssid[ETH_ALEN]; @@ -402,6 +406,7 @@ struct wma_txrx_node { tAniGetPEStatsRsp *stats_rsp; tANI_U8 fw_stats_set; void *del_staself_req; + tANI_U8 bss_status; }; #if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC) |
