From cc943caa7ef3fa988b372e3eebc573a245b862b9 Mon Sep 17 00:00:00 2001 From: Alok Kumar Date: Thu, 5 Jul 2018 18:48:14 +0530 Subject: [PATCH] qcacld-3.0: Add support to set/get timestamp for management frames Add setter and getter function of timestamp for management frames for the peer based on peer's mac address. Change-Id: Iab0862eda2392bd516c8ba0b913441b8e0d4c493 CRs-Fixed: 2264667 --- core/dp/txrx/ol_txrx.c | 125 ++++++++++++++++++++++++------- core/dp/txrx/ol_txrx_peer_find.c | 2 +- core/dp/txrx/ol_txrx_peer_find.h | 4 + core/wma/src/wma_mgmt.c | 78 ++++++------------- 4 files changed, 128 insertions(+), 81 deletions(-) diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 5111a2dae5fc..0038db0456a5 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -5968,42 +5968,116 @@ static uint16_t ol_txrx_get_vdev_id(struct cdp_vdev *pvdev) } /** - * ol_txrx_last_assoc_received() - get time of last assoc received - * @ppeer: peer handle + * ol_txrx_get_last_mgmt_timestamp() - get timestamp of last mgmt frame + * @pdev: pdev handle + * @ppeer_addr: peer mac addr + * @subtype: management frame type + * @timestamp: last timestamp * - * Return: pointer of the time of last assoc received + * Return: true if timestamp is retrieved for valid peer else false */ -static qdf_time_t *ol_txrx_last_assoc_received(void *ppeer) +static bool +ol_txrx_get_last_mgmt_timestamp(struct cdp_pdev *ppdev, + u8 *peer_addr, + u8 subtype, + qdf_time_t *timestamp) { - ol_txrx_peer_handle peer = ppeer; + /* + * Take the lock, find the peer based on peer mac addr. + * If peer is valid, retrieve the timestamp for "subtype" mgmt frame. + * release the lock + */ + union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr; + unsigned int index; + struct ol_txrx_peer_t *peer; + bool ret = false; + struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; - return &peer->last_assoc_rcvd; + qdf_mem_copy(&local_mac_addr_aligned.raw[0], + peer_addr, OL_TXRX_MAC_ADDR_LEN); + mac_addr = &local_mac_addr_aligned; + + index = ol_txrx_peer_find_hash_index(pdev, mac_addr); + qdf_spin_lock_bh(&pdev->peer_ref_mutex); + TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) { + if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == + 0 && (peer->valid)) { + /* found it */ + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: + *timestamp = peer->last_assoc_rcvd; + ret = true; + break; + case IEEE80211_FC0_SUBTYPE_DISASSOC: + case IEEE80211_FC0_SUBTYPE_DEAUTH: + *timestamp = peer->last_disassoc_rcvd; + ret = true; + break; + default: + break; + } + qdf_spin_unlock_bh(&pdev->peer_ref_mutex); + return ret; + } + } + qdf_spin_unlock_bh(&pdev->peer_ref_mutex); + return false; /* failure */ } /** - * ol_txrx_last_disassoc_received() - get time of last disassoc received - * @ppeer: peer handle + * ol_txrx_update_last_mgmt_timestamp() - set timestamp of last mgmt frame + * @pdev: pdev handle + * @ppeer_addr: peer mac addr + * @timestamp: time to be set + * @subtype: management frame type * - * Return: pointer of the time of last disassoc received + * Return: true if timestamp is updated for valid peer else false */ -static qdf_time_t *ol_txrx_last_disassoc_received(void *ppeer) +static bool +ol_txrx_update_last_mgmt_timestamp(struct cdp_pdev *ppdev, u8 *peer_addr, + qdf_time_t timestamp, u8 subtype) { - ol_txrx_peer_handle peer = ppeer; + /* + * Take the lock, find the peer based on peer mac addr. + * If peer is valid, update the timestamp for "subtype" mgmt frame. + * release the lock + */ + union ol_txrx_align_mac_addr_t local_mac_addr_aligned, *mac_addr; + bool ret = false; + unsigned int index; + struct ol_txrx_peer_t *peer; + struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)ppdev; - return &peer->last_disassoc_rcvd; -} + qdf_mem_copy(&local_mac_addr_aligned.raw[0], + peer_addr, OL_TXRX_MAC_ADDR_LEN); + mac_addr = &local_mac_addr_aligned; -/** - * ol_txrx_last_deauth_received() - get time of last deauth received - * @ppeer: peer handle - * - * Return: pointer of the time of last deauth received - */ -static qdf_time_t *ol_txrx_last_deauth_received(void *ppeer) -{ - ol_txrx_peer_handle peer = ppeer; + index = ol_txrx_peer_find_hash_index(pdev, mac_addr); + qdf_spin_lock_bh(&pdev->peer_ref_mutex); + TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) { + if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == + 0 && (peer->valid)) { + /* found it */ + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: + peer->last_assoc_rcvd = timestamp; + ret = true; + break; + case IEEE80211_FC0_SUBTYPE_DISASSOC: + case IEEE80211_FC0_SUBTYPE_DEAUTH: + peer->last_disassoc_rcvd = timestamp; + ret = true; + break; + default: + break; + } + qdf_spin_unlock_bh(&pdev->peer_ref_mutex); + return ret; + } + } + qdf_spin_unlock_bh(&pdev->peer_ref_mutex); - return &peer->last_deauth_rcvd; + return false; /* failure */ } /** @@ -6410,10 +6484,9 @@ static struct cdp_peer_ops ol_ops_peer = { .is_vdev_restore_last_peer = is_vdev_restore_last_peer, .update_last_real_peer = ol_txrx_update_last_real_peer, #endif /* CONFIG_HL_SUPPORT */ - .last_assoc_received = ol_txrx_last_assoc_received, - .last_disassoc_received = ol_txrx_last_disassoc_received, - .last_deauth_received = ol_txrx_last_deauth_received, .peer_detach_force_delete = ol_txrx_peer_detach_force_delete, + .get_last_mgmt_timestamp = ol_txrx_get_last_mgmt_timestamp, + .update_last_mgmt_timestamp = ol_txrx_update_last_mgmt_timestamp, }; static struct cdp_tx_delay_ops ol_ops_delay = { diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c index d007c47554cd..48a49f3b8201 100644 --- a/core/dp/txrx/ol_txrx_peer_find.c +++ b/core/dp/txrx/ol_txrx_peer_find.c @@ -145,7 +145,7 @@ static void ol_txrx_peer_find_hash_detach(struct ol_txrx_pdev_t *pdev) qdf_mem_free(pdev->peer_hash.bins); } -static inline unsigned int +unsigned int ol_txrx_peer_find_hash_index(struct ol_txrx_pdev_t *pdev, union ol_txrx_align_mac_addr_t *mac_addr) { diff --git a/core/dp/txrx/ol_txrx_peer_find.h b/core/dp/txrx/ol_txrx_peer_find.h index a3d6c37a4464..607e095a63a9 100644 --- a/core/dp/txrx/ol_txrx_peer_find.h +++ b/core/dp/txrx/ol_txrx_peer_find.h @@ -90,6 +90,10 @@ struct ol_txrx_peer_t *ol_txrx_peer_find_by_id(struct ol_txrx_pdev_t *pdev, return NULL; } +unsigned int +ol_txrx_peer_find_hash_index(struct ol_txrx_pdev_t *pdev, + union ol_txrx_align_mac_addr_t *mac_addr); + void ol_txrx_peer_find_hash_add(struct ol_txrx_pdev_t *pdev, struct ol_txrx_peer_t *peer); diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 90c0123f2a52..fcba5a0de0d0 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -3707,11 +3707,10 @@ static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle, uint8_t *peer_addr, uint8_t *bssid, uint8_t subtype) { - void *peer = NULL; struct cdp_pdev *pdev_ctx; - uint8_t peer_id; bool should_drop = false; - qdf_time_t *ptr; + qdf_time_t timestamp; + bool ret; void *soc = cds_get_context(QDF_MODULE_ID_SOC); uint8_t nan_addr[] = {0x50, 0x6F, 0x9A, 0x01, 0x00, 0x00}; @@ -3741,63 +3740,34 @@ static bool wma_is_pkt_drop_candidate(tp_wma_handle wma_handle, goto end; } - peer = cdp_peer_get_ref_by_addr(soc, pdev_ctx, peer_addr, &peer_id, - PEER_DEBUG_ID_WMA_PKT_DROP); - if (!peer) { + ret = cdp_peer_get_last_mgmt_timestamp(soc, pdev_ctx, + peer_addr, subtype, + ×tamp); + + if (!ret) { if (IEEE80211_FC0_SUBTYPE_ASSOC_REQ != subtype) { - WMA_LOGI( - FL("Received mgmt frame: %0x from unknown peer: %pM"), - subtype, peer_addr); + WMA_LOGE(FL("cdp_last_mgmt_timestamp_received %s 0x%x"), + "failed for subtype", subtype); should_drop = true; } goto end; + } else if (timestamp > 0 && + qdf_system_time_before(qdf_get_system_timestamp(), + timestamp + + WMA_MGMT_FRAME_DETECT_DOS_TIMER)) { + WMA_LOGD(FL("Dropping subtype 0x%x frame. %s %d ms %s %d ms"), + subtype, "It is received after", + (int)(qdf_get_system_timestamp() - timestamp), + "of last frame. Allow it only after", + WMA_MGMT_FRAME_DETECT_DOS_TIMER); + should_drop = true; + goto end; } - - switch (subtype) { - case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - ptr = cdp_peer_last_assoc_received(soc, peer); - if (!ptr) { - WMA_LOGE(FL("cdp_peer_last_assoc_received Failed")); - should_drop = true; - goto end; - } else if (*ptr > 0 && - qdf_system_time_before(qdf_get_system_timestamp(), - *ptr + WMA_MGMT_FRAME_DETECT_DOS_TIMER)) { - WMA_LOGD(FL("Dropping Assoc Req as it is received after %d ms of last frame. Allow it only after %d ms"), - (int)(qdf_get_system_timestamp() - *ptr), - WMA_MGMT_FRAME_DETECT_DOS_TIMER); - should_drop = true; - break; - } - *ptr = qdf_get_system_timestamp(); - break; - case IEEE80211_FC0_SUBTYPE_DISASSOC: - case IEEE80211_FC0_SUBTYPE_DEAUTH: - ptr = cdp_peer_last_disassoc_received(soc, peer); - if (!ptr) { - WMA_LOGE(FL("cdp_peer_last_disassoc_received Failed")); - should_drop = true; - goto end; - } else if (*ptr > 0 && - qdf_system_time_before(qdf_get_system_timestamp(), - *ptr + WMA_MGMT_FRAME_DETECT_DOS_TIMER)) { - WMA_LOGD(FL("Dropping subtype %x frame as it is received after %d ms of last frame. Allow it only after %d ms"), - subtype, (int) - (qdf_get_system_timestamp() - *ptr), - WMA_MGMT_FRAME_DETECT_DOS_TIMER); - should_drop = true; - break; - } - *ptr = qdf_get_system_timestamp(); - break; - default: - break; - } - + if (!cdp_peer_update_last_mgmt_timestamp(soc, pdev_ctx, peer_addr, + qdf_get_system_timestamp(), + subtype)) + should_drop = true; end: - if (peer) - cdp_peer_release_ref(soc, peer, PEER_DEBUG_ID_WMA_PKT_DROP); - return should_drop; }