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

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
...@@ -353,7 +353,10 @@ struct ath11k_sta { ...@@ -353,7 +353,10 @@ struct ath11k_sta {
#endif #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 #define ATH11K_MAX_5G_CHAN 173
enum ath11k_state { enum ath11k_state {
...@@ -431,6 +434,7 @@ struct ath11k { ...@@ -431,6 +434,7 @@ struct ath11k {
u32 vht_cap_info; u32 vht_cap_info;
struct ath11k_he ar_he; struct ath11k_he ar_he;
enum ath11k_state state; enum ath11k_state state;
bool supports_6ghz;
struct { struct {
struct completion started; struct completion started;
struct completion completed; struct completion completed;
......
...@@ -205,6 +205,17 @@ ath11k_phymodes[NUM_NL80211_BANDS][ATH11K_CHAN_WIDTH_NUM] = { ...@@ -205,6 +205,17 @@ ath11k_phymodes[NUM_NL80211_BANDS][ATH11K_CHAN_WIDTH_NUM] = {
[NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160, [NL80211_CHAN_WIDTH_160] = MODE_11AX_HE160,
[NL80211_CHAN_WIDTH_80P80] = MODE_11AX_HE80_80, [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 = { 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, ...@@ -1560,6 +1571,7 @@ static void ath11k_peer_assoc_h_phymode(struct ath11k *ar,
} }
break; break;
case NL80211_BAND_5GHZ: case NL80211_BAND_5GHZ:
case NL80211_BAND_6GHZ:
/* Check HE first */ /* Check HE first */
if (sta->he_cap.has_he) { if (sta->he_cap.has_he) {
phymode = ath11k_mac_get_phymode_he(ar, sta); phymode = ath11k_mac_get_phymode_he(ar, sta);
...@@ -3482,7 +3494,7 @@ static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar, ...@@ -3482,7 +3494,7 @@ static void ath11k_mac_setup_ht_vht_cap(struct ath11k *ar,
rate_cap_rx_chainmask); 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]; band = &ar->mac.sbands[NL80211_BAND_5GHZ];
ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info; ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info;
if (ht_cap_info) if (ht_cap_info)
...@@ -3714,6 +3726,16 @@ static void ath11k_mac_setup_he_cap(struct ath11k *ar, ...@@ -3714,6 +3726,16 @@ static void ath11k_mac_setup_he_cap(struct ath11k *ar,
band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ]; band->iftype_data = ar->mac.iftype[NL80211_BAND_5GHZ];
band->n_iftype_data = count; 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) 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, ...@@ -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].tx = ar->num_tx_chains;
params->chains[NL80211_BAND_5GHZ].rx = ar->num_rx_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 static u32
...@@ -5288,7 +5315,7 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar, ...@@ -5288,7 +5315,7 @@ ath11k_mac_get_single_legacy_rate(struct ath11k *ar,
rate_idx = ffs(mask->control[band].legacy) - 1; 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; rate_idx += ATH11K_MAC_FIRST_OFDM_RATE_IDX;
hw_rate = ath11k_legacy_rates[rate_idx].hw_value; hw_rate = ath11k_legacy_rates[rate_idx].hw_value;
...@@ -5754,7 +5781,8 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, ...@@ -5754,7 +5781,8 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
void *channels; void *channels;
BUILD_BUG_ON((ARRAY_SIZE(ath11k_2ghz_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); ATH11K_NUM_CHANS);
reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx]; reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx];
...@@ -5767,6 +5795,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, ...@@ -5767,6 +5795,7 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
return -ENOMEM; return -ENOMEM;
band = &ar->mac.sbands[NL80211_BAND_2GHZ]; band = &ar->mac.sbands[NL80211_BAND_2GHZ];
band->band = NL80211_BAND_2GHZ;
band->n_channels = ARRAY_SIZE(ath11k_2ghz_channels); band->n_channels = ARRAY_SIZE(ath11k_2ghz_channels);
band->channels = channels; band->channels = channels;
band->n_bitrates = ath11k_g_rates_size; band->n_bitrates = ath11k_g_rates_size;
...@@ -5778,23 +5807,48 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, ...@@ -5778,23 +5807,48 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
} }
if (supported_bands & WMI_HOST_WLAN_5G_CAP) { if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
channels = kmemdup(ath11k_5ghz_channels, if (reg_cap->high_5ghz_chan >= ATH11K_MAX_6G_FREQ) {
sizeof(ath11k_5ghz_channels), channels = kmemdup(ath11k_6ghz_channels,
GFP_KERNEL); sizeof(ath11k_6ghz_channels), GFP_KERNEL);
if (!channels) { if (!channels) {
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels); kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
return -ENOMEM; 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);
} }
band = &ar->mac.sbands[NL80211_BAND_5GHZ]; if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) {
band->n_channels = ARRAY_SIZE(ath11k_5ghz_channels); channels = kmemdup(ath11k_5ghz_channels,
band->channels = channels; sizeof(ath11k_5ghz_channels),
band->n_bitrates = ath11k_a_rates_size; GFP_KERNEL);
band->bitrates = ath11k_a_rates; if (!channels) {
ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
ath11k_mac_update_ch_list(ar, band, kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
reg_cap->low_5ghz_chan, return -ENOMEM;
reg_cap->high_5ghz_chan); }
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;
band->bitrates = ath11k_a_rates;
ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
ath11k_mac_update_ch_list(ar, band,
reg_cap->low_5ghz_chan,
reg_cap->high_5ghz_chan);
}
} }
return 0; return 0;
...@@ -5848,6 +5902,7 @@ static void __ath11k_mac_unregister(struct ath11k *ar) ...@@ -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_2GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels); kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
SET_IEEE80211_DEV(ar->hw, NULL); SET_IEEE80211_DEV(ar->hw, NULL);
} }
......
...@@ -368,6 +368,17 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(struct ath11k_pdev_wmi *wmi_handle, ...@@ -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, memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
sizeof(struct ath11k_ppe_threshold)); 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; return 0;
} }
...@@ -5206,9 +5217,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb) ...@@ -5206,9 +5217,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
goto exit; 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, 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]; sband = &ar->mac.sbands[status->band];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment