From 7c8cf12b76031f78a218a38874f271cff80ae5cb Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Fri, 7 Sep 2018 19:23:52 +0530 Subject: [PATCH] qcacmn: add API to get ast entry from peer ast list We are adding AST entry to ast_table from dp_rx_mcast_echo_check in STA mode as in STA mode we will not get the peer map event. Find AST entry from the peer ast list to get ast entry added in host for that particular peer. As in QWRAP mode there can exist multiple peers with same mac address and corresponding AST entries will be added Change-Id: Ia75f88c03c4d0eba0edbebf8e8f40d41396543d5 CRs-fixed: 2307540 --- dp/wifi3.0/dp_main.c | 7 +++-- dp/wifi3.0/dp_peer.c | 61 ++++++++++++++++++++++++++++++------------ dp/wifi3.0/dp_peer.h | 4 +++ dp/wifi3.0/dp_rx_err.c | 10 ++++--- dp/wifi3.0/dp_types.h | 1 + 5 files changed, 60 insertions(+), 23 deletions(-) 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 *