diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h index 9251386e1f5f..eb53f3e2ee03 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h +++ b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h @@ -689,6 +689,19 @@ typedef QDF_STATUS (*mgmt_frame_rx_callback)( struct mgmt_rx_event_params *mgmt_rx_params, enum mgmt_frame_type frm_type); +/** + * mgmt_frame_fill_peer_cb - Function pointer to fill peer in the buf + * @peer: peer + * @buf: buffer + * + * This is the function pointer to be called during drain to fill the + * peer into the buf's cb structure. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +typedef QDF_STATUS (*mgmt_frame_fill_peer_cb)( + struct wlan_objmgr_peer *peer, + qdf_nbuf_t buf); /** * struct mgmt_txrx_mgmt_frame_cb_info - frm and corresponding rx cb info @@ -792,6 +805,22 @@ QDF_STATUS wlan_mgmt_txrx_register_rx_cb( struct mgmt_txrx_mgmt_frame_cb_info *frm_cb_info, uint8_t num_entries); +/** + * wlan_mgmt_txrx_pdev_drain() - Function to drain all mgmt packets + * @pdev: pdev context + * @mgmt_fill_peer_cb: callback func to UMAC to fill peer into buf + * @status: opaque pointer about the status of the pkts passed to UMAC + * + * This function drains all mgmt packets. This can be used in the + * event of target going down without sending completions. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS wlan_mgmt_txrx_pdev_drain( + struct wlan_objmgr_pdev *pdev, + mgmt_frame_fill_peer_cb mgmt_fill_peer_cb, + void *status); + /** * wlan_mgmt_txrx_deregister_rx_cb() - deregisters the rx cb for mgmt. frames * @psoc: psoc context diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c index d05760fd024e..26bd84332f7f 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c +++ b/umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c @@ -30,6 +30,7 @@ #include "wlan_objmgr_vdev_obj.h" #include "wlan_objmgr_peer_obj.h" #include "qdf_nbuf.h" +#include "wlan_lmac_if_api.h" /** * wlan_mgmt_txrx_psoc_obj_create_notification() - called from objmgr when psoc @@ -768,3 +769,46 @@ QDF_STATUS wlan_mgmt_txrx_psoc_close(struct wlan_objmgr_psoc *psoc) } return QDF_STATUS_SUCCESS; } + +QDF_STATUS wlan_mgmt_txrx_pdev_drain(struct wlan_objmgr_pdev *pdev, + mgmt_frame_fill_peer_cb mgmt_fill_peer_cb, + void *status) +{ + struct mgmt_txrx_priv_pdev_context *mgmt_txrx_pdev_ctx; + struct mgmt_txrx_desc_elem_t *mgmt_desc; + struct wlan_objmgr_peer *peer; + uint32_t pool_size; + int i; + + if (!pdev) { + mgmt_txrx_err("pdev context is NULL"); + return QDF_STATUS_E_INVAL; + } + mgmt_txrx_pdev_ctx = (struct mgmt_txrx_priv_pdev_context *) + wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_MGMT_TXRX); + if (!mgmt_txrx_pdev_ctx) { + mgmt_txrx_err("mgmt txrx context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + pool_size = mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list.max_size; + if (!pool_size) { + mgmt_txrx_err("pool size is 0"); + return QDF_STATUS_E_FAILURE; + } + + for (i = 0; i < pool_size; i++) { + if (mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i].in_use) { + mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[i]; + peer = mgmt_txrx_get_peer(pdev, mgmt_desc->desc_id); + QDF_ASSERT(peer != NULL); + if (mgmt_fill_peer_cb) + mgmt_fill_peer_cb(peer, mgmt_desc->nbuf); + mgmt_txrx_tx_completion_handler(pdev, + mgmt_desc->desc_id, 0, status); + } + } + + return QDF_STATUS_SUCCESS; +}