diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 269d84b838..6d254f75a5 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -880,6 +880,8 @@ static void dp_print_ast_stats(struct dp_soc *soc) DP_PRINT_STATS(" Entries Deleted = %d", soc->stats.ast.deleted); DP_PRINT_STATS(" Entries Agedout = %d", soc->stats.ast.aged_out); DP_PRINT_STATS("AST Table:"); + + qdf_spin_lock_bh(&soc->ast_lock); for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) { pdev = soc->pdev_list[i]; qdf_spin_lock_bh(&pdev->vdev_list_lock); @@ -912,6 +914,7 @@ static void dp_print_ast_stats(struct dp_soc *soc) } qdf_spin_unlock_bh(&pdev->vdev_list_lock); } + qdf_spin_unlock_bh(&soc->ast_lock); } #else static void dp_print_ast_stats(struct dp_soc *soc) @@ -3921,7 +3924,7 @@ static inline struct dp_peer *dp_peer_can_reuse(struct dp_vdev *vdev, if (peer->bss_peer) return peer; - qdf_atomic_dec(&peer->ref_cnt); + dp_peer_unref_delete(peer); return NULL; } #else @@ -3938,7 +3941,7 @@ static inline struct dp_peer *dp_peer_can_reuse(struct dp_vdev *vdev, if (peer->bss_peer && (peer->vdev->vdev_id == vdev->vdev_id)) return peer; - qdf_atomic_dec(&peer->ref_cnt); + dp_peer_unref_delete(peer); return NULL; } #endif diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 5b902eb1c1..ea2641b906 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -338,6 +338,34 @@ static inline void dp_peer_ast_hash_remove(struct dp_soc *soc, TAILQ_REMOVE(&soc->ast_hash.bins[index], ase, hash_list_elem); } +/* + * dp_peer_ast_list_find() - Find AST entry by MAC address from peer ast list + * @soc: SoC handle + * @peer: peer handle + * @ast_mac_addr: mac address + * + * It assumes caller has taken the ast lock to protect the access to ast list + * + * Return: AST entry + */ +struct dp_ast_entry *dp_peer_ast_list_find(struct dp_soc *soc, + struct dp_peer *peer, + uint8_t *ast_mac_addr) +{ + struct dp_ast_entry *ast_entry = NULL; + union dp_align_mac_addr *mac_addr = + (union dp_align_mac_addr *)ast_mac_addr; + + TAILQ_FOREACH(ast_entry, &peer->ast_entry_list, ase_list_elem) { + if (!dp_peer_find_mac_addr_cmp(mac_addr, + &ast_entry->mac_addr)) { + return ast_entry; + } + } + + return NULL; +} + /* * dp_peer_ast_hash_find_by_pdevid() - Find AST entry by MAC address * and pdev id @@ -418,9 +446,8 @@ static inline void dp_peer_map_ast(struct dp_soc *soc, struct dp_peer *peer, uint8_t *mac_addr, uint16_t hw_peer_id, uint8_t vdev_id, uint16_t ast_hash) { - struct dp_ast_entry *ast_entry; + struct dp_ast_entry *ast_entry = NULL; enum cdp_txrx_ast_entry_type peer_type = CDP_TXRX_AST_TYPE_STATIC; - bool ast_entry_found = FALSE; if (!peer) { return; @@ -433,19 +460,18 @@ static inline void dp_peer_map_ast(struct dp_soc *soc, mac_addr[4], mac_addr[5]); qdf_spin_lock_bh(&soc->ast_lock); - TAILQ_FOREACH(ast_entry, &peer->ast_entry_list, ase_list_elem) { - if (!(qdf_mem_cmp(mac_addr, ast_entry->mac_addr.raw, - DP_MAC_ADDR_LEN))) { - ast_entry->ast_idx = hw_peer_id; - soc->ast_table[hw_peer_id] = ast_entry; - ast_entry->is_active = TRUE; - peer_type = ast_entry->type; - ast_entry_found = TRUE; - ast_entry->ast_hash_value = ast_hash; - } + + ast_entry = dp_peer_ast_list_find(soc, peer, mac_addr); + + if (ast_entry) { + ast_entry->ast_idx = hw_peer_id; + soc->ast_table[hw_peer_id] = ast_entry; + ast_entry->is_active = TRUE; + peer_type = ast_entry->type; + ast_entry->ast_hash_value = ast_hash; } - if (ast_entry_found || (peer->vdev && peer->vdev->proxysta_vdev)) { + if (ast_entry || (peer->vdev && peer->vdev->proxysta_vdev)) { if (soc->cdp_soc.ol_ops->peer_map_event) { soc->cdp_soc.ol_ops->peer_map_event( soc->ctrl_psoc, peer->peer_ids[0], @@ -573,6 +599,7 @@ add_ast_entry: ast_entry->peer = peer; ast_entry->pdev_id = vdev->pdev->pdev_id; ast_entry->vdev_id = vdev->vdev_id; + ast_entry->ast_idx = DP_INVALID_AST_IDX; switch (type) { case CDP_TXRX_AST_TYPE_STATIC: @@ -1335,7 +1362,7 @@ void *dp_find_peer_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr, /* ref_cnt is incremented inside dp_peer_find_hash_find(). * Decrement it here. */ - qdf_atomic_dec(&peer->ref_cnt); + dp_peer_unref_delete(peer); return peer; } @@ -2513,7 +2540,7 @@ void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle, return NULL; if (peer->vdev != vdev) { - qdf_atomic_dec(&peer->ref_cnt); + dp_peer_unref_delete(peer); return NULL; } @@ -2523,7 +2550,7 @@ void *dp_find_peer_by_addr_and_vdev(struct cdp_pdev *pdev_handle, /* ref_cnt is incremented inside dp_peer_find_hash_find(). * Decrement it here. */ - qdf_atomic_dec(&peer->ref_cnt); + dp_peer_unref_delete(peer); return peer; } @@ -2596,7 +2623,7 @@ QDF_STATUS dp_peer_state_update(struct cdp_pdev *pdev_handle, uint8_t *peer_mac, /* ref_cnt is incremented inside dp_peer_find_hash_find(). * Decrement it here. */ - qdf_atomic_dec(&peer->ref_cnt); + dp_peer_unref_delete(peer); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 47c0f7c359..0e02808631 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -119,6 +119,10 @@ struct dp_ast_entry *dp_peer_ast_hash_find_by_pdevid(struct dp_soc *soc, struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc, uint8_t *ast_mac_addr); +struct dp_ast_entry *dp_peer_ast_list_find(struct dp_soc *soc, + struct dp_peer *peer, + uint8_t *ast_mac_addr); + uint8_t dp_peer_ast_get_pdev_id(struct dp_soc *soc, struct dp_ast_entry *ast_entry); diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 378f6c63b6..77f2610cc4 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -127,16 +127,18 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, * ast is not in ast_table, we use the below API to get * AST entry for STA's own mac_address. */ - ase = dp_peer_ast_hash_find(soc, - &data[DP_MAC_ADDR_LEN]); + ase = dp_peer_ast_list_find(soc, peer, + &data[DP_MAC_ADDR_LEN]); + if (ase) { + ase->ast_idx = sa_idx; + soc->ast_table[sa_idx] = ase; + } } } else ase = dp_peer_ast_hash_find(soc, &data[DP_MAC_ADDR_LEN]); if (ase) { - ase->ast_idx = sa_idx; - soc->ast_table[sa_idx] = ase; if (ase->pdev_id != vdev->pdev->pdev_id) { qdf_spin_unlock_bh(&soc->ast_lock); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 00c7a9598b..03651b0562 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -636,6 +636,7 @@ union dp_align_mac_addr { } align4_2; }; +#define DP_INVALID_AST_IDX 0xFFFF /* * dp_ast_entry *