]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: ath12k: Handle 4-address EAPOL frames from WBM error path
authorTamizh Chelvam Raja <tamizh.raja@oss.qualcomm.com>
Mon, 25 May 2026 11:09:42 +0000 (16:39 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Mon, 1 Jun 2026 16:58:06 +0000 (09:58 -0700)
Whenever hardware receives 4-address EAPOL frames from an unauthorized
station it is routed through WBM/RXDMA error path with the
HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR error code. But, the
current driver does not handle the 4-address EAPOL frames
in the WBM error path. As a result, these frames are dropped,
causing authentication failures and connectivity issues for 4-address
stations.

Add support to correctly process these frames and forward them to mac80211
for proper handling. This prevents the loss of 4-address EAPOL frames and
ensures reliable connectivity for WDS/4-address clients.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01243-QCAHKSWPL_SILICONZ-1

Co-developed-by: Sathishkumar Muruganandam <quic_murugana@quicinc.com>
Signed-off-by: Sathishkumar Muruganandam <quic_murugana@quicinc.com>
Signed-off-by: Tamizh Chelvam Raja <tamizh.raja@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260525110942.2890212-7-tamizh.raja@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c

index 5c7eaaf200f93fb77dcc6d31901b33350a614bc0..cb9dd8cb28b6716fb59d7753b5ac7073be9e7f69 100644 (file)
@@ -1704,6 +1704,56 @@ static bool ath12k_wifi7_dp_rx_h_tkip_mic_err(struct ath12k_pdev_dp *dp_pdev,
        return false;
 }
 
+static bool ath12k_wifi7_dp_rx_h_unauth_wds_err(struct ath12k_pdev_dp *dp_pdev,
+                                               struct sk_buff *msdu,
+                                               struct hal_rx_desc_data *rx_info)
+{
+       struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
+       struct ath12k_dp *dp = dp_pdev->dp;
+       u32 hdr_len, hal_rx_desc_sz = dp->ab->hal.hal_desc_sz;
+       u8 l3pad_bytes = rx_info->l3_pad_bytes;
+       struct ath12k_dp_rx_rfc1042_hdr *llc;
+       u16 msdu_len = rx_info->msdu_len;
+       struct ath12k_dp_peer *peer;
+       struct ieee80211_hdr *hdr;
+       int ret;
+
+       guard(rcu)();
+       peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rxcb->peer_id);
+       if (!peer) {
+               ath12k_dbg(dp->ab, ATH12K_DBG_DATA,
+                          "failed to find the peer to process unauth wds err handling peer_id %d\n",
+                          rxcb->peer_id);
+               return true;
+       }
+
+       if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE)
+               return true;
+
+       skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len);
+       skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes);
+
+       if (unlikely(!ath12k_dp_rx_check_nwifi_hdr_len_valid(dp, msdu,
+                                                            rx_info)))
+               return true;
+
+       ath12k_dp_rx_h_ppdu(dp_pdev, rx_info);
+
+       ret = ath12k_wifi7_dp_rx_h_mpdu(dp_pdev, msdu, rx_info);
+       if (ret)
+               return true;
+
+       rxcb->tid = rx_info->tid;
+
+       hdr = (struct ieee80211_hdr *)msdu->data;
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
+       llc = (struct ath12k_dp_rx_rfc1042_hdr *)(msdu->data + hdr_len);
+       if (llc->snap_type != cpu_to_be16(ETH_P_PAE))
+               return true;
+
+       return false;
+}
+
 static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,
                                           struct sk_buff *msdu,
                                           struct hal_rx_desc_data *rx_info)
@@ -1715,6 +1765,9 @@ static bool ath12k_wifi7_dp_rx_h_rxdma_err(struct ath12k_pdev_dp *dp_pdev,
        dp->device_stats.rxdma_error[rxcb->err_code]++;
 
        switch (rxcb->err_code) {
+       case HAL_REO_ENTR_RING_RXDMA_ECODE_UNAUTH_WDS_ERR:
+               drop = ath12k_wifi7_dp_rx_h_unauth_wds_err(dp_pdev, msdu, rx_info);
+               break;
        case HAL_REO_ENTR_RING_RXDMA_ECODE_DECRYPT_ERR:
        case HAL_REO_ENTR_RING_RXDMA_ECODE_TKIP_MIC_ERR:
                if (rx_info->err_bitmap & HAL_RX_MPDU_ERR_TKIP_MIC) {