From d111e1ef4354b7678f7e3468164cec5063558089 Mon Sep 17 00:00:00 2001 From: Pavankumar Nandeshwar Date: Wed, 5 Feb 2020 19:18:19 +0530 Subject: [PATCH] qcacmn: Validate number of wds entries deleted during unmap Validate number of wds entries deleted during peer unmap handling with the number which firmware has sent in peer unmap message, which indicates the number of wds ast entries deleted by firmware after peer delete. Change-Id: I09e1c41bab19cd023e7a83baf1e90d51aab4229e CRs-fixed: 2667445 --- dp/wifi3.0/dp_htt.c | 9 +++++++-- dp/wifi3.0/dp_internal.h | 2 +- dp/wifi3.0/dp_main.c | 8 ++++++-- dp/wifi3.0/dp_peer.c | 40 ++++++++++++++++++++++++++++++++++------ dp/wifi3.0/dp_peer.h | 2 +- dp/wifi3.0/dp_types.h | 1 + 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index a518b8776c..cf5b71b66f 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -4132,7 +4132,8 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) vdev_id = HTT_RX_PEER_UNMAP_VDEV_ID_GET(*msg_word); dp_rx_peer_unmap_handler(soc->dp_soc, peer_id, - vdev_id, mac_addr, 0); + vdev_id, mac_addr, 0, + DP_PEER_WDS_COUNT_INVALID); break; } case HTT_T2H_MSG_TYPE_SEC_IND: @@ -4329,6 +4330,7 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) u_int16_t peer_id; u_int8_t vdev_id; u_int8_t is_wds; + u_int32_t free_wds_count; peer_id = HTT_RX_PEER_UNMAP_V2_SW_PEER_ID_GET(*msg_word); @@ -4338,6 +4340,9 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) &mac_addr_deswizzle_buf[0]); is_wds = HTT_RX_PEER_UNMAP_V2_NEXT_HOP_GET(*(msg_word + 2)); + free_wds_count = + HTT_RX_PEER_UNMAP_V2_PEER_WDS_FREE_COUNT_GET(*(msg_word + 4)); + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, "HTT_T2H_MSG_TYPE_PEER_UNMAP msg for peer id %d vdev id %d n", @@ -4345,7 +4350,7 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt) dp_rx_peer_unmap_handler(soc->dp_soc, peer_id, vdev_id, mac_addr, - is_wds); + is_wds, free_wds_count); break; } case HTT_T2H_MSG_TYPE_RX_DELBA: diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 61d9d5a4dc..e3f42dbdf2 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -22,7 +22,7 @@ #include "dp_types.h" #define RX_BUFFER_SIZE_PKTLOG_LITE 1024 - +#define DP_PEER_WDS_COUNT_INVALID UINT_MAX #define DP_RSSI_INVAL 0x80 #define DP_RSSI_AVG_WEIGHT 2 diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 3b1e99c725..86bafdbf3b 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1173,6 +1173,8 @@ 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(" Entries MAP ERR = %d", soc->stats.ast.map_err); + DP_PRINT_STATS(" Entries Mismatch ERR = %d", + soc->stats.ast.ast_mismatch); DP_PRINT_STATS("AST Table:"); @@ -5467,7 +5469,8 @@ static void dp_peer_flush_ast_entry(struct dp_soc *soc, (soc, peer_id, vdev_id, ase->mac_addr.raw, - 1); + 1, + DP_PEER_WDS_COUNT_INVALID); } } } @@ -5558,7 +5561,8 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool unmap_only) dp_rx_peer_unmap_handler(soc, peer_ids[i], vdev->vdev_id, - peer->mac_addr.raw, 0); + peer->mac_addr.raw, 0, + DP_PEER_WDS_COUNT_INVALID); } qdf_mem_free(peer_ids); diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index 7540dc9c6c..5544457854 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -1244,11 +1244,38 @@ static uint32_t dp_peer_ast_free_wds_entries(struct dp_soc *soc, return num_ast; } -#else -static uint32_t dp_peer_ast_free_wds_entries(struct dp_soc *soc, - struct dp_peer *peer) +/** + * dp_peer_clean_wds_entries() - Clean wds ast entries and compare + * @soc: soc handle + * @peer: peer handle + * @free_wds_count - number of wds entries freed by FW with peer delete + * + * Free all the wds ast entries associated with peer and compare with + * the value received from firmware + * + * Return: Number of wds ast entries freed + */ +static void +dp_peer_clean_wds_entries(struct dp_soc *soc, struct dp_peer *peer, + uint32_t free_wds_count) +{ + uint32_t wds_deleted = 0; + + wds_deleted = dp_peer_ast_free_wds_entries(soc, peer); + if ((DP_PEER_WDS_COUNT_INVALID != free_wds_count) && + (free_wds_count != wds_deleted)) { + DP_STATS_INC(soc, ast.ast_mismatch, 1); + dp_alert("For peer %pK (mac: %pM)number of wds entries deleted by fw = %d during peer delete is not same as the numbers deleted by host = %d", + peer, peer->mac_addr.raw, free_wds_count, + wds_deleted); + } +} + +#else +static void +dp_peer_clean_wds_entries(struct dp_soc *soc, struct dp_peer *peer, + uint32_t free_wds_count) { - return 0; } #endif @@ -1711,13 +1738,14 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, * @vdev_id - vdev ID * @mac_addr - mac address of the peer or wds entry * @is_wds - flag to indicate peer map event for WDS ast entry + * @free_wds_count - number of wds entries freed by FW with peer delete * * Return: none */ void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, uint8_t vdev_id, uint8_t *mac_addr, - uint8_t is_wds) + uint8_t is_wds, uint32_t free_wds_count) { struct dp_peer *peer; uint8_t i; @@ -1747,7 +1775,7 @@ dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, return; } else { - dp_peer_ast_free_wds_entries(soc, peer); + dp_peer_clean_wds_entries(soc, peer, free_wds_count); } dp_info("peer_unmap_event (soc:%pK) peer_id %d peer %pK", diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h index 5f0a9c8e9f..8b45bbb6c4 100644 --- a/dp/wifi3.0/dp_peer.h +++ b/dp/wifi3.0/dp_peer.h @@ -121,7 +121,7 @@ void dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id, uint8_t is_wds); void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id, uint8_t vdev_id, uint8_t *peer_mac_addr, - uint8_t is_wds); + uint8_t is_wds, uint32_t free_wds_count); void dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id, enum cdp_sec_type sec_type, int is_unicast, u_int32_t *michael_key, u_int32_t *rx_pn); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index ee0d8abe84..f10cbcbba1 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -708,6 +708,7 @@ struct dp_soc_stats { uint32_t deleted; uint32_t aged_out; uint32_t map_err; + uint32_t ast_mismatch; } ast; /* SOC level TX stats */