ath11k: add support for 6GHz radio in driver
authorPradeep Kumar Chitrapu <pradeepc@codeaurora.org>
Tue, 9 Jun 2020 06:31:02 +0000 (09:31 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 11 Jun 2020 05:05:06 +0000 (08:05 +0300)
This patch adds 6GHz band support and mac80211 registration for
the 6G phy radio.

Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200603001724.12161-3-pradeepc@codeaurora.org
drivers/net/wireless/ath/ath11k/core.h
drivers/net/wireless/ath/ath11k/mac.c
drivers/net/wireless/ath/ath11k/wmi.c

index e04f0e7..67dee66 100644 (file)
@@ -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;
index b55a374..ea732f9 100644 (file)
@@ -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,23 +5807,48 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar,
        }
 
        if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
-               channels = kmemdup(ath11k_5ghz_channels,
-                                  sizeof(ath11k_5ghz_channels),
-                                  GFP_KERNEL);
-               if (!channels) {
-                       kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
-                       return -ENOMEM;
+               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);
                }
 
-               band = &ar->mac.sbands[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);
+               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;
+                       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;
@@ -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);
 }
index c2a9723..291fb27 100644 (file)
@@ -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];