diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 80c2913ce5..d38015c251 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -1035,9 +1035,8 @@ struct cdp_ocb_ops { * @remove_peers_for_vdev_no_lock: * @copy_mac_addr_raw: * @add_last_real_peer: - * @last_assoc_received: - * @last_disassoc_received: - * @last_deauth_received: + * @get_last_mgmt_timestamp: + * @set_last_mgmt_timestamp: * @is_vdev_restore_last_peer: * @update_last_real_peer: */ @@ -1081,13 +1080,18 @@ struct cdp_peer_ops { void (*copy_mac_addr_raw)(struct cdp_vdev *vdev, uint8_t *bss_addr); void (*add_last_real_peer)(struct cdp_pdev *pdev, struct cdp_vdev *vdev, uint8_t *peer_id); - qdf_time_t * (*last_assoc_received)(void *peer); - qdf_time_t * (*last_disassoc_received)(void *peer); - qdf_time_t * (*last_deauth_received)(void *peer); bool (*is_vdev_restore_last_peer)(void *peer); void (*update_last_real_peer)(struct cdp_pdev *pdev, void *peer, uint8_t *peer_id, bool restore_last_peer); void (*peer_detach_force_delete)(void *peer); + bool (*get_last_mgmt_timestamp)(struct cdp_pdev *ppdev, + u8 *peer_addr, + u8 subtype, + qdf_time_t *timestamp); + bool (*update_last_mgmt_timestamp)(struct cdp_pdev *ppdev, + u8 *peer_addr, + qdf_time_t timestamp, + u8 subtype); }; /** diff --git a/dp/inc/cdp_txrx_peer_ops.h b/dp/inc/cdp_txrx_peer_ops.h index 81a74a6267..fdcc45898d 100644 --- a/dp/inc/cdp_txrx_peer_ops.h +++ b/dp/inc/cdp_txrx_peer_ops.h @@ -568,78 +568,65 @@ cdp_peer_add_last_real_peer(ol_txrx_soc_handle soc, } /** - * cdp_peer_last_assoc_received() - last assoc received peer + * cdp_peer_get_last_mgmt_timestamp() - retrieve last timestamp for peer * @soc - data path soc handle - * @peer - peer instance pointer + * @pdev - data path device instance + * @peer_addr - peer mac addr + * @subtype - Management frame subtype * - * !!! This should be implemented on legacy also - * last assoc received peer - * - * Return: pointer + * Return: true/false */ -static inline qdf_time_t * -cdp_peer_last_assoc_received(ol_txrx_soc_handle soc, void *peer) +static inline bool +cdp_peer_get_last_mgmt_timestamp(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev, + u8 *peer_addr, + u8 subtype, + qdf_time_t *timestamp) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return NULL; + "%s invalid instance", __func__); + return 0; } - if (soc->ops->peer_ops->last_assoc_received) - return soc->ops->peer_ops->last_assoc_received(peer); + if (soc->ops->peer_ops->get_last_mgmt_timestamp) { + return soc->ops->peer_ops-> + get_last_mgmt_timestamp(pdev, peer_addr, + subtype, timestamp); + } - return NULL; + return false; } /** - * cdp_peer_last_disassoc_received() - last disassoc received peer + * cdp_peer_update_last_mgmt_timestamp() - update timestamp for the peer * @soc - data path soc handle - * @peer - peer instance pointer + * @pdev - data path device instance + * @peer_addr - peer mac addr + * @subtype - Management frame subtype * - * !!! This should be implemented on legacy also - * last disassoc received peer - * - * Return: pointer + * Return: true/false */ -static inline qdf_time_t * -cdp_peer_last_disassoc_received(ol_txrx_soc_handle soc, void *peer) +static inline bool +cdp_peer_update_last_mgmt_timestamp(ol_txrx_soc_handle soc, + struct cdp_pdev *pdev, + u8 *peer_addr, + qdf_time_t timestamp, + u8 subtype) { if (!soc || !soc->ops || !soc->ops->peer_ops) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return NULL; + "%s invalid instance", __func__); + return false; } - if (soc->ops->peer_ops->last_disassoc_received) - return soc->ops->peer_ops->last_disassoc_received(peer); - - return NULL; -} - -/** - * cdp_peer_last_deauth_received() - last deauth received peer - * @soc - data path soc handle - * @peer - peer instance pointer - * - * !!! This should be implemented on legacy also - * last deauth received peer - * - * Return: pointer - */ -static inline qdf_time_t * -cdp_peer_last_deauth_received(ol_txrx_soc_handle soc, void *peer) -{ - if (!soc || !soc->ops || !soc->ops->peer_ops) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, - "%s invalid instance", __func__); - return NULL; + if (soc->ops->peer_ops->update_last_mgmt_timestamp) { + return soc->ops->peer_ops-> + update_last_mgmt_timestamp(pdev, peer_addr, + timestamp, subtype); } - if (soc->ops->peer_ops->last_deauth_received) - return soc->ops->peer_ops->last_deauth_received(peer); - - return NULL; + return false; } /** diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 2e3622fb13..3bb13aa460 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -364,9 +364,10 @@ int dp_get_peer_state(void *peer_handle); void dp_local_peer_id_pool_init(struct dp_pdev *pdev); void dp_local_peer_id_alloc(struct dp_pdev *pdev, struct dp_peer *peer); void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer); -qdf_time_t *dp_get_last_assoc_received(void *peer_handle); -qdf_time_t *dp_get_last_disassoc_received(void *peer_handle); -qdf_time_t *dp_get_last_deauth_received(void *peer_handle); +bool dp_get_last_mgmt_timestamp(struct cdp_pdev *ppdev, u8 *peer_addr, + u8 subtype, qdf_time_t *timestamp); +bool dp_update_last_mgmt_timestamp(struct cdp_pdev *ppdev, u8 *peer_addr, + qdf_time_t timestamp, u8 subtype); #else static inline void dp_local_peer_id_pool_init(struct dp_pdev *pdev) { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 436b16944b..12b6ec7c66 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -7417,9 +7417,8 @@ static struct cdp_peer_ops dp_ops_peer = { .peer_get_peer_mac_addr = dp_peer_get_peer_mac_addr, .get_vdev_for_peer = dp_get_vdev_for_peer, .get_peer_state = dp_get_peer_state, - .last_assoc_received = dp_get_last_assoc_received, - .last_disassoc_received = dp_get_last_disassoc_received, - .last_deauth_received = dp_get_last_deauth_received, + .get_last_mgmt_timestamp = dp_get_last_mgmt_timestamp, + .update_last_mgmt_timestamp = dp_update_last_mgmt_timestamp, }; #endif diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index ca2e9ba6cc..2a93da13e1 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -2174,48 +2174,125 @@ int dp_get_peer_state(void *peer_handle) } /** - * dp_get_last_assoc_received() - get time of last assoc received - * @peer_handle: peer handle + * dp_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 for the time of last assoc received + * Return: true if timestamp is retrieved for valid peer else false */ -qdf_time_t *dp_get_last_assoc_received(void *peer_handle) +bool dp_get_last_mgmt_timestamp(struct cdp_pdev *ppdev, u8 *peer_addr, + u8 subtype, qdf_time_t *timestamp) { - struct dp_peer *peer = peer_handle; + union dp_align_mac_addr local_mac_addr_aligned, *mac_addr; + unsigned int index; + struct dp_peer *peer; + struct dp_soc *soc; - DP_TRACE(INFO, "peer %pK last_assoc_rcvd: %lu", peer, - peer->last_assoc_rcvd); - return &peer->last_assoc_rcvd; + bool ret = false; + struct dp_pdev *pdev = (struct dp_pdev *)ppdev; + + soc = pdev->soc; + qdf_mem_copy( + &local_mac_addr_aligned.raw[0], + peer_addr, DP_MAC_ADDR_LEN); + mac_addr = &local_mac_addr_aligned; + + index = dp_peer_find_hash_index(soc, mac_addr); + + qdf_spin_lock_bh(&soc->peer_ref_mutex); + TAILQ_FOREACH(peer, &soc->peer_hash.bins[index], hash_list_elem) { +#if ATH_SUPPORT_WRAP + /* ProxySTA may have multiple BSS peer with same MAC address, + * modified find will take care of finding the correct BSS peer. + */ + if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 && + (peer->vdev->vdev_id == DP_VDEV_ALL)) { +#else + if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0) { +#endif + /* 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(&soc->peer_ref_mutex); + return ret; + } + } + qdf_spin_unlock_bh(&soc->peer_ref_mutex); + return false; /*failure*/ } /** - * dp_get_last_disassoc_received() - get time of last disassoc received - * @peer_handle: peer handle + * dp_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 for the time of last disassoc received + * Return: true if timestamp is updated for valid peer else false */ -qdf_time_t *dp_get_last_disassoc_received(void *peer_handle) + +bool dp_update_last_mgmt_timestamp(struct cdp_pdev *ppdev, u8 *peer_addr, + qdf_time_t timestamp, u8 subtype) { - struct dp_peer *peer = peer_handle; + union dp_align_mac_addr local_mac_addr_aligned, *mac_addr; + unsigned int index; + struct dp_peer *peer; + struct dp_soc *soc; - DP_TRACE(INFO, "peer %pK last_disassoc_rcvd: %lu", peer, - peer->last_disassoc_rcvd); - return &peer->last_disassoc_rcvd; -} + bool ret = false; + struct dp_pdev *pdev = (struct dp_pdev *)ppdev; -/** - * dp_get_last_deauth_received() - get time of last deauth received - * @peer_handle: peer handle - * - * Return: pointer for the time of last deauth received - */ -qdf_time_t *dp_get_last_deauth_received(void *peer_handle) -{ - struct dp_peer *peer = peer_handle; + soc = pdev->soc; + qdf_mem_copy(&local_mac_addr_aligned.raw[0], + peer_addr, DP_MAC_ADDR_LEN); + mac_addr = &local_mac_addr_aligned; - DP_TRACE(INFO, "peer %pK last_deauth_rcvd: %lu", peer, - peer->last_deauth_rcvd); - return &peer->last_deauth_rcvd; + index = dp_peer_find_hash_index(soc, mac_addr); + + qdf_spin_lock_bh(&soc->peer_ref_mutex); + TAILQ_FOREACH(peer, &soc->peer_hash.bins[index], hash_list_elem) { +#if ATH_SUPPORT_WRAP + /* ProxySTA may have multiple BSS peer with same MAC address, + * modified find will take care of finding the correct BSS peer. + */ + if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0 && + (peer->vdev->vdev_id == DP_VDEV_ALL)) { +#else + if (dp_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) == 0) { +#endif + /* 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(&soc->peer_ref_mutex); + return ret; + } + } + qdf_spin_unlock_bh(&soc->peer_ref_mutex); + return false; /*failure*/ } /**