Commit 22eeadcd authored by Pradeep Kumar Chitrapu's avatar Pradeep Kumar Chitrapu Committed by Kalle Valo
Browse files

ath11k: add support for 6GHz radio in driver



This patch adds 6GHz band support and mac80211 registration for
the 6G phy radio.

Signed-off-by: default avatarPradeep Kumar Chitrapu <pradeepc@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200603001724.12161-3-pradeepc@codeaurora.org
parent c5625aba
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -353,7 +353,10 @@ struct ath11k_sta {
#endif
};

#define ATH11K_NUM_CHANS 41
#define ATH11K_MIN_5G_FREQ 4150
#define ATH11K_MIN_6G_FREQ 5945
#define ATH11K_MAX_6G_FREQ 7115
#define ATH11K_NUM_CHANS 100
#define ATH11K_MAX_5G_CHAN 173

enum ath11k_state {
@@ -431,6 +434,7 @@ struct ath11k {
	u32 vht_cap_info;
	struct ath11k_he ar_he;
	enum ath11k_state state;
	bool supports_6ghz;
	struct {
		struct completion started;
		struct completion completed;
+73 −18
Original line number Diff line number Diff line
@@ -205,6 +205,17 @@ ath11k_phymodes[NUM_NL80211_BANDS][ATH11K_CHAN_WIDTH_NUM] = {
			[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
			[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
	},
	[NL80211_BAND_6GHZ] = {
			[NL80211_CHAN_WIDTH_5] = MODE_UNKNOWN,
			[NL80211_CHAN_WIDTH_10] = MODE_UNKNOWN,
			[NL80211_CHAN_WIDTH_20_NOHT] = MODE_11AX_HE20,
			[NL80211_CHAN_WIDTH_20] = MODE_11AX_HE20,
			[NL80211_CHAN_WIDTH_40] = MODE_11AX_HE40,
			[NL80211_CHAN_WIDTH_80] = MODE_11AX_HE80,
			[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
			[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80,
	},

};

const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default = {
@@ -1560,6 +1571,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
		}
		break;
	case NL80211_BAND_5GHZ:
	case NL80211_BAND_6GHZ:
		/* Check HE first */
		if (sta->he_cap.has_he) {
			phymode = ath11k_mac_get_phymode_he(ar, sta);
@@ -3482,7 +3494,7 @@ static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar,
						    rate_cap_rx_chainmask);
	}

	if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP) {
	if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) {
		band = &ar->mac.sbands[NL80211_BAND_5GHZ];
		ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info;
		if (ht_cap_info)
@@ -3714,6 +3726,16 @@ static void ath11k_mac_setup_he_cap(struct ath11k *ar,
		band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
		band->n_iftype_data = count;
	}

	if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
	    ar->supports_6ghz) {
		count = ath11k_mac_copy_he_cap(ar, cap,
					       ar->mac.iftype[NL80211_BAND_6GHZ],
					       NL80211_BAND_6GHZ);
		band = &ar->mac.sbands[NL80211_BAND_6GHZ];
		band->iftype_data = ar->mac.iftype[NL80211_BAND_6GHZ];
		band->n_iftype_data = count;
	}
}

static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant)
@@ -4156,6 +4178,11 @@ ath11k_mac_setup_vdev_create_params(struct ath11k_vif *arvif,
		params->chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
		params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
	}
	if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP &&
	    ar->supports_6ghz) {
		params->chains[NL80211_BAND_6GHZ].tx = ar->num_tx_chains;
		params->chains[NL80211_BAND_6GHZ].rx = ar->num_rx_chains;
	}
}

static u32
@@ -5288,7 +5315,7 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar,

	rate_idx = ffs(mask->control[band].legacy) - 1;

	if (band == NL80211_BAND_5GHZ)
	if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ)
		rate_idx += ATH11K_MAC_FIRST_OFDM_RATE_IDX;

	hw_rate = ath11k_legacy_rates[rate_idx].hw_value;
@@ -5754,7 +5781,8 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
	void *channels;

	BUILD_BUG_ON((ARRAY_SIZE(ath11k_2ghz_channels) +
		      ARRAY_SIZE(ath11k_5ghz_channels)) !=
		      ARRAY_SIZE(ath11k_5ghz_channels) +
		      ARRAY_SIZE(ath11k_6ghz_channels)) !=
		     ATH11K_NUM_CHANS);

	reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx];
@@ -5767,6 +5795,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
			return -ENOMEM;

		band = &ar->mac.sbands[NL80211_BAND_2GHZ];
		band->band = NL80211_BAND_2GHZ;
		band->n_channels = ARRAY_SIZE(ath11k_2ghz_channels);
		band->channels = channels;
		band->n_bitrates = ath11k_g_rates_size;
@@ -5778,15 +5807,39 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
	}

	if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
		if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) {
			channels = kmemdup(ath11k_6ghz_channels,
					   sizeof(ath11k_6ghz_channels), GFP_KERNEL);
			if (!channels) {
				kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
				return -ENOMEM;
			}

			ar->supports_6ghz = true;
			band = &ar->mac.sbands[NL80211_BAND_6GHZ];
			band->band = NL80211_BAND_6GHZ;
			band->n_channels = ARRAY_SIZE(ath11k_6ghz_channels);
			band->channels = channels;
			band->n_bitrates = ath11k_a_rates_size;
			band->bitrates = ath11k_a_rates;
			ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band;
			ath11k_mac_update_ch_list(ar, band,
						  reg_cap->low_5ghz_chan,
						  reg_cap->high_5ghz_chan);
		}

		if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) {
			channels = kmemdup(ath11k_5ghz_channels,
					   sizeof(ath11k_5ghz_channels),
					   GFP_KERNEL);
			if (!channels) {
				kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
				kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
				return -ENOMEM;
			}

			band = &ar->mac.sbands[NL80211_BAND_5GHZ];
			band->band = NL80211_BAND_5GHZ;
			band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels);
			band->channels = channels;
			band->n_bitrates = ath11k_a_rates_size;
@@ -5796,6 +5849,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
						  reg_cap->low_5ghz_chan,
						  reg_cap->high_5ghz_chan);
		}
	}

	return 0;
}
@@ -5848,6 +5902,7 @@ static void __ath11k_mac_unregister(struct ath11k *ar)

	kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
	kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
	kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);

	SET_IEEE80211_DEV(ar->hw, NULL);
}
+14 −2
Original line number Diff line number Diff line
@@ -368,6 +368,17 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle,
	memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
	       sizeof(struct ath11k_ppe_threshold));

	cap_band = &pdev_cap->band[NL80211_BAND_6GHZ];
	cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
	cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
	cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
	cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
	cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
	memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
	       sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
	memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
	       sizeof(struct ath11k_ppe_threshold));

	return 0;
}

@@ -5206,9 +5217,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
		goto exit;
	}

	if (rx_ev.phy_mode == MODE_11B && status->band == NL80211_BAND_5GHZ)
	if (rx_ev.phy_mode == MODE_11B &&
	    (status->band == NL80211_BAND_5GHZ || status->band == NL80211_BAND_6GHZ))
		ath11k_dbg(ab, ATH11K_DBG_WMI,
			   "wmi mgmt rx 11b (CCK) on 5GHz\n");
			   "wmi mgmt rx 11b (CCK) on 5/6GHz, band = %d\n", status->band);

	sband = &ar->mac.sbands[status->band];