Commit 8092a0ee authored by Kalle Valo's avatar Kalle Valo
Browse files
ath.git patches for v5.20. Major changes:

ath10k

* 802.3 frame format support
parents fbb89d02 cc2609ed
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -33,9 +33,11 @@ EXPORT_SYMBOL(ath10k_debug_mask);
static unsigned int ath10k_cryptmode_param;
static bool uart_print;
static bool skip_otp;
static bool rawmode;
static bool fw_diag_log;

/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */
unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI;

unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
				     BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);

@@ -44,15 +46,16 @@ module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
module_param(uart_print, bool, 0644);
module_param(skip_otp, bool, 0644);
module_param(rawmode, bool, 0644);
module_param(fw_diag_log, bool, 0644);
module_param_named(frame_mode, ath10k_frame_mode, uint, 0644);
module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);

MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
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(rawmode, "Use raw 802.11 frame datapath");
MODULE_PARM_DESC(frame_mode,
		 "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");

@@ -2599,7 +2602,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
	ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
	ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;

	if (rawmode) {
	if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) {
		if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
			      fw_file->fw_features)) {
			ath10k_err(ar, "rawmode = 1 requires support from firmware");
+1 −0
Original line number Diff line number Diff line
@@ -1314,6 +1314,7 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar)
	return false;
}

extern unsigned int ath10k_frame_mode;
extern unsigned long ath10k_coredump_mask;

void ath10k_core_napi_sync_disable(struct ath10k *ar);
+5 −1
Original line number Diff line number Diff line
@@ -3563,7 +3563,7 @@ static void ath10k_htt_rx_tx_mode_switch_ind(struct ath10k *ar,
	threshold = MS(info1, HTT_TX_MODE_SWITCH_IND_INFO1_THRESHOLD);

	ath10k_dbg(ar, ATH10K_DBG_HTT,
		   "htt rx tx mode switch ind info0 0x%04hx info1 0x%04x enable %d num records %zd mode %d threshold %u\n",
		   "htt rx tx mode switch ind info0 0x%04x info1 0x%04x enable %d num records %zd mode %d threshold %u\n",
		   info0, info1, enable, num_records, mode, threshold);

	len += sizeof(resp->tx_mode_switch_ind.records[0]) * num_records;
@@ -3884,6 +3884,10 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
		arsta->tx_info.status.rates[0].flags |=
				IEEE80211_TX_RC_80_MHZ_WIDTH;
		break;
	case RATE_INFO_BW_160:
		arsta->tx_info.status.rates[0].flags |=
				IEEE80211_TX_RC_160_MHZ_WIDTH;
		break;
	}

	if (peer_stats->succ_pkts) {
+35 −26
Original line number Diff line number Diff line
@@ -1275,7 +1275,6 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
	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;
@@ -1286,12 +1285,16 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
	u16 flags1 = 0;
	u16 msdu_id = 0;

	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;

@@ -1387,7 +1390,6 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
{
	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];
@@ -1419,6 +1421,9 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
	txbuf_paddr = htt->txbuf.paddr +
		      (sizeof(struct ath10k_htt_txbuf_32) * msdu_id);

	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)) &&
@@ -1429,6 +1434,7 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
			   ieee80211_has_protected(hdr->frame_control)) {
			skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
		}
	}

	skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
				       DMA_TO_DEVICE);
@@ -1589,7 +1595,6 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
{
	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];
@@ -1621,6 +1626,9 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
	txbuf_paddr = htt->txbuf.paddr +
		      (sizeof(struct ath10k_htt_txbuf_64) * msdu_id);

	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)) &&
@@ -1631,6 +1639,7 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
			   ieee80211_has_protected(hdr->frame_control)) {
			skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
		}
	}

	skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
				       DMA_TO_DEVICE);
+56 −14
Original line number Diff line number Diff line
@@ -3713,6 +3713,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
	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;

@@ -3873,6 +3876,12 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
	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;

@@ -3911,6 +3920,7 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
		cb->flags |= ATH10K_SKB_F_RAW_TX;
	}

finish_cb_fill:
	cb->vif = vif;
	cb->txq = txq;
	cb->airtime_est = airtime;
@@ -4034,6 +4044,10 @@ static int ath10k_mac_tx(struct ath10k *ar,
		ath10k_tx_h_seq_no(vif, skb);
		break;
	case ATH10K_HW_TXRX_ETHERNET:
		/* 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:
@@ -4645,12 +4659,10 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
	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;

@@ -4664,8 +4676,14 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
	is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);

	if (is_htt) {
		bool is_presp = false;

		spin_lock_bh(&ar->htt.tx_lock);
		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) {
@@ -5465,6 +5483,30 @@ static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
					 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,
@@ -5674,15 +5716,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,

	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.
@@ -9375,6 +9409,7 @@ static const struct ieee80211_ops ath10k_ops = {
	.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,
@@ -10044,6 +10079,12 @@ int ath10k_mac_register(struct ath10k *ar)
	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;
@@ -10229,7 +10270,8 @@ int ath10k_mac_register(struct ath10k *ar)
		ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
	}

	if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
	if (!ath_is_world_regd(&ar->ath_common.reg_world_copy) &&
	    !ath_is_world_regd(&ar->ath_common.regulatory)) {
		ret = regulatory_hint(ar->hw->wiphy,
				      ar->ath_common.regulatory.alpha2);
		if (ret)
Loading