Search Linux Wireless

wifi: ath12k: do not drop data frames from unassociated stations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 'IEEE Std 802.11-2020 section 11.3.4.1':
If STA A in an infrastructure BSS receives a Class 2 or Class 3 frame
from STA B that is not authenticated with STA A
(i.e., the state for STA B is State 1), STA A shall discard the frame.
If the frame has an individual address in the Address 1 field,
the MLME of STA A shall send a Deauthentication frame to STA B.

When data frames from unassociated stations are received by an AP,
the AP is supposed to send a deauthentication/disassociation frame with
reason code "Class 2 frame received from nonauthenticated STA" or
"Class 3 frame received from nonassociated STA".

But ath12k AP doesn't send deauthentication/disassociation frames,
when it receives data frames from unassociated stations.

The ath12k driver drops the data frames from unassociated
station and the upper layer(mac80211/hostapd) is not aware of such event.
Hence deauthentication/disassociation frame is not sent to that
particular station by the AP.

To address this issue, allow the data frames from the
unassociated stations to reach mac80211 so that mac80211 can send
NL80211_CMD_UNEXPECTED_FRAME event to userspace(hostapd) and hostapd
upon receiving the event will send the deauthentication/disassociation
frame with proper reason code.

The data frame from unassociated stations gets dropped in mac80211.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0-02903-QCAHKSWPL_SILICONZ-1

Signed-off-by: Hari Chandrakanthan <quic_haric@xxxxxxxxxxx>
---
 drivers/net/wireless/ath/ath12k/dp_rx.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index 0adcbcf..90eaf2d 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -3485,23 +3485,13 @@ static int ath12k_dp_rx_h_null_q_desc(struct ath12k *ar, struct sk_buff *msdu,
 				      struct sk_buff_head *msdu_list)
 {
 	struct ath12k_base *ab = ar->ab;
-	u16 msdu_len, peer_id;
+	u16 msdu_len;
 	struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data;
 	u8 l3pad_bytes;
 	struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);
 	u32 hal_rx_desc_sz = ar->ab->hw_params->hal_desc_sz;
 
 	msdu_len = ath12k_dp_rx_h_msdu_len(ab, desc);
-	peer_id = ath12k_dp_rx_h_peer_id(ab, desc);
-
-	spin_lock(&ab->base_lock);
-	if (!ath12k_peer_find_by_id(ab, peer_id)) {
-		spin_unlock(&ab->base_lock);
-		ath12k_dbg(ab, ATH12K_DBG_DATA, "invalid peer id received in wbm err pkt%d\n",
-			   peer_id);
-		return -EINVAL;
-	}
-	spin_unlock(&ab->base_lock);
 
 	if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) {
 		/* First buffer will be freed by the caller, so deduct it's length */
-- 
2.7.4




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux