aboutsummaryrefslogtreecommitdiff
path: root/net/wireless/chan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/chan.c')
-rw-r--r--net/wireless/chan.c93
1 files changed, 56 insertions, 37 deletions
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index fcac5c6366e1..cddf92c5d09e 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -6,7 +6,7 @@
*
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright 2018 Intel Corporation
+ * Copyright 2018-2020 Intel Corporation
*/
#include <linux/export.h>
@@ -27,6 +27,7 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
return;
chandef->chan = chan;
+ chandef->freq1_offset = chan->freq_offset;
chandef->center_freq2 = 0;
chandef->edmg.bw_config = 0;
chandef->edmg.channels = 0;
@@ -146,6 +147,9 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
if (!chandef->chan)
return false;
+ if (chandef->freq1_offset >= 1000)
+ return false;
+
control_freq = chandef->chan->center_freq;
switch (chandef->width) {
@@ -153,7 +157,8 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
case NL80211_CHAN_WIDTH_10:
case NL80211_CHAN_WIDTH_20:
case NL80211_CHAN_WIDTH_20_NOHT:
- if (chandef->center_freq1 != control_freq)
+ if (ieee80211_chandef_to_khz(chandef) !=
+ ieee80211_channel_to_khz(chandef->chan))
return false;
if (chandef->center_freq2)
return false;
@@ -386,10 +391,11 @@ static u32 cfg80211_get_start_freq(u32 center_freq,
{
u32 start_freq;
- if (bandwidth <= 20)
+ bandwidth = MHZ_TO_KHZ(bandwidth);
+ if (bandwidth <= MHZ_TO_KHZ(20))
start_freq = center_freq;
else
- start_freq = center_freq - bandwidth/2 + 10;
+ start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
return start_freq;
}
@@ -399,10 +405,11 @@ static u32 cfg80211_get_end_freq(u32 center_freq,
{
u32 end_freq;
- if (bandwidth <= 20)
+ bandwidth = MHZ_TO_KHZ(bandwidth);
+ if (bandwidth <= MHZ_TO_KHZ(20))
end_freq = center_freq;
else
- end_freq = center_freq + bandwidth/2 - 10;
+ end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
return end_freq;
}
@@ -417,8 +424,8 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
- for (freq = start_freq; freq <= end_freq; freq += 20) {
- c = ieee80211_get_channel(wiphy, freq);
+ for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
if (!c)
return -EINVAL;
@@ -449,8 +456,8 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
return -EINVAL;
ret = cfg80211_get_chans_dfs_required(wiphy,
- chandef->center_freq1,
- width);
+ ieee80211_chandef_to_khz(chandef),
+ width);
if (ret < 0)
return ret;
else if (ret > 0)
@@ -460,8 +467,8 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
return 0;
ret = cfg80211_get_chans_dfs_required(wiphy,
- chandef->center_freq2,
- width);
+ MHZ_TO_KHZ(chandef->center_freq2),
+ width);
if (ret < 0)
return ret;
else if (ret > 0)
@@ -503,8 +510,8 @@ static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
* DFS_AVAILABLE). Return number of usable channels
* (require CAC). Allow DFS and non-DFS channel mix.
*/
- for (freq = start_freq; freq <= end_freq; freq += 20) {
- c = ieee80211_get_channel(wiphy, freq);
+ for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
if (!c)
return -EINVAL;
@@ -536,8 +543,9 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
if (width < 0)
return false;
- r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1,
- width);
+ r1 = cfg80211_get_chans_dfs_usable(wiphy,
+ MHZ_TO_KHZ(chandef->center_freq1),
+ width);
if (r1 < 0)
return false;
@@ -546,8 +554,8 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
case NL80211_CHAN_WIDTH_80P80:
WARN_ON(!chandef->center_freq2);
r2 = cfg80211_get_chans_dfs_usable(wiphy,
- chandef->center_freq2,
- width);
+ MHZ_TO_KHZ(chandef->center_freq2),
+ width);
if (r2 < 0)
return false;
break;
@@ -694,8 +702,8 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
* If any channel in between is disabled or has not
* had gone through CAC return false
*/
- for (freq = start_freq; freq <= end_freq; freq += 20) {
- c = ieee80211_get_channel(wiphy, freq);
+ for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
if (!c)
return false;
@@ -724,7 +732,8 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
if (width < 0)
return false;
- r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1,
+ r = cfg80211_get_chans_dfs_available(wiphy,
+ MHZ_TO_KHZ(chandef->center_freq1),
width);
/* If any of channels unavailable for cf1 just return */
@@ -735,8 +744,8 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
case NL80211_CHAN_WIDTH_80P80:
WARN_ON(!chandef->center_freq2);
r = cfg80211_get_chans_dfs_available(wiphy,
- chandef->center_freq2,
- width);
+ MHZ_TO_KHZ(chandef->center_freq2),
+ width);
break;
default:
WARN_ON(chandef->center_freq2);
@@ -757,8 +766,8 @@ static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
- for (freq = start_freq; freq <= end_freq; freq += 20) {
- c = ieee80211_get_channel(wiphy, freq);
+ for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
if (!c)
return 0;
@@ -790,14 +799,14 @@ cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
return 0;
t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
- chandef->center_freq1,
+ MHZ_TO_KHZ(chandef->center_freq1),
width);
if (!chandef->center_freq2)
return t1;
t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
- chandef->center_freq2,
+ MHZ_TO_KHZ(chandef->center_freq2),
width);
return max(t1, t2);
@@ -813,8 +822,8 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
- for (freq = start_freq; freq <= end_freq; freq += 20) {
- c = ieee80211_get_channel(wiphy, freq);
+ for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+ c = ieee80211_get_channel_khz(wiphy, freq);
if (!c || c->flags & prohibited_flags)
return false;
}
@@ -910,7 +919,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
width = 10;
break;
case NL80211_CHAN_WIDTH_20:
- if (!ht_cap->ht_supported)
+ if (!ht_cap->ht_supported &&
+ chandef->chan->band != NL80211_BAND_6GHZ)
return false;
/* fall through */
case NL80211_CHAN_WIDTH_20_NOHT:
@@ -919,6 +929,8 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
break;
case NL80211_CHAN_WIDTH_40:
width = 40;
+ if (chandef->chan->band == NL80211_BAND_6GHZ)
+ break;
if (!ht_cap->ht_supported)
return false;
if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
@@ -933,24 +945,29 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
break;
case NL80211_CHAN_WIDTH_80P80:
cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
- if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
+ if (chandef->chan->band != NL80211_BAND_6GHZ &&
+ cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
return false;
/* fall through */
case NL80211_CHAN_WIDTH_80:
- if (!vht_cap->vht_supported)
- return false;
prohibited_flags |= IEEE80211_CHAN_NO_80MHZ;
width = 80;
+ if (chandef->chan->band == NL80211_BAND_6GHZ)
+ break;
+ if (!vht_cap->vht_supported)
+ return false;
break;
case NL80211_CHAN_WIDTH_160:
+ prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
+ width = 160;
+ if (chandef->chan->band == NL80211_BAND_6GHZ)
+ break;
if (!vht_cap->vht_supported)
return false;
cap = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
if (cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ &&
cap != IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
return false;
- prohibited_flags |= IEEE80211_CHAN_NO_160MHZ;
- width = 160;
break;
default:
WARN_ON_ONCE(1);
@@ -976,13 +993,15 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
- if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1,
+ if (!cfg80211_secondary_chans_ok(wiphy,
+ ieee80211_chandef_to_khz(chandef),
width, prohibited_flags))
return false;
if (!chandef->center_freq2)
return true;
- return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2,
+ return cfg80211_secondary_chans_ok(wiphy,
+ MHZ_TO_KHZ(chandef->center_freq2),
width, prohibited_flags);
}
EXPORT_SYMBOL(cfg80211_chandef_usable);