qcacld-3.0: Avoid Rome mgmt nbuf double unmap during SSR

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.

Change-Id: I2fc658e833cf013bf7048c6bec90d9b247566444
CRs-Fixed: 2694854
Cette révision appartient à :
Jianmin Zhu
2020-06-01 17:15:19 +08:00
révisé par nshrivas
Parent 883685660d
révision 61409803d7

Voir le fichier

@@ -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;