diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 117f4d7d33..712efd00de 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -723,8 +723,9 @@ bool dp_peer_ast_get_wmi_sent_wifi3(struct cdp_soc_t *soc_handle, bool wmi_sent = false; qdf_spin_lock_bh(&soc->ast_lock); - wmi_sent = dp_peer_ast_get_wmi_sent(soc, - (struct dp_ast_entry *)ast_entry); + wmi_sent = dp_peer_ast_get_del_cmd_sent(soc, + (struct dp_ast_entry *) + ast_entry); qdf_spin_unlock_bh(&soc->ast_lock); return wmi_sent; @@ -951,7 +952,7 @@ static void dp_print_ast_stats(struct dp_soc *soc) " ast_hash = %d" " pdev_id = %d" " vdev_id = %d" - " wmi_sent = %d", + " del_cmd_sent = %d", ++num_entries, ase->mac_addr.raw, ase->peer->mac_addr.raw, @@ -963,7 +964,7 @@ static void dp_print_ast_stats(struct dp_soc *soc) ase->ast_hash_value, ase->pdev_id, ase->vdev_id, - ase->wmi_sent); + ase->del_cmd_sent); } } } @@ -4071,7 +4072,8 @@ static inline struct dp_peer *dp_peer_can_reuse(struct dp_vdev *vdev, } #endif -#if defined(FEATURE_AST) && !defined(AST_HKV1_WORKAROUND) +#if defined(FEATURE_AST) +#if !defined(AST_HKV1_WORKAROUND) static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc, uint8_t *peer_mac_addr) { @@ -4084,6 +4086,21 @@ static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc, qdf_spin_unlock_bh(&soc->ast_lock); } #else +static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc, + uint8_t *peer_mac_addr) +{ + struct dp_ast_entry *ast_entry; + + if (soc->ast_override_support) { + qdf_spin_lock_bh(&soc->ast_lock); + ast_entry = dp_peer_ast_hash_find_soc(soc, peer_mac_addr); + if (ast_entry && ast_entry->next_hop) + dp_peer_del_ast(soc, ast_entry); + qdf_spin_unlock_bh(&soc->ast_lock); + } +} +#endif +#else static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc, uint8_t *peer_mac_addr) { diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 5afe6ee5d3..7041cae2d2 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -485,6 +485,18 @@ static inline void dp_peer_map_ast(struct dp_soc *soc, return; } +#ifdef AST_HKV1_WORKAROUND +static inline void +dp_peer_ast_init_del_cmd_sent_flag(struct dp_ast_entry *ast_entry) +{ + ast_entry->del_cmd_sent = false; +} +#else +static inline void +dp_peer_ast_init_del_cmd_sent_flag(struct dp_ast_entry *ast_entry) +{} +#endif + /* * dp_peer_add_ast() - Allocate and add AST entry into peer list * @soc: SoC handle @@ -609,6 +621,7 @@ add_ast_entry: ast_entry->pdev_id = vdev->pdev->pdev_id; ast_entry->vdev_id = vdev->vdev_id; ast_entry->is_mapped = false; + dp_peer_ast_init_del_cmd_sent_flag(ast_entry); switch (type) { case CDP_TXRX_AST_TYPE_STATIC: @@ -695,14 +708,23 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry) if (ast_entry->next_hop && ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) { dp_peer_ast_send_wds_del(soc, ast_entry); - } else { + } + /* AST free happens in completion handler for HKV1 */ + if (soc->ast_override_support || !ast_entry->del_cmd_sent) { /* * release the reference only if it is mapped * to ast_table */ if (ast_entry->is_mapped) soc->ast_table[ast_entry->ast_idx] = NULL; - TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); + + /* ast_entry like next_hop is already removed as part of + * AST del command send, Remove ast_entry that dont + * send ast del command. + */ + if (!ast_entry->del_cmd_sent) + TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, + ase_list_elem); if (ast_entry == peer->self_ast_entry) peer->self_ast_entry = NULL; @@ -939,18 +961,18 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc, struct dp_peer *peer = ast_entry->peer; struct cdp_soc_t *cdp_soc = &soc->cdp_soc; - if (!ast_entry->wmi_sent) { + if (!ast_entry->del_cmd_sent) { cdp_soc->ol_ops->peer_del_wds_entry(peer->vdev->osif_vdev, ast_entry->mac_addr.raw); - ast_entry->wmi_sent = true; + ast_entry->del_cmd_sent = true; TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); } } -bool dp_peer_ast_get_wmi_sent(struct dp_soc *soc, - struct dp_ast_entry *ast_entry) +bool dp_peer_ast_get_del_cmd_sent(struct dp_soc *soc, + struct dp_ast_entry *ast_entry) { - return ast_entry->wmi_sent; + return ast_entry->del_cmd_sent; } void dp_peer_ast_free_entry(struct dp_soc *soc, diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index c3da59f2b5..8d8d28e730 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -145,8 +145,8 @@ void *dp_peer_ast_get_cp_ctx(struct dp_soc *soc, void dp_peer_ast_send_wds_del(struct dp_soc *soc, struct dp_ast_entry *ast_entry); -bool dp_peer_ast_get_wmi_sent(struct dp_soc *soc, - struct dp_ast_entry *ast_entry); +bool dp_peer_ast_get_del_cmd_sent(struct dp_soc *soc, + struct dp_ast_entry *ast_entry); void dp_peer_ast_free_entry(struct dp_soc *soc, struct dp_ast_entry *ast_entry); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 990fc7656d..5053e3a637 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -655,7 +655,7 @@ union dp_align_mac_addr { * @ast_hash_value: hast value in HW * @ref_cnt: reference count * @type: flag to indicate type of the entry(static/WDS/MEC) - * @wmi_sent: Flag to identify of WMI to del ast is sent (AST_HKV1_WORKAROUND) + * @del_cmd_sent: Flag to identify if WMI to del ast is sent * @cp_ctx: Opaque context used by control path (AST_HKV1_WORKAROUND) * @hash_list_elem: node in soc AST hash list (mac address used as hash) */ @@ -673,7 +673,7 @@ struct dp_ast_entry { uint16_t ast_hash_value; qdf_atomic_t ref_cnt; enum cdp_txrx_ast_entry_type type; - bool wmi_sent; + bool del_cmd_sent; void *cp_ctx; TAILQ_ENTRY(dp_ast_entry) ase_list_elem; TAILQ_ENTRY(dp_ast_entry) hash_list_elem;