Commit df78a0c0 authored by Thomas Pedersen's avatar Thomas Pedersen Committed by Johannes Berg

nl80211: S1G band and channel definitions

Gives drivers the definitions needed to advertise support
for S1G bands.
Signed-off-by: default avatarThomas 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.comSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 41d707b7
...@@ -568,11 +568,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef) ...@@ -568,11 +568,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
case NL80211_CHAN_WIDTH_40: case NL80211_CHAN_WIDTH_40:
phymode = MODE_11NG_HT40; phymode = MODE_11NG_HT40;
break; break;
case NL80211_CHAN_WIDTH_5: default:
case NL80211_CHAN_WIDTH_10:
case NL80211_CHAN_WIDTH_80:
case NL80211_CHAN_WIDTH_80P80:
case NL80211_CHAN_WIDTH_160:
phymode = MODE_UNKNOWN; phymode = MODE_UNKNOWN;
break; break;
} }
...@@ -597,8 +593,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef) ...@@ -597,8 +593,7 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
case NL80211_CHAN_WIDTH_80P80: case NL80211_CHAN_WIDTH_80P80:
phymode = MODE_11AC_VHT80_80; phymode = MODE_11AC_VHT80_80;
break; break;
case NL80211_CHAN_WIDTH_5: default:
case NL80211_CHAN_WIDTH_10:
phymode = MODE_UNKNOWN; phymode = MODE_UNKNOWN;
break; break;
} }
......
...@@ -417,6 +417,22 @@ struct ieee80211_edmg { ...@@ -417,6 +417,22 @@ struct ieee80211_edmg {
enum ieee80211_edmg_bw_config bw_config; enum ieee80211_edmg_bw_config bw_config;
}; };
/**
* 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 * struct ieee80211_supported_band - frequency band definition
* *
...@@ -448,6 +464,7 @@ struct ieee80211_supported_band { ...@@ -448,6 +464,7 @@ struct ieee80211_supported_band {
int n_bitrates; int n_bitrates;
struct ieee80211_sta_ht_cap ht_cap; struct ieee80211_sta_ht_cap ht_cap;
struct ieee80211_sta_vht_cap vht_cap; struct ieee80211_sta_vht_cap vht_cap;
struct ieee80211_sta_s1g_cap s1g_cap;
struct ieee80211_edmg edmg_cap; struct ieee80211_edmg edmg_cap;
u16 n_iftype_data; u16 n_iftype_data;
const struct ieee80211_sband_iftype_data *iftype_data; const struct ieee80211_sband_iftype_data *iftype_data;
......
...@@ -4437,6 +4437,11 @@ enum nl80211_key_mode { ...@@ -4437,6 +4437,11 @@ enum nl80211_key_mode {
* attribute must be provided as well * attribute must be provided as well
* @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel
* @NL80211_CHAN_WIDTH_10: 10 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 { enum nl80211_chan_width {
NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_20_NOHT,
...@@ -4447,6 +4452,11 @@ enum nl80211_chan_width { ...@@ -4447,6 +4452,11 @@ enum nl80211_chan_width {
NL80211_CHAN_WIDTH_160, NL80211_CHAN_WIDTH_160,
NL80211_CHAN_WIDTH_5, NL80211_CHAN_WIDTH_5,
NL80211_CHAN_WIDTH_10, 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 { ...@@ -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_20: control channel is 20 MHz wide or compatible
* @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide * @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_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 { enum nl80211_bss_scan_width {
NL80211_BSS_CHAN_WIDTH_20, NL80211_BSS_CHAN_WIDTH_20,
NL80211_BSS_CHAN_WIDTH_10, NL80211_BSS_CHAN_WIDTH_10,
NL80211_BSS_CHAN_WIDTH_5, NL80211_BSS_CHAN_WIDTH_5,
NL80211_BSS_CHAN_WIDTH_1,
NL80211_BSS_CHAN_WIDTH_2,
}; };
/** /**
...@@ -4740,6 +4754,7 @@ enum nl80211_txrate_gi { ...@@ -4740,6 +4754,7 @@ enum nl80211_txrate_gi {
* @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) * @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_60GHZ: around 60 GHz band (58.32 - 69.12 GHz)
* @NL80211_BAND_6GHZ: around 6 GHz band (5.9 - 7.2 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 * @NUM_NL80211_BANDS: number of bands, avoid using this in userspace
* since newer kernel versions may support more bands * since newer kernel versions may support more bands
*/ */
...@@ -4748,6 +4763,7 @@ enum nl80211_band { ...@@ -4748,6 +4763,7 @@ enum nl80211_band {
NL80211_BAND_5GHZ, NL80211_BAND_5GHZ,
NL80211_BAND_60GHZ, NL80211_BAND_60GHZ,
NL80211_BAND_6GHZ, NL80211_BAND_6GHZ,
NL80211_BAND_S1GHZ,
NUM_NL80211_BANDS, NUM_NL80211_BANDS,
}; };
......
...@@ -313,9 +313,14 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, ...@@ -313,9 +313,14 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
lockdep_assert_held(&local->chanctx_mtx); 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 || if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
ctx->conf.def.width == NL80211_CHAN_WIDTH_10 || 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.radar_enabled) {
ctx->conf.min_def = ctx->conf.def; ctx->conf.min_def = ctx->conf.def;
return; return;
......
...@@ -913,6 +913,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, ...@@ -913,6 +913,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
case NL80211_BSS_CHAN_WIDTH_10: case NL80211_BSS_CHAN_WIDTH_10:
local->scan_chandef.width = NL80211_CHAN_WIDTH_10; local->scan_chandef.width = NL80211_CHAN_WIDTH_10;
break; break;
default:
case NL80211_BSS_CHAN_WIDTH_20: case NL80211_BSS_CHAN_WIDTH_20:
/* If scanning on oper channel, use whatever channel-type /* If scanning on oper channel, use whatever channel-type
* is currently in use. * is currently in use.
......
...@@ -166,6 +166,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, ...@@ -166,6 +166,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
if (r->flags & IEEE80211_RATE_MANDATORY_A) if (r->flags & IEEE80211_RATE_MANDATORY_A)
mrate = r->bitrate; mrate = r->bitrate;
break; break;
case NL80211_BAND_S1GHZ:
case NL80211_BAND_60GHZ: case NL80211_BAND_60GHZ:
/* TODO, for now fall through */ /* TODO, for now fall through */
case NUM_NL80211_BANDS: case NUM_NL80211_BANDS:
......
...@@ -3730,6 +3730,11 @@ u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c) ...@@ -3730,6 +3730,11 @@ u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
c->width = NL80211_CHAN_WIDTH_20_NOHT; c->width = NL80211_CHAN_WIDTH_20_NOHT;
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
break; 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_5:
case NL80211_CHAN_WIDTH_10: case NL80211_CHAN_WIDTH_10:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
......
...@@ -153,6 +153,11 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) ...@@ -153,6 +153,11 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
control_freq = chandef->chan->center_freq; control_freq = chandef->chan->center_freq;
switch (chandef->width) { 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_5:
case NL80211_CHAN_WIDTH_10: case NL80211_CHAN_WIDTH_10:
case NL80211_CHAN_WIDTH_20: case NL80211_CHAN_WIDTH_20:
...@@ -263,6 +268,21 @@ static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c) ...@@ -263,6 +268,21 @@ static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
int width; int width;
switch (c->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: case NL80211_CHAN_WIDTH_5:
width = 5; width = 5;
break; break;
...@@ -911,6 +931,21 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, ...@@ -911,6 +931,21 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
control_freq = chandef->chan->center_freq; control_freq = chandef->chan->center_freq;
switch (chandef->width) { 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: case NL80211_CHAN_WIDTH_5:
width = 5; width = 5;
break; break;
......
...@@ -803,10 +803,11 @@ int wiphy_register(struct wiphy *wiphy) ...@@ -803,10 +803,11 @@ int wiphy_register(struct wiphy *wiphy)
if (WARN_ON(!sband->n_channels)) if (WARN_ON(!sband->n_channels))
return -EINVAL; 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 * 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)) !sband->n_bitrates))
return -EINVAL; return -EINVAL;
......
...@@ -102,6 +102,8 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band) ...@@ -102,6 +102,8 @@ u32 ieee80211_channel_to_freq_khz(int chan, enum nl80211_band band)
if (chan < 7) if (chan < 7)
return MHZ_TO_KHZ(56160 + chan * 2160); return MHZ_TO_KHZ(56160 + chan * 2160);
break; break;
case NL80211_BAND_S1GHZ:
return 902000 + chan * 500;
default: default:
; ;
} }
...@@ -210,6 +212,12 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband) ...@@ -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.ht_supported);
WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e); WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e);
break; 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: case NUM_NL80211_BANDS:
default: default:
WARN_ON(1); WARN_ON(1);
......
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