diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index bf8319b5ac41..d8750bc4574f 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -1164,11 +1164,11 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params) { struct cdp_pdev *pdev; struct cdp_vdev *vdev; - void *peer; void *soc = cds_get_context(QDF_MODULE_ID_SOC); - uint8_t vdev_id, peer_id; + uint8_t vdev_id; bool roam_synch_in_progress = false; QDF_STATUS status; + struct wma_target_req *msg; params->status = true; WMA_LOGD("%s: state %d selfmac %pM", __func__, @@ -1215,18 +1215,28 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params) cdp_fc_vdev_pause(soc, wma->interfaces[vdev_id].handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); + msg = wma_fill_vdev_req(wma, vdev_id, + WMA_SET_LINK_STATE, + WMA_TARGET_REQ_TYPE_VDEV_STOP, params, + WMA_VDEV_STOP_REQUEST_TIMEOUT); + if (!msg) { + WMA_LOGP(FL("Failed to fill vdev request for vdev_id %d"), + vdev_id); + status = QDF_STATUS_E_NOMEM; + } wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); if (wma_send_vdev_stop_to_fw(wma, vdev_id)) { WMA_LOGP("%s: %d Failed to send vdev stop", __func__, __LINE__); - } - peer = cdp_peer_find_by_addr(soc, pdev, - params->bssid, &peer_id); - if (peer) { - WMA_LOGP("%s: Deleting peer %pM vdev id %d", - __func__, params->bssid, vdev_id); - wma_remove_peer(wma, params->bssid, vdev_id, peer, - roam_synch_in_progress); + } else { + WMA_LOGP("%s: %d vdev stop sent vdev %d", + __func__, __LINE__, vdev_id); + /* + * Remove peer, Vdev down and sending set link + * response will be handled in vdev stop response + * handler + */ + return; } } out: diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 6b68e131f691..2c14408a03c5 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -1437,6 +1437,8 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info, wmi_vdev_stopped_event_fixed_param *resp_event; struct wma_target_req *req_msg; struct cdp_pdev *pdev; + void *peer; + uint8_t peer_id; struct wma_txrx_node *iface; int32_t status = 0; void *soc = cds_get_context(QDF_MODULE_ID_SOC); @@ -1590,6 +1592,24 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info, resp_event->vdev_id); wma_vdev_detach(wma, iface->del_staself_req, 1); } + } else if (req_msg->msg_type == WMA_SET_LINK_STATE) { + tpLinkStateParams params = + (tpLinkStateParams) req_msg->user_data; + + peer = cdp_peer_find_by_addr(soc, pdev, params->bssid, &peer_id); + if (peer) { + WMA_LOGP(FL("Deleting peer %pM vdev id %d"), + params->bssid, req_msg->vdev_id); + wma_remove_peer(wma, params->bssid, req_msg->vdev_id, + peer, false); + } + if (wmi_unified_vdev_down_send(wma->wmi_handle, + req_msg->vdev_id) != + QDF_STATUS_SUCCESS) { + WMA_LOGE("Failed to send vdev down cmd: vdev %d", + req_msg->vdev_id); + } + wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0); } free_req_msg: @@ -2503,6 +2523,8 @@ void wma_vdev_resp_timer(void *data) struct wma_target_req *tgt_req = (struct wma_target_req *)data; struct cdp_pdev *pdev; struct wma_target_req *msg; + uint8_t peer_id; + void *peer; QDF_STATUS status = QDF_STATUS_SUCCESS; struct scheduler_msg sme_msg = { 0 }; void *soc = cds_get_context(QDF_MODULE_ID_SOC); @@ -2697,6 +2719,27 @@ void wma_vdev_resp_timer(void *data) } else if (tgt_req->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART) { WMA_LOGE("Hidden ssid vdev restart Timed Out; vdev_id: %d, type = %d", tgt_req->vdev_id, tgt_req->type); + } else if (tgt_req->msg_type == WMA_SET_LINK_STATE) { + tpLinkStateParams params = + (tpLinkStateParams) tgt_req->user_data; + + peer = cdp_peer_find_by_addr(soc, pdev, params->bssid, &peer_id); + if (peer) { + WMA_LOGP(FL("Deleting peer %pM vdev id %d"), + params->bssid, tgt_req->vdev_id); + wma_remove_peer(wma, params->bssid, tgt_req->vdev_id, + peer, false); + } + if (wmi_unified_vdev_down_send(wma->wmi_handle, + tgt_req->vdev_id) != + QDF_STATUS_SUCCESS) { + WMA_LOGE("Failed to send vdev down cmd: vdev %d", + tgt_req->vdev_id); + } + params->status = QDF_STATUS_E_TIMEOUT; + WMA_LOGA("%s: WMA_SET_LINK_STATE timedout vdev %d", __func__, + tgt_req->vdev_id); + wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0); } free_tgt_req: qdf_mc_timer_destroy(&tgt_req->event_timeout);