diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 99f5d9639a2e..aeb888161b44 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -1619,11 +1619,39 @@ static void ol_tx_free_descs_inuse(ol_txrx_pdev_handle pdev) * In particular, check that there are no frames that have * been given to the target to transmit, for which the * target has never provided a response. + * + * Rome supports mgmt Tx via HTT interface, not via WMI. + * When mgmt frame is sent, 2 tx desc is allocated: + * mgmt_txrx_desc is allocated in wlan_mgmt_txrx_mgmt_frame_tx, + * ol_tx_desc is allocated in ol_txrx_mgmt_send_ext. + * They point to same net buffer. + * net buffer is mapped in htt_tx_desc_init. + * + * When SSR during Rome STA connected, deauth frame is sent, + * but no tx complete since firmware hung already. + * Pending mgmt frames are unmapped and freed when destroy + * vdev. + * hdd_reset_all_adapters->hdd_stop_adapter->hdd_vdev_destroy + * ->wma_handle_vdev_detach->wlan_mgmt_txrx_vdev_drain + * ->wma_mgmt_frame_fill_peer_cb + * ->mgmt_txrx_tx_completion_handler. + * + * Don't need unmap and free net buffer of mgmt frames again + * during data path clean up, just free ol_tx_desc. + * hdd_wlan_stop_modules->cds_post_disable->cdp_pdev_pre_detach + * ->ol_txrx_pdev_pre_detach->ol_tx_free_descs_inuse. */ if (qdf_atomic_read(&tx_desc->ref_cnt)) { - ol_txrx_dbg("Warning: freeing tx frame (no compltn)"); - ol_tx_desc_frame_free_nonstd(pdev, - tx_desc, 1); + if (!ol_tx_get_is_mgmt_over_wmi_enabled() && + tx_desc->pkt_type >= OL_TXRX_MGMT_TYPE_BASE) { + qdf_atomic_init(&tx_desc->ref_cnt); + ol_txrx_dbg("Pending mgmt frames nbuf unmapped and freed already when vdev destroyed"); + /* free the tx desc */ + ol_tx_desc_free(pdev, tx_desc); + } else { + ol_txrx_dbg("Warning: freeing tx frame (no compltn)"); + ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 1); + } num_freed_tx_desc++; } htt_tx_desc = tx_desc->htt_tx_desc;