From 0d3f1d62e1929fcd9b76c7597c25eb330c347b74 Mon Sep 17 00:00:00 2001 From: Prakash Dhavali Date: Sun, 20 Nov 2016 23:48:24 -0800 Subject: [PATCH] qcacld-3.0: Better handling of first peer map event Use a flag fw_create_pending flag to compensate for the extra peer reference count only once for the first peer map event. It will avoid duplicate compensation of ref count and untimely peer delete. CRs-Fixed: 1092503 Change-Id: I8b32290ad1bc4a834a3edb68e25b212eee2951c1 --- core/dp/txrx/ol_txrx.c | 11 ++++++++++- core/dp/txrx/ol_txrx_peer_find.c | 32 +++++++++++++------------------- core/dp/txrx/ol_txrx_types.h | 1 + 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index ce8507e55725..839b4a7a9e0a 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -2214,9 +2214,18 @@ ol_txrx_peer_attach(void *pvdev, uint8_t *peer_mac_addr) /* keep one reference for attach */ qdf_atomic_inc(&peer->ref_cnt); - /* keep one reference for ol_rx_peer_map_handler */ + /* + * Set a flag to indicate peer create is pending in firmware and + * increment ref_cnt so that peer will not get deleted while + * peer create command is pending in firmware. + * First peer_map event from firmware signifies successful + * peer creation and it will be decremented in peer_map handling. + */ + qdf_atomic_init(&peer->fw_create_pending); + 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); diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c index 92ea155af73d..e287f25cfd1d 100644 --- a/core/dp/txrx/ol_txrx_peer_find.c +++ b/core/dp/txrx/ol_txrx_peer_find.c @@ -329,6 +329,10 @@ static void ol_txrx_peer_find_map_detach(struct ol_txrx_pdev_t *pdev) * its array of peer_id's and update the peer_id_to_obj map entry * for that peer_id. Increment corresponding reference counts. * + * Riva/Pronto has one peer id for each peer. + * Peregrine/Rome has two peer id for each peer. + * iHelium has upto three peer id for each peer. + * * Return: None */ static inline void ol_txrx_peer_find_add_id(struct ol_txrx_pdev_t *pdev, @@ -336,9 +340,7 @@ static inline void ol_txrx_peer_find_add_id(struct ol_txrx_pdev_t *pdev, { struct ol_txrx_peer_t *peer; int status; - int del_peer_ref = 0; int i; - bool found = false; /* check if there's already a peer object with this MAC address */ peer = @@ -370,15 +372,6 @@ static inline void ol_txrx_peer_find_add_id(struct ol_txrx_pdev_t *pdev, qdf_atomic_inc (&pdev->peer_id_to_obj_map[peer_id].peer_id_ref_cnt); - /* Check if entire peer_id array is empty */ - for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) { - if (peer->peer_ids[i] != HTT_INVALID_PEER) { - found = true; - break; - } - } - if (!found) - del_peer_ref = 1; status = 1; /* find a place in peer_id array and insert peer_id */ @@ -390,15 +383,16 @@ static inline void ol_txrx_peer_find_add_id(struct ol_txrx_pdev_t *pdev, } } - /* - * remove the reference added in ol_txrx_peer_find_hash_find. - * the reference for the first peer id is already added in - * ol_txrx_peer_attach. - * Riva/Pronto has one peer id for each peer. - * Peregrine/Rome has two peer id for each peer. - */ - if (del_peer_ref) + if (qdf_atomic_read(&peer->fw_create_pending) == 1) { + /* + * First peer map event signifies successful peer + * creation in firmware. Decrement the ref count + * which was incremented when peer create command + * was sent to firmware. + */ + qdf_atomic_set(&peer->fw_create_pending, 0); ol_txrx_peer_unref_delete(peer); + } qdf_spin_unlock(&pdev->peer_map_unmap_lock); diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h index 0a62ba308b0e..dee92df91814 100644 --- a/core/dp/txrx/ol_txrx_types.h +++ b/core/dp/txrx/ol_txrx_types.h @@ -1197,6 +1197,7 @@ struct ol_txrx_peer_t { qdf_time_t last_assoc_rcvd; qdf_time_t last_disassoc_rcvd; qdf_time_t last_deauth_rcvd; + qdf_atomic_t fw_create_pending; }; struct ol_rx_remote_data {