diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 9d4c67051d..4201f8f68c 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1476,7 +1476,7 @@ static void dp_wds_aging_timer_fn(void *soc_hdl) struct dp_pdev *pdev; struct dp_vdev *vdev; struct dp_peer *peer; - struct dp_ast_entry *ase; + struct dp_ast_entry *ase, *temp_ase; int i; qdf_spin_lock_bh(&soc->ast_lock); @@ -1485,7 +1485,7 @@ static void dp_wds_aging_timer_fn(void *soc_hdl) pdev = soc->pdev_list[i]; DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev) { DP_VDEV_ITERATE_PEER_LIST(vdev, peer) { - DP_PEER_ITERATE_ASE_LIST(peer, ase) { + DP_PEER_ITERATE_ASE_LIST(peer, ase, temp_ase) { /* * Do not expire static ast entries */ @@ -4730,12 +4730,12 @@ static struct cdp_wds_ops dp_ops_wds = { static inline void dp_peer_delete_ast_entries(struct dp_soc *soc, struct dp_peer *peer) { - struct dp_ast_entry *ast_entry; + struct dp_ast_entry *ast_entry, *temp_ast_entry; qdf_spin_lock_bh(&soc->ast_lock); - DP_PEER_ITERATE_ASE_LIST(peer, ast_entry) { + DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, temp_ast_entry) { if (ast_entry->next_hop) { soc->cdp_soc.ol_ops->peer_del_wds_entry( - soc->osif_soc, + peer->vdev->pdev->osif_pdev, ast_entry->mac_addr.raw); } diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index d66c6b2821..3f3afc26b6 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -375,10 +375,10 @@ static inline void dp_peer_map_ast(struct dp_soc *soc, 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))) { - qdf_spin_unlock_bh(&soc->ast_lock); ast_entry->ast_idx = hw_peer_id; soc->ast_table[hw_peer_id] = ast_entry; ast_entry->is_active = TRUE; + qdf_spin_unlock_bh(&soc->ast_lock); return; } } @@ -415,7 +415,11 @@ int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer, qdf_spin_lock_bh(&soc->ast_lock); /* If AST entry already exists , just return from here */ - if (dp_peer_ast_hash_find(soc, mac_addr, 0)) { + ast_entry = dp_peer_ast_hash_find(soc, mac_addr, 0); + if (ast_entry) { + if (ast_entry->is_mec) + ast_entry->is_active = TRUE; + qdf_spin_unlock_bh(&soc->ast_lock); return 1; } diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 3b1cc31b44..e354c2b1ec 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -54,14 +54,14 @@ void dp_rx_sec_ind_handler(void *soc_handle, uint16_t peer_id, uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle, uint16_t peer_id, uint8_t *peer_mac); -struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc, - uint8_t *ast_mac_addr, int mac_addr_is_aligned); #ifdef FEATURE_WDS int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer, uint8_t *mac_addr, uint8_t is_self); void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry); +struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc, + uint8_t *ast_mac_addr, int mac_addr_is_aligned); #else static inline int dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer, uint8_t *mac_addr, uint8_t is_self) @@ -72,6 +72,11 @@ static inline void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry) { } +static inline struct dp_ast_entry *dp_peer_ast_hash_find(struct dp_soc *soc, + uint8_t *ast_mac_addr, int mac_addr_is_aligned) +{ + return NULL; +} #endif #ifdef DP_LFR diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index d78dba5a88..655f50ad4e 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -274,6 +274,9 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, uint16_t peer_id = 0xFFFF; struct dp_peer *peer = NULL; uint32_t sgi, rate_mcs, tid; + struct dp_ast_entry *ase; + uint16_t sa_idx; + uint8_t *data; rx_bufs_used++; @@ -353,13 +356,11 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, * This is a Multicast echo check, drop the pkt if we meet * the Multicast Echo Check condition */ + data = qdf_nbuf_data(nbuf); + qdf_spin_lock_bh(&soc->ast_lock); if (hal_rx_msdu_end_sa_is_valid_get(rx_desc->rx_buf_start)) { - struct dp_ast_entry *ase; - uint16_t sa_idx; - uint8_t *nbuf_data = NULL; - - nbuf_data = qdf_nbuf_data(nbuf); sa_idx = hal_rx_msdu_end_sa_idx_get(rx_desc->rx_buf_start); + if ((sa_idx < 0) || (sa_idx > (WLAN_UMAC_PSOC_MAX_PEERS * 2))) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "invalid sa_idx: %d", sa_idx); @@ -367,18 +368,22 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, } ase = soc->ast_table[sa_idx]; - if (ase) { - if (ase->is_mec || (ase->peer != peer)) { - QDF_TRACE(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_INFO, - "received pkt with same src mac %pM", - &nbuf_data[DP_MAC_ADDR_LEN]); + } else + ase = dp_peer_ast_hash_find(soc, &data[DP_MAC_ADDR_LEN], 0); - qdf_nbuf_free(nbuf); - goto fail; - } + if (ase) { + if (ase->is_mec || (ase->peer != peer)) { + qdf_spin_unlock_bh(&soc->ast_lock); + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_INFO, + "received pkt with same src mac %pM", + &data[DP_MAC_ADDR_LEN]); + + qdf_nbuf_free(nbuf); + goto fail; } } + qdf_spin_unlock_bh(&soc->ast_lock); /* WDS Source Port Learning */ if (qdf_likely(vdev->rx_decap_type == htt_cmn_pkt_type_ethernet)) diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index d8386f5e47..e26ea60264 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -105,8 +105,8 @@ union dp_rx_desc_list_elem_t; #define DP_VDEV_ITERATE_PEER_LIST(_vdev, _peer) \ TAILQ_FOREACH((_peer), &(_vdev)->peer_list, peer_list_elem) -#define DP_PEER_ITERATE_ASE_LIST(_peer, _ase) \ - TAILQ_FOREACH((_ase), &peer->ast_entry_list, ase_list_elem) +#define DP_PEER_ITERATE_ASE_LIST(_peer, _ase, _temp_ase) \ + TAILQ_FOREACH_SAFE((_ase), &peer->ast_entry_list, ase_list_elem, (_temp_ase)) #define DP_MUTEX_TYPE qdf_spinlock_t