summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qti.qualcomm.com>2014-01-05 18:52:02 -0800
committerPrakash Dhavali <pdhavali@codeaurora.org>2014-01-17 21:45:54 -0800
commitbcedb835f59d582b9182d926542104219b8c68fd (patch)
tree7c61541076e32c6ce79bc632b2868d821fa88ce6
parent47f2f12c263187a4a1df4fd0d8596a03fb066325 (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.c31
-rw-r--r--CORE/SERVICES/WMA/wma.h5
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)