From 74e6d8b5101bfbb6d62d29bf651080b7c3fc1d10 Mon Sep 17 00:00:00 2001 From: Kiran Venkatappa Date: Mon, 5 Nov 2018 15:02:29 +0530 Subject: [PATCH] qcacmn: Enable AST workaround only for HKV1 HKV1 does not have support to maintain per pdev AST table. Hence workaround is required to ensure that AST entry is deleted before adding an entry with same MAC. This syncronization needs to done across pdev. This workaround in required on for HKV1, add changes to enable workaround only for HKV1 and disabled for other platforms. Change-Id: I9aa43ea51fdff2f02cdcc8ff7e906c7305446317 CRs-Fixed: 2344921 --- dp/wifi3.0/dp_main.c | 27 ++++++++++++++++++++++----- dp/wifi3.0/dp_peer.c | 36 +++++++++++++++++++++++++++++------- dp/wifi3.0/dp_peer.h | 4 ++-- dp/wifi3.0/dp_types.h | 4 ++-- 4 files changed, 55 insertions(+), 16 deletions(-) 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;