Commit b13b6bbf authored by Abhishek Kumar's avatar Abhishek Kumar Committed by Johannes Berg

wifi: cfg80211: call reg_call_notifier on beacon hints

Currently the channel property updates are not propagated to
driver. This causes issues in the discovery of hidden SSIDs and
fails to connect to them.
This change defines a new wiphy flag which when enabled by vendor
driver, the reg_call_notifier callback will be trigger on beacon
hints. This ensures that the channel property changes are visible
to the vendor driver. The vendor changes the channels for active
scans. This fixes the discovery issue of hidden SSID.
Signed-off-by: default avatarAbhishek Kumar <kuabhs@chromium.org>
Link: https://lore.kernel.org/r/20230629035254.1.I059fe585f9f9e896c2d51028ef804d197c8c009e@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 13ba6794
...@@ -4861,6 +4861,8 @@ struct cfg80211_ops { ...@@ -4861,6 +4861,8 @@ struct cfg80211_ops {
* @WIPHY_FLAG_SUPPORTS_EXT_KCK_32: The device supports 32-byte KCK keys. * @WIPHY_FLAG_SUPPORTS_EXT_KCK_32: The device supports 32-byte KCK keys.
* @WIPHY_FLAG_NOTIFY_REGDOM_BY_DRIVER: The device could handle reg notify for * @WIPHY_FLAG_NOTIFY_REGDOM_BY_DRIVER: The device could handle reg notify for
* NL80211_REGDOM_SET_BY_DRIVER. * NL80211_REGDOM_SET_BY_DRIVER.
* @WIPHY_FLAG_CHANNEL_CHANGE_ON_BEACON: reg_call_notifier() is called if driver
* set this flag to update channels on beacon hints.
*/ */
enum wiphy_flags { enum wiphy_flags {
WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0), WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0),
...@@ -4887,6 +4889,7 @@ enum wiphy_flags { ...@@ -4887,6 +4889,7 @@ enum wiphy_flags {
WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22), WIPHY_FLAG_SUPPORTS_5_10_MHZ = BIT(22),
WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23), WIPHY_FLAG_HAS_CHANNEL_SWITCH = BIT(23),
WIPHY_FLAG_NOTIFY_REGDOM_BY_DRIVER = BIT(24), WIPHY_FLAG_NOTIFY_REGDOM_BY_DRIVER = BIT(24),
WIPHY_FLAG_CHANNEL_CHANGE_ON_BEACON = BIT(25),
}; };
/** /**
......
...@@ -2151,6 +2151,13 @@ static bool reg_is_world_roaming(struct wiphy *wiphy) ...@@ -2151,6 +2151,13 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
return false; return false;
} }
static void reg_call_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
if (wiphy->reg_notifier)
wiphy->reg_notifier(wiphy, request);
}
static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
struct reg_beacon *reg_beacon) struct reg_beacon *reg_beacon)
{ {
...@@ -2158,6 +2165,7 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, ...@@ -2158,6 +2165,7 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
bool channel_changed = false; bool channel_changed = false;
struct ieee80211_channel chan_before; struct ieee80211_channel chan_before;
struct regulatory_request *lr = get_last_request();
sband = wiphy->bands[reg_beacon->chan.band]; sband = wiphy->bands[reg_beacon->chan.band];
chan = &sband->channels[chan_idx]; chan = &sband->channels[chan_idx];
...@@ -2183,8 +2191,11 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, ...@@ -2183,8 +2191,11 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
channel_changed = true; channel_changed = true;
} }
if (channel_changed) if (channel_changed) {
nl80211_send_beacon_hint_event(wiphy, &chan_before, chan); nl80211_send_beacon_hint_event(wiphy, &chan_before, chan);
if (wiphy->flags & WIPHY_FLAG_CHANNEL_CHANGE_ON_BEACON)
reg_call_notifier(wiphy, lr);
}
} }
/* /*
...@@ -2327,13 +2338,6 @@ static void reg_process_ht_flags(struct wiphy *wiphy) ...@@ -2327,13 +2338,6 @@ static void reg_process_ht_flags(struct wiphy *wiphy)
reg_process_ht_flags_band(wiphy, wiphy->bands[band]); reg_process_ht_flags_band(wiphy, wiphy->bands[band]);
} }
static void reg_call_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
{
if (wiphy->reg_notifier)
wiphy->reg_notifier(wiphy, request);
}
static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
{ {
struct cfg80211_chan_def chandef = {}; struct cfg80211_chan_def chandef = {};
......
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