diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index bae1bf01475b..5ae64ebcb6c2 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -749,6 +749,8 @@ struct ol_if_ops { int (*config_bssid_in_fw_for_nac_rssi)(struct wlan_objmgr_pdev *pdev, u_int8_t vdev_id, enum cdp_nac_param_cmd cmd, char *bssid); #endif + int (*peer_sta_kickout)(void *osif_pdev, uint8_t *peer_macaddr); + /* TODO: Add any other control path calls required to OL_IF/WMA layer */ }; diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index ffce0982913d..d233d3481959 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -546,8 +546,25 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer, { int ret = -1; struct dp_peer *old_peer; + struct dp_peer *sa_peer; - qdf_spin_lock_bh(&soc->ast_lock); + if (ast_entry->type == CDP_TXRX_AST_TYPE_STATIC) { + sa_peer = ast_entry->peer; + + /* + * Kickout, when direct associated peer(SA) roams + * to another AP and reachable via TA peer + */ + if (!sa_peer->delete_in_progress) { + sa_peer->delete_in_progress = true; + if (soc->cdp_soc.ol_ops->peer_sta_kickout) { + soc->cdp_soc.ol_ops->peer_sta_kickout( + sa_peer->vdev->pdev->osif_pdev, + ast_entry->mac_addr.raw); + } + return 0; + } + } old_peer = ast_entry->peer; TAILQ_REMOVE(&old_peer->ast_entry_list, ast_entry, ase_list_elem); @@ -559,19 +576,11 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer, ast_entry->is_active = TRUE; TAILQ_INSERT_TAIL(&peer->ast_entry_list, ast_entry, ase_list_elem); - if (ast_entry->type != CDP_TXRX_AST_TYPE_STATIC) { - if (QDF_STATUS_SUCCESS == - soc->cdp_soc.ol_ops->peer_update_wds_entry( - peer->vdev->osif_vdev, + ret = soc->cdp_soc.ol_ops->peer_update_wds_entry( + peer->vdev->osif_vdev, ast_entry->mac_addr.raw, peer->mac_addr.raw, - flags)) { - qdf_spin_unlock_bh(&soc->ast_lock); - return 0; - } - } - - qdf_spin_unlock_bh(&soc->ast_lock); + flags); return ret; } diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index e3b7ed9bc257..3744dfd4b150 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -366,6 +366,8 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc, uint32_t flags = IEEE80211_NODE_F_WDS_HM; uint32_t ret = 0; uint8_t wds_src_mac[IEEE80211_ADDR_LEN]; + struct dp_ast_entry *ast; + uint16_t sa_idx; /* Do wds source port learning only if it is a 4-address mpdu */ if (!(qdf_nbuf_is_rx_chfrag_start(nbuf) && @@ -381,32 +383,42 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc, wds_src_mac, CDP_TXRX_AST_TYPE_WDS, flags); + return; - } else { - /* - * Get the AST entry from HW SA index and mark it as active - */ - struct dp_ast_entry *ast; - uint16_t sa_idx = hal_rx_msdu_end_sa_idx_get(rx_tlv_hdr); - ast = soc->ast_table[sa_idx]; - - /* - * Ensure we are updating the right AST entry by - * validating ast_idx. - * There is a possibility we might arrive here without - * AST MAP event , so this check is mandatory - */ - if (ast && (ast->ast_idx == sa_idx)) { - ast->is_active = TRUE; - } - - if (ast && sa_sw_peer_id != ta_peer->peer_ids[0]) - dp_peer_update_ast(soc, ta_peer, ast, flags); } + + /* + * Get the AST entry from HW SA index and mark it as active + */ + sa_idx = hal_rx_msdu_end_sa_idx_get(rx_tlv_hdr); + + qdf_spin_lock_bh(&soc->ast_lock); + ast = soc->ast_table[sa_idx]; + + if (!ast) { + qdf_spin_unlock_bh(&soc->ast_lock); + return; + } + + /* + * Ensure we are updating the right AST entry by + * validating ast_idx. + * There is a possibility we might arrive here without + * AST MAP event , so this check is mandatory + */ + if (ast->ast_idx == sa_idx) + ast->is_active = TRUE; + + /* Handle client roaming */ + if (sa_sw_peer_id != ta_peer->peer_ids[0]) + dp_peer_update_ast(soc, ta_peer, ast, flags); + + qdf_spin_unlock_bh(&soc->ast_lock); + return; } #else - static inline void +static inline void dp_rx_wds_srcport_learn(struct dp_soc *soc, uint8_t *rx_tlv_hdr, struct dp_peer *ta_peer, @@ -417,7 +429,7 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc, uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf); void dp_rx_process_invalid_peer_wrapper(struct dp_soc *soc, - qdf_nbuf_t mpdu, bool mpdu_done); + qdf_nbuf_t mpdu, bool mpdu_done); void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr); #define DP_RX_LIST_APPEND(head, tail, elem) \ @@ -428,19 +440,19 @@ void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tl qdf_nbuf_set_next((tail), (elem)); \ } \ (tail) = (elem); \ - qdf_nbuf_set_next((tail), NULL); \ -} while (0) + qdf_nbuf_set_next((tail), NULL); \ + } while (0) #ifndef BUILD_X86 static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf, - qdf_dma_addr_t *paddr, struct dp_pdev *pdev) + qdf_dma_addr_t *paddr, struct dp_pdev *pdev) { return QDF_STATUS_SUCCESS; } #else #define MAX_RETRY 100 static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf, - qdf_dma_addr_t *paddr, struct dp_pdev *pdev) + qdf_dma_addr_t *paddr, struct dp_pdev *pdev) { uint32_t nbuf_retry = 0; int32_t ret; @@ -455,13 +467,13 @@ static inline int check_x86_paddr(struct dp_soc *dp_soc, qdf_nbuf_t *rx_netbuf, return QDF_STATUS_SUCCESS; else { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - "phy addr %pK exceded 0x50000000 trying again\n", - paddr); + "phy addr %pK exceded 0x50000000 trying again\n", + paddr); nbuf_retry++; if ((*rx_netbuf)) { qdf_nbuf_unmap_single(dp_soc->osdev, *rx_netbuf, - QDF_DMA_BIDIRECTIONAL); + QDF_DMA_BIDIRECTIONAL); /* Not freeing buffer intentionally. * Observed that same buffer is getting * re-allocated resulting in longer load time