qcacmn: WAR to avoid processing corrupted packet

In defrag path match addr1 with VAP mac address
and if there is mismatch do not process considering
it as corrupted packet

Change-Id: I003c07949e760ff4e64a7d22bfbefc25cc817ae2
CRs-Fixed: 3327977
This commit is contained in:
Chaithanya Garrepalli
2022-11-02 20:48:39 +05:30
committed by Madan Koyyalamudi
parent d7c7a5b0bb
commit 67fa8470e3
3 changed files with 77 additions and 0 deletions

View File

@@ -1682,6 +1682,73 @@ dp_rx_defrag_save_info_from_ring_desc(struct dp_soc *soc,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#ifdef DP_RX_DEFRAG_ADDR1_CHECK_WAR
#ifdef WLAN_FEATURE_11BE_MLO
/*
* dp_rx_defrag_vdev_mac_addr_cmp() - function to check whether mac address
* matches VDEV mac
* @vdev: dp_vdev object of the VDEV on which this data packet is received
* @mac_addr: Address to compare
*
* Return: 1 if the mac matching,
* 0 if this frame is not correctly destined to this VDEV/MLD
*/
static int dp_rx_defrag_vdev_mac_addr_cmp(struct dp_vdev *vdev,
uint8_t *mac_addr)
{
return ((qdf_mem_cmp(mac_addr, &vdev->mac_addr.raw[0],
QDF_MAC_ADDR_SIZE) == 0) ||
(qdf_mem_cmp(mac_addr, &vdev->mld_mac_addr.raw[0],
QDF_MAC_ADDR_SIZE) == 0));
}
#else
static int dp_rx_defrag_vdev_mac_addr_cmp(struct dp_vdev *vdev,
uint8_t *mac_addr)
{
return (qdf_mem_cmp(mac_addr, &vdev->mac_addr.raw[0],
QDF_MAC_ADDR_SIZE) == 0);
}
#endif
static bool dp_rx_defrag_addr1_check(struct dp_soc *soc,
struct dp_vdev *vdev,
uint8_t *rx_tlv_hdr)
{
union dp_align_mac_addr mac_addr;
/* If address1 is not valid discard the fragment */
if (hal_rx_mpdu_get_addr1(soc->hal_soc, rx_tlv_hdr,
&mac_addr.raw[0]) != QDF_STATUS_SUCCESS) {
DP_STATS_INC(soc, rx.err.defrag_ad1_invalid, 1);
return false;
}
/* WAR suggested by HW team to avoid crashing incase of packet
* corruption issue
*
* recipe is to compare VDEV mac or MLD mac address with ADDR1
* in case of mismatch consider it as corrupted packet and do
* not process further
*/
if (!dp_rx_defrag_vdev_mac_addr_cmp(vdev,
&mac_addr.raw[0])) {
DP_STATS_INC(soc, rx.err.defrag_ad1_invalid, 1);
return false;
}
return true;
}
#else
static inline bool dp_rx_defrag_addr1_check(struct dp_soc *soc,
struct dp_vdev *vdev,
uint8_t *rx_tlv_hdr)
{
return true;
}
#endif
/* /*
* dp_rx_defrag_store_fragment(): Store incoming fragments * dp_rx_defrag_store_fragment(): Store incoming fragments
* @soc: Pointer to the SOC data structure * @soc: Pointer to the SOC data structure
@@ -1759,6 +1826,12 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
goto discard_frag; goto discard_frag;
} }
if (!dp_rx_defrag_addr1_check(soc, txrx_peer->vdev,
rx_desc->rx_buf_start)) {
dp_info("Invalid address 1");
goto discard_frag;
}
mpdu_sequence_control_valid = mpdu_sequence_control_valid =
hal_rx_get_mpdu_sequence_control_valid(soc->hal_soc, hal_rx_get_mpdu_sequence_control_valid(soc->hal_soc,
rx_desc->rx_buf_start); rx_desc->rx_buf_start);

View File

@@ -7988,6 +7988,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
DP_PRINT_STATS("Rx Flush count:%d", soc->stats.rx.err.rx_flush_count); DP_PRINT_STATS("Rx Flush count:%d", soc->stats.rx.err.rx_flush_count);
DP_PRINT_STATS("Rx invalid TID count:%d", DP_PRINT_STATS("Rx invalid TID count:%d",
soc->stats.rx.err.rx_invalid_tid_err); soc->stats.rx.err.rx_invalid_tid_err);
DP_PRINT_STATS("Rx Defrag Address1 Invalid:%d",
soc->stats.rx.err.defrag_ad1_invalid);
} }
#ifdef FEATURE_TSO_STATS #ifdef FEATURE_TSO_STATS

View File

@@ -1251,6 +1251,8 @@ struct dp_soc_stats {
uint32_t rx_flush_count; uint32_t rx_flush_count;
/* Rx invalid tid count */ /* Rx invalid tid count */
uint32_t rx_invalid_tid_err; uint32_t rx_invalid_tid_err;
/* Invalid address1 in defrag path*/
uint32_t defrag_ad1_invalid;
} err; } err;
/* packet count per core - per ring */ /* packet count per core - per ring */