From e1c2e21a3d92eeba248a5932f454afc3bea28da7 Mon Sep 17 00:00:00 2001 From: Deepak Dhamdhere Date: Fri, 13 Jan 2017 01:54:02 -0800 Subject: [PATCH] qcacld-3.0: Add peer unmap timeout handler Add a timeout handler that fires off 6000 ms after peer detach operation is initiated. Used for debugging the scenario of missing peer unmap events after deleting a STA type peer. CRs-Fixed: 1109867 Change-Id: Iad18f374ba3c1458c5214befd1d5c1517a7bdedf --- core/dp/txrx/ol_txrx.c | 38 +++++++++++++++++++++++++++++++++++- core/dp/txrx/ol_txrx.h | 2 ++ core/dp/txrx/ol_txrx_types.h | 4 ++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 3366c1132715..f74c3a556aa1 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -2458,7 +2458,6 @@ ol_txrx_peer_attach(struct cdp_vdev *pvdev, uint8_t *peer_mac_addr) qdf_atomic_set(&peer->fw_create_pending, 1); qdf_atomic_inc(&peer->ref_cnt); - peer->valid = 1; ol_txrx_peer_find_hash_add(pdev, peer); @@ -3148,6 +3147,11 @@ int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer) vdev->wait_on_peer_id = OL_TXRX_INVALID_LOCAL_PEER_ID; } + if (vdev->opmode == wlan_op_mode_sta) { + qdf_mc_timer_stop(&peer->peer_unmap_timer); + qdf_mc_timer_destroy(&peer->peer_unmap_timer); + } + /* check whether the parent vdev has no peers left */ if (TAILQ_EMPTY(&vdev->peer_list)) { /* @@ -3285,6 +3289,27 @@ static QDF_STATUS ol_txrx_clear_peer(struct cdp_pdev *ppdev, uint8_t sta_id) } +/** + * peer_unmap_timer() - peer unmap timer function + * @data: peer object pointer + * + * Return: none + */ +void peer_unmap_timer_handler(void *data) +{ + ol_txrx_peer_handle peer = (ol_txrx_peer_handle)data; + + ol_txrx_err("all unmap events not received for peer %p, ref_cnt %d", + peer, qdf_atomic_read(&peer->ref_cnt)); + ol_txrx_err("peer %p (%02x:%02x:%02x:%02x:%02x:%02x)", + peer, + peer->mac_addr.raw[0], peer->mac_addr.raw[1], + peer->mac_addr.raw[2], peer->mac_addr.raw[3], + peer->mac_addr.raw[4], peer->mac_addr.raw[5]); + QDF_BUG(0); +} + + /** * ol_txrx_peer_detach() - Delete a peer's data object. * @peer - the object to detach @@ -3337,6 +3362,17 @@ static void ol_txrx_peer_detach(void *ppeer) */ qdf_atomic_set(&peer->delete_in_progress, 1); + /* + * Create a timer to track unmap events when the sta peer gets deleted. + */ + if (vdev->opmode == wlan_op_mode_sta) { + qdf_mc_timer_init(&peer->peer_unmap_timer, QDF_TIMER_TYPE_SW, + peer_unmap_timer_handler, peer); + qdf_mc_timer_start(&peer->peer_unmap_timer, + OL_TXRX_PEER_UNMAP_TIMEOUT); + ol_txrx_info("started peer_unmap_timer for peer %p", peer); + } + /* * Remove the reference added during peer_attach. * The peer will still be left allocated until the diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h index 27a026fb11e3..de60f40db6e6 100644 --- a/core/dp/txrx/ol_txrx.h +++ b/core/dp/txrx/ol_txrx.h @@ -123,4 +123,6 @@ void *ol_txrx_find_peer_by_addr(struct cdp_pdev *pdev, uint8_t *peer_id); void htt_pkt_log_init(struct cdp_pdev *pdev_handle, void *scn); +void peer_unmap_timer_handler(void *data); + #endif /* _OL_TXRX__H_ */ diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index bf05ead91d30..0da6ab2cd0ed 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -1117,6 +1117,9 @@ typedef A_STATUS (*ol_tx_filter_func)(struct ol_txrx_msdu_info_t * #define OL_TXRX_PEER_SECURITY_UNICAST 1 #define OL_TXRX_PEER_SECURITY_MAX 2 +/* Allow 6000 ms to receive peer unmap events after peer is deleted */ +#define OL_TXRX_PEER_UNMAP_TIMEOUT (6000) + struct ol_txrx_peer_t { struct ol_txrx_vdev_t *vdev; @@ -1226,6 +1229,7 @@ struct ol_txrx_peer_t { qdf_time_t last_disassoc_rcvd; qdf_time_t last_deauth_rcvd; qdf_atomic_t fw_create_pending; + qdf_mc_timer_t peer_unmap_timer; }; struct ol_rx_remote_data {