mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 14:04:26 -04:00 
			
		
		
		
	Add tags to already upstreamed patches. Signed-off-by: Nick Hainke <vincent@systemli.org>
		
			
				
	
	
		
			164 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 70f119fb82af7f7417dc659faf02c91e1f853739 Mon Sep 17 00:00:00 2001
 | |
| From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
 | |
| Date: Mon, 16 May 2022 13:26:00 +0300
 | |
| Subject: ath10k: htt_tx: do not interpret Eth frames as WiFi
 | |
| 
 | |
| The xmit path for the Ethernet encapsulated frames become more or less
 | |
| usable since d740d8fd2439 ("ath10k: unify tx mode and dispatch"). This
 | |
| change reorganize the xmit path in a manageable way to properly support
 | |
| various tx modes, but misses that the Ethernet encapsulated frame is a
 | |
| special case. We do not have an IEEE 802.11 header at the begining of
 | |
| them. But the HTT Tx handler still interprets first bytes of each frame
 | |
| as an IEEE 802.11 Frame Control field.
 | |
| 
 | |
| Than this code was copied by e62ee5c381c5 ("ath10k: Add support for
 | |
| htt_data_tx_desc_64 descriptor") and a2097d6444c3 ("ath10k: htt: High
 | |
| latency TX support") to another handlers. In fact the issue in the high
 | |
| latency (HL) handler was introduced by 83ac260151e7 ("ath10k: add mic
 | |
| bytes for pmf management packet").
 | |
| 
 | |
| Ethernet encapsulated frame tx mode stay unused until 75d85fd9993c
 | |
| ("ath10k: introduce basic tdls functionality") started using it for TDLS
 | |
| frames to avoid key selection issue in some firmwares.
 | |
| 
 | |
| Trying to interpret the begining of an Ethernet encapsulated frame as an
 | |
| IEEE 802.11 header was not hurt us noticeably since we need to meet two
 | |
| conditions: (1) xmit should be performed towards a TDLS peer, and (2)
 | |
| the TDLS peer should have a specific OUI part of its MAC address. Looks
 | |
| like that the rareness in TDLS communications of OUIs that can be
 | |
| interpreted as an 802.11 management frame saves users from facing this
 | |
| issue earlier.
 | |
| 
 | |
| Improve Ethernet tx mode support in the HTT Tx handler by avoiding
 | |
| interpreting its first bytes as an IEEE 802.11 header. While at it, make
 | |
| the ieee80211_hdr variable local to the code block that is guarded by
 | |
| !is_eth check. In this way, we clarify in which cases a frame can be
 | |
| interpreted as IEEE 802.11, and saves us from similar issues in the
 | |
| future.
 | |
| 
 | |
| Credits: this change as part of xmit encapsulation offloading support
 | |
| was originally made by QCA and then submitted for inclusion by John
 | |
| Crispin [1]. But the whole work was not accepted due to the lack of a
 | |
| part for 64-bits descriptors [2]. Zhijun You then pointed this out to me
 | |
| in a reply to my initial RFC patch series. And I made this slightly
 | |
| reworked version that covered all the HTT Tx handler variants.
 | |
| 
 | |
| 1. https://lore.kernel.org/all/20191216092207.31032-1-john@phrozen.org/
 | |
| 2. https://patchwork.kernel.org/project/linux-wireless/patch/20191216092207.31032-1-john@phrozen.org/
 | |
| 
 | |
| Reported-by: Zhijun You <hujy652@gmail.com>
 | |
| Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
 | |
| Signed-off-by: John Crispin <john@phrozen.org>
 | |
| Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
 | |
| Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
 | |
| Link: https://lore.kernel.org/r/20220516032519.29831-3-ryazanov.s.a@gmail.com
 | |
| ---
 | |
|  drivers/net/wireless/ath/ath10k/htt_tx.c | 61 ++++++++++++++++++--------------
 | |
|  1 file changed, 35 insertions(+), 26 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/wireless/ath/ath10k/htt_tx.c
 | |
| +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
 | |
| @@ -1295,7 +1295,6 @@ static int ath10k_htt_tx_hl(struct ath10
 | |
|  	struct ath10k *ar = htt->ar;
 | |
|  	int res, data_len;
 | |
|  	struct htt_cmd_hdr *cmd_hdr;
 | |
| -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
 | |
|  	struct htt_data_tx_desc *tx_desc;
 | |
|  	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
 | |
|  	struct sk_buff *tmp_skb;
 | |
| @@ -1306,11 +1305,15 @@ static int ath10k_htt_tx_hl(struct ath10
 | |
|  	u16 flags1 = 0;
 | |
|  	u16 msdu_id = 0;
 | |
|  
 | |
| -	if ((ieee80211_is_action(hdr->frame_control) ||
 | |
| -	     ieee80211_is_deauth(hdr->frame_control) ||
 | |
| -	     ieee80211_is_disassoc(hdr->frame_control)) &&
 | |
| -	     ieee80211_has_protected(hdr->frame_control)) {
 | |
| -		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +	if (!is_eth) {
 | |
| +		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
 | |
| +
 | |
| +		if ((ieee80211_is_action(hdr->frame_control) ||
 | |
| +		     ieee80211_is_deauth(hdr->frame_control) ||
 | |
| +		     ieee80211_is_disassoc(hdr->frame_control)) &&
 | |
| +		     ieee80211_has_protected(hdr->frame_control)) {
 | |
| +			skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +		}
 | |
|  	}
 | |
|  
 | |
|  	data_len = msdu->len;
 | |
| @@ -1407,7 +1410,6 @@ static int ath10k_htt_tx_32(struct ath10
 | |
|  {
 | |
|  	struct ath10k *ar = htt->ar;
 | |
|  	struct device *dev = ar->dev;
 | |
| -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
 | |
|  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
 | |
|  	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
 | |
|  	struct ath10k_hif_sg_item sg_items[2];
 | |
| @@ -1439,15 +1441,19 @@ static int ath10k_htt_tx_32(struct ath10
 | |
|  	txbuf_paddr = htt->txbuf.paddr +
 | |
|  		      (sizeof(struct ath10k_htt_txbuf_32) * msdu_id);
 | |
|  
 | |
| -	if ((ieee80211_is_action(hdr->frame_control) ||
 | |
| -	     ieee80211_is_deauth(hdr->frame_control) ||
 | |
| -	     ieee80211_is_disassoc(hdr->frame_control)) &&
 | |
| -	     ieee80211_has_protected(hdr->frame_control)) {
 | |
| -		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| -	} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
 | |
| -		   txmode == ATH10K_HW_TXRX_RAW &&
 | |
| -		   ieee80211_has_protected(hdr->frame_control)) {
 | |
| -		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +	if (!is_eth) {
 | |
| +		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
 | |
| +
 | |
| +		if ((ieee80211_is_action(hdr->frame_control) ||
 | |
| +		     ieee80211_is_deauth(hdr->frame_control) ||
 | |
| +		     ieee80211_is_disassoc(hdr->frame_control)) &&
 | |
| +		     ieee80211_has_protected(hdr->frame_control)) {
 | |
| +			skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +		} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
 | |
| +			   txmode == ATH10K_HW_TXRX_RAW &&
 | |
| +			   ieee80211_has_protected(hdr->frame_control)) {
 | |
| +			skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +		}
 | |
|  	}
 | |
|  
 | |
|  	skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
 | |
| @@ -1609,7 +1615,6 @@ static int ath10k_htt_tx_64(struct ath10
 | |
|  {
 | |
|  	struct ath10k *ar = htt->ar;
 | |
|  	struct device *dev = ar->dev;
 | |
| -	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
 | |
|  	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
 | |
|  	struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
 | |
|  	struct ath10k_hif_sg_item sg_items[2];
 | |
| @@ -1641,15 +1646,19 @@ static int ath10k_htt_tx_64(struct ath10
 | |
|  	txbuf_paddr = htt->txbuf.paddr +
 | |
|  		      (sizeof(struct ath10k_htt_txbuf_64) * msdu_id);
 | |
|  
 | |
| -	if ((ieee80211_is_action(hdr->frame_control) ||
 | |
| -	     ieee80211_is_deauth(hdr->frame_control) ||
 | |
| -	     ieee80211_is_disassoc(hdr->frame_control)) &&
 | |
| -	     ieee80211_has_protected(hdr->frame_control)) {
 | |
| -		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| -	} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
 | |
| -		   txmode == ATH10K_HW_TXRX_RAW &&
 | |
| -		   ieee80211_has_protected(hdr->frame_control)) {
 | |
| -		skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +	if (!is_eth) {
 | |
| +		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
 | |
| +
 | |
| +		if ((ieee80211_is_action(hdr->frame_control) ||
 | |
| +		     ieee80211_is_deauth(hdr->frame_control) ||
 | |
| +		     ieee80211_is_disassoc(hdr->frame_control)) &&
 | |
| +		     ieee80211_has_protected(hdr->frame_control)) {
 | |
| +			skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +		} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
 | |
| +			   txmode == ATH10K_HW_TXRX_RAW &&
 | |
| +			   ieee80211_has_protected(hdr->frame_control)) {
 | |
| +			skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
 | |
| +		}
 | |
|  	}
 | |
|  
 | |
|  	skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
 |