@@ -5361,11 +5361,21 @@ static void ieee80211_rx_bss_info(struct ieee80211_link_data *link,
struct ieee80211_local *local = sdata->local;
struct ieee80211_bss *bss;
struct ieee80211_channel *channel;
+ u32 rx_freq_khz = ieee80211_rx_status_to_khz(rx_status);
+ enum nl80211_regulatory_power_modes power_mode_6ghz;
sdata_assert_lock(sdata);
- channel = ieee80211_get_channel_khz(local->hw.wiphy,
- ieee80211_rx_status_to_khz(rx_status));
+ if (is_6ghz_freq_khz(rx_freq_khz)) {
+ ieee80211_get_6ghz_power_mode(&sdata->wdev, 0,
+ &power_mode_6ghz);
+ channel = ieee80211_get_6ghz_channel_khz(local->hw.wiphy,
+ rx_freq_khz,
+ power_mode_6ghz);
+ } else {
+ channel = ieee80211_get_channel_khz(local->hw.wiphy,
+ rx_freq_khz);
+ }
if (!channel)
return;
@@ -261,6 +261,8 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
struct ieee80211_channel *channel;
size_t min_hdr_len = offsetof(struct ieee80211_mgmt,
u.probe_resp.variable);
+ u32 rx_freq_khz = ieee80211_rx_status_to_khz(rx_status);
+ enum nl80211_regulatory_power_modes power_mode_6ghz;
if (!ieee80211_is_probe_resp(mgmt->frame_control) &&
!ieee80211_is_beacon(mgmt->frame_control) &&
@@ -319,8 +321,17 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
return;
}
- channel = ieee80211_get_channel_khz(local->hw.wiphy,
- ieee80211_rx_status_to_khz(rx_status));
+ if (is_6ghz_freq_khz(rx_freq_khz)) {
+ ieee80211_get_6ghz_power_mode(sdata1 ? &sdata1->wdev : &sdata2->wdev,
+ 0, &power_mode_6ghz);
+
+ channel = ieee80211_get_6ghz_channel_khz(local->hw.wiphy,
+ rx_freq_khz,
+ power_mode_6ghz);
+ } else {
+ channel = ieee80211_get_channel_khz(local->hw.wiphy,
+ rx_freq_khz);
+ }
if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
return;
@@ -1574,12 +1574,26 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
return 0;
}
-static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
+static struct ieee80211_channel *nl80211_get_valid_chan(struct wireless_dev *wdev,
+ unsigned int link_id,
u32 freq)
{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
struct ieee80211_channel *chan;
+ enum nl80211_regulatory_power_modes power_mode_6ghz;
+
+ if (is_6ghz_freq_khz(freq)) {
+ power_mode_6ghz = rdev_get_6ghz_power_mode(rdev, wdev, link_id);
+
+ if (power_mode_6ghz >= NL80211_REG_PWR_MODE_MAX)
+ return NULL;
+
+ chan = ieee80211_get_6ghz_channel_khz(wiphy, freq, power_mode_6ghz);
+ } else {
+ chan = ieee80211_get_channel_khz(wiphy, freq);
+ }
- chan = ieee80211_get_channel_khz(wiphy, freq);
if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
return NULL;
return chan;
@@ -10652,7 +10666,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
freq +=
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
- chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
+ chan = nl80211_get_valid_chan(dev->ieee80211_ptr, 0, freq);
if (!chan)
return -EINVAL;
@@ -10861,6 +10875,8 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
}
static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ unsigned int link_id,
const u8 *ssid, int ssid_len,
struct nlattr **attrs,
const u8 **bssid_out)
@@ -10879,7 +10895,7 @@ static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device
if (attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
freq += nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
- chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
+ chan = nl80211_get_valid_chan(dev->ieee80211_ptr, link_id, freq);
if (!chan)
return ERR_PTR(-EINVAL);
@@ -11062,8 +11078,8 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
goto free;
}
req.links[link_id].bss =
- nl80211_assoc_bss(rdev, ssid, ssid_len, attrs,
- &bssid);
+ nl80211_assoc_bss(rdev, dev, link_id, ssid, ssid_len,
+ attrs, &bssid);
if (IS_ERR(req.links[link_id].bss)) {
err = PTR_ERR(req.links[link_id].bss);
req.links[link_id].bss = NULL;
@@ -11114,7 +11130,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
if (req.link_id >= 0)
return -EINVAL;
- req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs,
+ req.bss = nl80211_assoc_bss(rdev, dev, 0, ssid, ssid_len, info->attrs,
&bssid);
if (IS_ERR(req.bss))
return PTR_ERR(req.bss);
@@ -11813,13 +11829,14 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
if (freq) {
- connect.channel = nl80211_get_valid_chan(wiphy, freq);
+ connect.channel = nl80211_get_valid_chan(dev->ieee80211_ptr, 0, freq);
if (!connect.channel)
return -EINVAL;
} else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
freq = MHZ_TO_KHZ(freq);
- connect.channel_hint = nl80211_get_valid_chan(wiphy, freq);
+ connect.channel_hint = nl80211_get_valid_chan(dev->ieee80211_ptr, 0,
+ freq);
if (!connect.channel_hint)
return -EINVAL;
}
Commit "wifi: mac80211: add support for 6 GHz channels and regulatory" adds different channel pools for different power modes for 6 GHz channels. Currently, during MLME and association BSS handling, channel is fetched from older API ieee80211_get_channel_khz which will not consider the power mode for 6 GHz. Hence use proper API ieee80211_get_6ghz_channel_khz to fetch the 6 GHz channel. Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com> --- net/mac80211/mlme.c | 14 ++++++++++++-- net/mac80211/scan.c | 15 +++++++++++++-- net/wireless/nl80211.c | 35 ++++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 13 deletions(-)