nl80211: S1G band and channel definitions
authorThomas Pedersen <thomas@adapt-ip.com>
Tue, 2 Jun 2020 06:22:47 +0000 (23:22 -0700)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 31 Jul 2020 07:24:13 +0000 (09:24 +0200)
Gives drivers the definitions needed to advertise support
for S1G bands.

Signed-off-by: Thomas Pedersen <thomas@adapt-ip.com>
Link: https://lore.kernel.org/r/20200602062247.23212-1-thomas@adapt-ip.com
Link: https://lore.kernel.org/r/20200731055636.795173-1-thomas@adapt-ip.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/ath/ath10k/mac.c
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/mac80211/chan.c
net/mac80211/scan.c
net/mac80211/tx.c
net/mac80211/util.c
net/wireless/chan.c
net/wireless/core.c
net/wireless/util.c

index 919d155..3c0c33a 100644 (file)
@@ -568,11 +568,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
                case NL80211_CHAN_WIDTH_40:
                        phymode = MODE_11NG_HT40;
                        break;
-               case NL80211_CHAN_WIDTH_5:
-               case NL80211_CHAN_WIDTH_10:
-               case NL80211_CHAN_WIDTH_80:
-               case NL80211_CHAN_WIDTH_80P80:
-               case NL80211_CHAN_WIDTH_160:
+               default:
                        phymode = MODE_UNKNOWN;
                        break;
                }
@@ -597,8 +593,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
                case NL80211_CHAN_WIDTH_80P80:
                        phymode = MODE_11AC_VHT80_80;
                        break;
-               case NL80211_CHAN_WIDTH_5:
-               case NL80211_CHAN_WIDTH_10:
+               default:
                        phymode = MODE_UNKNOWN;
                        break;
                }
index fc7e880..ac6e581 100644 (file)
@@ -418,6 +418,22 @@ struct ieee80211_edmg {
 };
 
 /**
+ * struct ieee80211_sta_s1g_cap - STA's S1G capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11ah S1G capabilities for a STA.
+ *
+ * @s1g_supported: is STA an S1G STA
+ * @cap: S1G capabilities information
+ * @nss_mcs: Supported NSS MCS set
+ */
+struct ieee80211_sta_s1g_cap {
+       bool s1g;
+       u8 cap[10]; /* use S1G_CAPAB_ */
+       u8 nss_mcs[5];
+};
+
+/**
  * struct ieee80211_supported_band - frequency band definition
  *
  * This structure describes a frequency band a wiphy
@@ -448,6 +464,7 @@ struct ieee80211_supported_band {
        int n_bitrates;
        struct ieee80211_sta_ht_cap ht_cap;
        struct ieee80211_sta_vht_cap vht_cap;
+       struct ieee80211_sta_s1g_cap s1g_cap;
        struct ieee80211_edmg edmg_cap;
        u16 n_iftype_data;
        const struct ieee80211_sband_iftype_data *iftype_data;
index 4e6339a..ad18346 100644 (file)
@@ -4437,6 +4437,11 @@ enum nl80211_key_mode {
  *     attribute must be provided as well
  * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel
  * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_1: 1 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_2: 2 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_4: 4 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_8: 8 MHz OFDM channel
+ * @NL80211_CHAN_WIDTH_16: 16 MHz OFDM channel
  */
 enum nl80211_chan_width {
        NL80211_CHAN_WIDTH_20_NOHT,
@@ -4447,6 +4452,11 @@ enum nl80211_chan_width {
        NL80211_CHAN_WIDTH_160,
        NL80211_CHAN_WIDTH_5,
        NL80211_CHAN_WIDTH_10,
+       NL80211_CHAN_WIDTH_1,
+       NL80211_CHAN_WIDTH_2,
+       NL80211_CHAN_WIDTH_4,
+       NL80211_CHAN_WIDTH_8,
+       NL80211_CHAN_WIDTH_16,
 };
 
 /**
@@ -4457,11 +4467,15 @@ enum nl80211_chan_width {
  * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible
  * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide
  * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_1: control channel is 1 MHz wide
+ * @NL80211_BSS_CHAN_WIDTH_2: control channel is 2 MHz wide
  */
 enum nl80211_bss_scan_width {
        NL80211_BSS_CHAN_WIDTH_20,
        NL80211_BSS_CHAN_WIDTH_10,
        NL80211_BSS_CHAN_WIDTH_5,
+       NL80211_BSS_CHAN_WIDTH_1,
+       NL80211_BSS_CHAN_WIDTH_2,
 };
 
 /**
@@ -4740,6 +4754,7 @@ enum nl80211_txrate_gi {
  * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
  * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 69.12 GHz)
  * @NL80211_BAND_6GHZ: around 6 GHz band (5.9 - 7.2 GHz)
+ * @NL80211_BAND_S1GHZ: around 900MHz, supported by S1G PHYs
  * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace
  *     since newer kernel versions may support more bands
  */
@@ -4748,6 +4763,7 @@ enum nl80211_band {
        NL80211_BAND_5GHZ,
        NL80211_BAND_60GHZ,
        NL80211_BAND_6GHZ,
+       NL80211_BAND_S1GHZ,
 
        NUM_NL80211_BANDS,
 };
index e6e192f..08cf9da 100644 (file)
@@ -313,9 +313,14 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
 
        lockdep_assert_held(&local->chanctx_mtx);
 
-       /* don't optimize 5MHz, 10MHz, and radar_enabled confs */
+       /* don't optimize non-20MHz based and radar_enabled confs */
        if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
            ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_1 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_2 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_4 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_8 ||
+           ctx->conf.def.width == NL80211_CHAN_WIDTH_16 ||
            ctx->conf.radar_enabled) {
                ctx->conf.min_def = ctx->conf.def;
                return;
index ad90bbe..8003be6 100644 (file)
@@ -913,6 +913,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
        case NL80211_BSS_CHAN_WIDTH_10:
                local->scan_chandef.width = NL80211_CHAN_WIDTH_10;
                break;
+       default:
        case NL80211_BSS_CHAN_WIDTH_20:
                /* If scanning on oper channel, use whatever channel-type
                 * is currently in use.
index 1a2941e..ee30ef4 100644 (file)
@@ -166,6 +166,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
                        if (r->flags & IEEE80211_RATE_MANDATORY_A)
                                mrate = r->bitrate;
                        break;
+               case NL80211_BAND_S1GHZ:
                case NL80211_BAND_60GHZ:
                        /* TODO, for now fall through */
                case NUM_NL80211_BANDS:
index 21c9409..64a83ec 100644 (file)
@@ -3730,6 +3730,11 @@ u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
                c->width = NL80211_CHAN_WIDTH_20_NOHT;
                ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
                break;
+       case NL80211_CHAN_WIDTH_1:
+       case NL80211_CHAN_WIDTH_2:
+       case NL80211_CHAN_WIDTH_4:
+       case NL80211_CHAN_WIDTH_8:
+       case NL80211_CHAN_WIDTH_16:
        case NL80211_CHAN_WIDTH_5:
        case NL80211_CHAN_WIDTH_10:
                WARN_ON_ONCE(1);
index cddf92c..90f0f82 100644 (file)
@@ -153,6 +153,11 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
        control_freq = chandef->chan->center_freq;
 
        switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_1:
+       case NL80211_CHAN_WIDTH_2:
+       case NL80211_CHAN_WIDTH_4:
+       case NL80211_CHAN_WIDTH_8:
+       case NL80211_CHAN_WIDTH_16:
        case NL80211_CHAN_WIDTH_5:
        case NL80211_CHAN_WIDTH_10:
        case NL80211_CHAN_WIDTH_20:
@@ -263,6 +268,21 @@ static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
        int width;
 
        switch (c->width) {
+       case NL80211_CHAN_WIDTH_1:
+               width = 1;
+               break;
+       case NL80211_CHAN_WIDTH_2:
+               width = 2;
+               break;
+       case NL80211_CHAN_WIDTH_4:
+               width = 4;
+               break;
+       case NL80211_CHAN_WIDTH_8:
+               width = 8;
+               break;
+       case NL80211_CHAN_WIDTH_16:
+               width = 16;
+               break;
        case NL80211_CHAN_WIDTH_5:
                width = 5;
                break;
@@ -911,6 +931,21 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
        control_freq = chandef->chan->center_freq;
 
        switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_1:
+               width = 1;
+               break;
+       case NL80211_CHAN_WIDTH_2:
+               width = 2;
+               break;
+       case NL80211_CHAN_WIDTH_4:
+               width = 4;
+               break;
+       case NL80211_CHAN_WIDTH_8:
+               width = 8;
+               break;
+       case NL80211_CHAN_WIDTH_16:
+               width = 16;
+               break;
        case NL80211_CHAN_WIDTH_5:
                width = 5;
                break;
index c623d9b..1971d7e 100644 (file)
@@ -803,10 +803,11 @@ int wiphy_register(struct wiphy *wiphy)
                if (WARN_ON(!sband->n_channels))
                        return -EINVAL;
                /*
-                * on 60GHz band, there are no legacy rates, so
+                * on 60GHz or sub-1Ghz band, there are no legacy rates, so
                 * n_bitrates is 0
                 */
-               if (WARN_ON(band != NL80211_BAND_60GHZ &&
+               if (WARN_ON((band != NL80211_BAND_60GHZ &&
+                            band != NL80211_BAND_S1GHZ) &&
                            !sband->n_bitrates))
                        return -EINVAL;
 
index 4d3b76f..26a9773 100644 (file)
@@ -102,6 +102,8 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
                if (chan < 7)
                        return MHZ_TO_KHZ(56160 + chan * 2160);
                break;
+       case NL80211_BAND_S1GHZ:
+               return 902000 + chan * 500;
        default:
                ;
        }
@@ -210,6 +212,12 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband)
                WARN_ON(!sband->ht_cap.ht_supported);
                WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e);
                break;
+       case NL80211_BAND_S1GHZ:
+               /* Figure 9-589bd: 3 means unsupported, so != 3 means at least
+                * mandatory is ok.
+                */
+               WARN_ON((sband->s1g_cap.nss_mcs[0] & 0x3) == 0x3);
+               break;
        case NUM_NL80211_BANDS:
        default:
                WARN_ON(1);