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 */