diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index f08df5bf8568..c5a7fb42dfc5 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -2377,4 +2377,121 @@ void wma_vdev_set_mlme_state(tp_wma_handle wma, uint8_t vdev_id, wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID); } } + +/** + * wma_update_vdev_pause_bitmap() - update vdev pause bitmap + * @vdev_id: the Id of the vdev to configure + * @value: value pause bitmap value + * + * Return: None + */ +static inline +void wma_vdev_update_pause_bitmap(uint8_t vdev_id, uint16_t value) +{ + tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *iface; + + if (vdev_id > wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id: %d", __func__, vdev_id); + return; + } + + if (!wma) { + WMA_LOGE("%s: WMA context is invald!", __func__); + return; + } + + iface = &wma->interfaces[vdev_id]; + if (!iface || !iface->handle) { + WMA_LOGE("%s: Failed to get iface handle: %p", + __func__, iface->handle); + return; + } + + iface->pause_bitmap = value; +} + +/** + * wma_vdev_get_pause_bitmap() - Get vdev pause bitmap + * @vdev_id: the Id of the vdev to configure + * + * Return: Vdev pause bitmap value else 0 on error + */ +static inline +uint16_t wma_vdev_get_pause_bitmap(uint8_t vdev_id) +{ + tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *iface; + + if (!wma) { + WMA_LOGE("%s: WMA context is invald!", __func__); + return 0; + } + + iface = &wma->interfaces[vdev_id]; + if (!iface || !iface->handle) { + WMA_LOGE("%s: Failed to get iface handle: %p", + __func__, iface->handle); + return 0; + } + + return iface->pause_bitmap; +} + +/** + * wma_vdev_set_pause_bit() - Set a bit in vdev pause bitmap + * @vdev_id: the Id of the vdev to configure + * @bit_pos: set bit position in pause bitmap + * + * Return: None + */ +static inline +void wma_vdev_set_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) +{ + tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *iface; + + if (!wma) { + WMA_LOGE("%s: WMA context is invald!", __func__); + return; + } + + iface = &wma->interfaces[vdev_id]; + if (!iface || !iface->handle) { + WMA_LOGE("%s: Failed to get iface handle: %p", + __func__, iface->handle); + return; + } + + iface->pause_bitmap |= (1 << bit_pos); +} + +/** + * wma_vdev_clear_pause_bit() - Clear a bit from vdev pause bitmap + * @vdev_id: the Id of the vdev to configure + * @bit_pos: set bit position in pause bitmap + * + * Return: None + */ +static inline +void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) +{ + tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA); + struct wma_txrx_node *iface; + + if (!wma) { + WMA_LOGE("%s: WMA context is invald!", __func__); + return; + } + + iface = &wma->interfaces[vdev_id]; + if (!iface || !iface->handle) { + WMA_LOGE("%s: Failed to get iface handle: %p", + __func__, iface->handle); + return; + } + + iface->pause_bitmap &= ~(1 << bit_pos); +} + #endif diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 3b0edfed630b..608ff94a2f85 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -1222,7 +1222,7 @@ 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); - wma->interfaces[vdev_id].pause_bitmap |= (1 << PAUSE_TYPE_HOST); + 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__); @@ -1259,11 +1259,11 @@ void wma_unpause_vdev(tp_wma_handle wma) #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) /* When host resume, by default, unpause all active vdev */ - if (wma->interfaces[vdev_id].pause_bitmap) { + if (wma_vdev_get_pause_bitmap(vdev_id)) { cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC), wma->interfaces[vdev_id].handle, 0xffffffff); - wma->interfaces[vdev_id].pause_bitmap = 0; + wma_vdev_update_pause_bitmap(vdev_id, 0); } #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */ @@ -1650,20 +1650,20 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event, * Now only support per-dev pause so it is not * necessary to pause a paused queue again. */ - if (!wma->interfaces[vdev_id].pause_bitmap) + if (!wma_vdev_get_pause_bitmap(vdev_id)) cdp_fc_vdev_pause(soc, wma-> interfaces[vdev_id].handle, OL_TXQ_PAUSE_REASON_FW); - wma->interfaces[vdev_id].pause_bitmap |= - (1 << wmi_event->pause_type); + wma_vdev_set_pause_bit(vdev_id, + wmi_event->pause_type); } /* UNPAUSE action, clean bitmap */ else if (ACTION_UNPAUSE == wmi_event->action) { /* Handle unpause only if already paused */ - if (wma->interfaces[vdev_id].pause_bitmap) { - wma->interfaces[vdev_id].pause_bitmap &= - ~(1 << wmi_event->pause_type); + if (wma_vdev_get_pause_bitmap(vdev_id)) { + wma_vdev_clear_pause_bit(vdev_id, + wmi_event->pause_type); if (!wma->interfaces[vdev_id]. pause_bitmap) { @@ -1682,7 +1682,7 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event, WMA_LOGD ("vdev_id %d, pause_map 0x%x, pause type %d, action %d", - vdev_id, wma->interfaces[vdev_id].pause_bitmap, + vdev_id, wma_vdev_get_pause_bitmap(vdev_id), wmi_event->pause_type, wmi_event->action); } /* Test Next VDEV */ @@ -2998,7 +2998,7 @@ void wma_tx_abort(uint8_t vdev_id) return; } WMA_LOGI("%s: vdevid %d bssid %pM", __func__, vdev_id, iface->bssid); - iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST); + wma_vdev_set_pause_bit(vdev_id, PAUSE_TYPE_HOST); cdp_fc_vdev_pause(cds_get_context(QDF_MODULE_ID_SOC), iface->handle, OL_TXQ_PAUSE_REASON_TX_ABORT); diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index b73bfb27b92d..8609445d9409 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -911,7 +911,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info, cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC), iface->handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); - iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST); + wma_vdev_clear_pause_bit(resp_event->vdev_id, PAUSE_TYPE_HOST); } req_msg = wma_find_vdev_req(wma, resp_event->vdev_id, @@ -1527,7 +1527,7 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info, __func__, resp_event->vdev_id); cdp_fc_vdev_unpause(soc, iface->handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); - iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST); + wma_vdev_clear_pause_bit(resp_event->vdev_id, PAUSE_TYPE_HOST); qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", __func__, iface->type, iface->sub_type); @@ -1640,7 +1640,7 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle, self_sta_req->self_mac_addr, self_sta_req->session_id, txrx_vdev_type); - wma_handle->interfaces[self_sta_req->session_id].pause_bitmap = 0; + wma_vdev_update_pause_bitmap(self_sta_req->session_id, 0); WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %p", self_sta_req->session_id, txrx_vdev_handle); @@ -2112,7 +2112,7 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma, cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC), wma->interfaces[params.vdev_id].handle, 0xffffffff); - wma->interfaces[params.vdev_id].pause_bitmap = 0; + wma_vdev_update_pause_bitmap(params.vdev_id, 0); } return wma_send_vdev_start_to_fw(wma, ¶ms); @@ -2607,7 +2607,7 @@ void wma_vdev_resp_timer(void *data) __func__, tgt_req->vdev_id); cdp_fc_vdev_unpause(soc, iface->handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); - iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST); + wma_vdev_clear_pause_bit(tgt_req->vdev_id, PAUSE_TYPE_HOST); qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", __func__, iface->type, iface->sub_type); @@ -4452,14 +4452,14 @@ void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params) __func__, params->smesessionId); cdp_fc_vdev_pause(soc, iface->handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); - iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST); + wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST); cdp_fc_vdev_flush(soc, iface->handle); WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp", __func__, params->smesessionId); cdp_fc_vdev_unpause(soc, iface->handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); - iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST); + wma_vdev_clear_pause_bit(params->smesessionId, PAUSE_TYPE_HOST); qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", __func__, iface->type, iface->sub_type); @@ -4602,11 +4602,10 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)", __func__, params->smesessionId); - iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST); + wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST); cdp_fc_vdev_pause(soc, wma->interfaces[params->smesessionId].handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); - iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST); if (wma_send_vdev_stop_to_fw(wma, params->smesessionId)) { WMA_LOGP("%s: %d Failed to send vdev stop", __func__, __LINE__); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 9f549f1102d4..118f9f6ca325 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -86,6 +86,7 @@ #include "wlan_global_lmac_if_api.h" #include "target_if_pmo.h" #include "wma_he.h" +#include "wlan_pmo_obj_mgmt_api.h" #include #define WMA_LOG_COMPLETION_TIMER 10000 /* 10 seconds */ @@ -2533,6 +2534,11 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, void *cds_context, wma_ndp_register_all_event_handlers(wma_handle); wma_register_debug_callback(); + /* Register callback with PMO so PMO can update the vdev pause bitmap*/ + pmo_register_pause_bitmap_notifier(wma_handle->psoc, + wma_vdev_update_pause_bitmap); + pmo_register_get_pause_bitmap(wma_handle->psoc, + wma_vdev_get_pause_bitmap); return QDF_STATUS_SUCCESS; @@ -3634,6 +3640,12 @@ QDF_STATUS wma_close(void *cds_ctx) target_if_close(); wma_target_if_close(wma_handle); + pmo_unregister_pause_bitmap_notifier(wma_handle->psoc, + wma_vdev_update_pause_bitmap); + pmo_unregister_get_pause_bitmap(wma_handle->psoc, + wma_vdev_get_pause_bitmap); + + WMA_LOGD("%s: Exit", __func__); return QDF_STATUS_SUCCESS; } diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 5830f20506de..a90607c166eb 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -2935,8 +2935,7 @@ void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle, wma_handle-> interfaces[pReq->sessionId].handle, OL_TXQ_PAUSE_REASON_VDEV_STOP); - wma_handle->interfaces[pReq->sessionId].pause_bitmap |= - (1 << PAUSE_TYPE_HOST); + wma_vdev_set_pause_bit(pReq->sessionId, PAUSE_TYPE_HOST); if (wma_send_vdev_stop_to_fw(wma_handle, pReq->sessionId)) { WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__); qdf_atomic_set(&intr[pReq->sessionId].vdev_restart_params.