 c47f8dacb8
			
		
	
	c47f8dacb8
	
	
	
		
			
			Add tags to already upstreamed patches. Signed-off-by: Nick Hainke <vincent@systemli.org>
		
			
				
	
	
		
			195 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From af6d8265c47e46881b80c6b073f53c8c4af52d28 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: add encapsulation offloading support
 | |
| MIME-Version: 1.0
 | |
| Content-Type: text/plain; charset=UTF-8
 | |
| Content-Transfer-Encoding: 8bit
 | |
| 
 | |
| Frame encapsulation from Ethernet into the IEEE 802.11 frame format
 | |
| takes a considerable host CPU time on the xmit path. The firmware is
 | |
| able to do this operation for us, so enable encapsulation offloading for
 | |
| AP and Sta interface types to improve overall system performance.
 | |
| 
 | |
| The driver is almost ready for encapsulation offloading support. There
 | |
| are only a few places where the driver assumes the frame format is IEEE
 | |
| 802.11 that need to be fixed.
 | |
| 
 | |
| Encapsulation offloading is currently disabled by default and the driver
 | |
| utilizes mac80211 encapsulation support. To activate offloading, the
 | |
| frame_mode=2 parameter should be passed during module loading.
 | |
| 
 | |
| On a QCA9563+QCA9888-based access point in bridged mode, encapsulation
 | |
| offloading increases TCP 16-streams DL throughput from 365 to 396 mbps
 | |
| (+8%) and UDP DL throughput from 436 to 483 mbps (+11%).
 | |
| 
 | |
| Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131
 | |
| Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1
 | |
| Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
 | |
| Tested-by: Oldřich Jedlička <oldium.pro@gmail.com> # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880)
 | |
| Tested-by: Edward Matijevic <motolav@gmail.com> # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1)
 | |
| Tested-by: Edward Matijevic <motolav@gmail.com> # QCA9377 PCI in Sta mode
 | |
| Tested-by: Zhijun You <hujy652@gmail.com> # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159)
 | |
| Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
 | |
| Link: https://lore.kernel.org/r/20220516032519.29831-5-ryazanov.s.a@gmail.com
 | |
| ---
 | |
|  drivers/net/wireless/ath/ath10k/core.c |  2 +-
 | |
|  drivers/net/wireless/ath/ath10k/mac.c  | 67 +++++++++++++++++++++++++++-------
 | |
|  2 files changed, 55 insertions(+), 14 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/wireless/ath/ath10k/core.c
 | |
| +++ b/drivers/net/wireless/ath/ath10k/core.c
 | |
| @@ -54,7 +54,7 @@ MODULE_PARM_DESC(uart_print, "Uart targe
 | |
|  MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
 | |
|  MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
 | |
|  MODULE_PARM_DESC(frame_mode,
 | |
| -		 "Datapath frame mode (0: raw, 1: native wifi (default))");
 | |
| +		 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
 | |
|  MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
 | |
|  MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");
 | |
|  
 | |
| --- a/drivers/net/wireless/ath/ath10k/mac.c
 | |
| +++ b/drivers/net/wireless/ath/ath10k/mac.c
 | |
| @@ -3710,6 +3710,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k
 | |
|  	const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
 | |
|  	__le16 fc = hdr->frame_control;
 | |
|  
 | |
| +	if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
 | |
| +		return ATH10K_HW_TXRX_ETHERNET;
 | |
| +
 | |
|  	if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
 | |
|  		return ATH10K_HW_TXRX_RAW;
 | |
|  
 | |
| @@ -3870,6 +3873,12 @@ static void ath10k_mac_tx_h_fill_cb(stru
 | |
|  	bool noack = false;
 | |
|  
 | |
|  	cb->flags = 0;
 | |
| +
 | |
| +	if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
 | |
| +		cb->flags |= ATH10K_SKB_F_QOS;	/* Assume data frames are QoS */
 | |
| +		goto finish_cb_fill;
 | |
| +	}
 | |
| +
 | |
|  	if (!ath10k_tx_h_use_hwcrypto(vif, skb))
 | |
|  		cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
 | |
|  
 | |
| @@ -3908,6 +3917,7 @@ static void ath10k_mac_tx_h_fill_cb(stru
 | |
|  		cb->flags |= ATH10K_SKB_F_RAW_TX;
 | |
|  	}
 | |
|  
 | |
| +finish_cb_fill:
 | |
|  	cb->vif = vif;
 | |
|  	cb->txq = txq;
 | |
|  	cb->airtime_est = airtime;
 | |
| @@ -4031,7 +4041,11 @@ static int ath10k_mac_tx(struct ath10k *
 | |
|  		ath10k_tx_h_seq_no(vif, skb);
 | |
|  		break;
 | |
|  	case ATH10K_HW_TXRX_ETHERNET:
 | |
| -		ath10k_tx_h_8023(skb);
 | |
| +		/* Convert 802.11->802.3 header only if the frame was erlier
 | |
| +		 * encapsulated to 802.11 by mac80211. Otherwise pass it as is.
 | |
| +		 */
 | |
| +		if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
 | |
| +			ath10k_tx_h_8023(skb);
 | |
|  		break;
 | |
|  	case ATH10K_HW_TXRX_RAW:
 | |
|  		if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
 | |
| @@ -4643,12 +4657,10 @@ static void ath10k_mac_op_tx(struct ieee
 | |
|  	struct ieee80211_vif *vif = info->control.vif;
 | |
|  	struct ieee80211_sta *sta = control->sta;
 | |
|  	struct ieee80211_txq *txq = NULL;
 | |
| -	struct ieee80211_hdr *hdr = (void *)skb->data;
 | |
|  	enum ath10k_hw_txrx_mode txmode;
 | |
|  	enum ath10k_mac_tx_path txpath;
 | |
|  	bool is_htt;
 | |
|  	bool is_mgmt;
 | |
| -	bool is_presp;
 | |
|  	int ret;
 | |
|  	u16 airtime;
 | |
|  
 | |
| @@ -4662,8 +4674,14 @@ static void ath10k_mac_op_tx(struct ieee
 | |
|  	is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
 | |
|  
 | |
|  	if (is_htt) {
 | |
| +		bool is_presp = false;
 | |
| +
 | |
|  		spin_lock_bh(&ar->htt.tx_lock);
 | |
| -		is_presp = ieee80211_is_probe_resp(hdr->frame_control);
 | |
| +		if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
 | |
| +			struct ieee80211_hdr *hdr = (void *)skb->data;
 | |
| +
 | |
| +			is_presp = ieee80211_is_probe_resp(hdr->frame_control);
 | |
| +		}
 | |
|  
 | |
|  		ret = ath10k_htt_tx_inc_pending(htt);
 | |
|  		if (ret) {
 | |
| @@ -5463,6 +5481,30 @@ static int ath10k_mac_set_txbf_conf(stru
 | |
|  					 ar->wmi.vdev_param->txbf, value);
 | |
|  }
 | |
|  
 | |
| +static void ath10k_update_vif_offload(struct ieee80211_hw *hw,
 | |
| +				      struct ieee80211_vif *vif)
 | |
| +{
 | |
| +	struct ath10k_vif *arvif = (void *)vif->drv_priv;
 | |
| +	struct ath10k *ar = hw->priv;
 | |
| +	u32 vdev_param;
 | |
| +	int ret;
 | |
| +
 | |
| +	if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET ||
 | |
| +	    ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED ||
 | |
| +	     (vif->type != NL80211_IFTYPE_STATION &&
 | |
| +	      vif->type != NL80211_IFTYPE_AP))
 | |
| +		vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
 | |
| +
 | |
| +	vdev_param = ar->wmi.vdev_param->tx_encap_type;
 | |
| +	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 | |
| +					ATH10K_HW_TXRX_NATIVE_WIFI);
 | |
| +	/* 10.X firmware does not support this VDEV parameter. Do not warn */
 | |
| +	if (ret && ret != -EOPNOTSUPP) {
 | |
| +		ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
 | |
| +			    arvif->vdev_id, ret);
 | |
| +	}
 | |
| +}
 | |
| +
 | |
|  /*
 | |
|   * TODO:
 | |
|   * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
 | |
| @@ -5672,15 +5714,7 @@ static int ath10k_add_interface(struct i
 | |
|  
 | |
|  	arvif->def_wep_key_idx = -1;
 | |
|  
 | |
| -	vdev_param = ar->wmi.vdev_param->tx_encap_type;
 | |
| -	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
 | |
| -					ATH10K_HW_TXRX_NATIVE_WIFI);
 | |
| -	/* 10.X firmware does not support this VDEV parameter. Do not warn */
 | |
| -	if (ret && ret != -EOPNOTSUPP) {
 | |
| -		ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
 | |
| -			    arvif->vdev_id, ret);
 | |
| -		goto err_vdev_delete;
 | |
| -	}
 | |
| +	ath10k_update_vif_offload(hw, vif);
 | |
|  
 | |
|  	/* Configuring number of spatial stream for monitor interface is causing
 | |
|  	 * target assert in qca9888 and qca6174.
 | |
| @@ -9368,6 +9402,7 @@ static const struct ieee80211_ops ath10k
 | |
|  	.stop				= ath10k_stop,
 | |
|  	.config				= ath10k_config,
 | |
|  	.add_interface			= ath10k_add_interface,
 | |
| +	.update_vif_offload		= ath10k_update_vif_offload,
 | |
|  	.remove_interface		= ath10k_remove_interface,
 | |
|  	.configure_filter		= ath10k_configure_filter,
 | |
|  	.bss_info_changed		= ath10k_bss_info_changed,
 | |
| @@ -10037,6 +10072,12 @@ int ath10k_mac_register(struct ath10k *a
 | |
|  	if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
 | |
|  		ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);
 | |
|  
 | |
| +	if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) {
 | |
| +		if (ar->wmi.vdev_param->tx_encap_type !=
 | |
| +		    WMI_VDEV_PARAM_UNSUPPORTED)
 | |
| +			ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
 | |
| +	}
 | |
| +
 | |
|  	ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
 | |
|  	ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 | |
|  	ar->hw->wiphy->max_remain_on_channel_duration = 5000;
 |