summaryrefslogtreecommitdiff
path: root/net/wireless/reg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/reg.c')
-rw-r--r--net/wireless/reg.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 970880924eca..d68c7318805a 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1760,13 +1760,11 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
if (ignore_reg_update(wiphy, initiator)) {
/*
* Regulatory updates set by CORE are ignored for custom
- * regulatory cards and for self managed regulatory.
- * Let us notify the changes to the driver,
+ * regulatory cards. Let us notify the changes to the driver,
* as some drivers used this to restore its orig_* reg domain.
*/
- if ((initiator == NL80211_REGDOM_SET_BY_CORE &&
- wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) ||
- (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED))
+ if (initiator == NL80211_REGDOM_SET_BY_CORE &&
+ wiphy->regulatory_flags & REGULATORY_CUSTOM_REG)
reg_call_notifier(wiphy, lr);
return;
}
@@ -1796,14 +1794,6 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
reg_check_channels();
}
-void cfg80211_send_reg_change_event(struct regulatory_request *request,
- struct wiphy *wiphy)
-{
- request->wiphy_idx = get_wiphy_idx(wiphy);
- nl80211_send_reg_change_event(request);
-}
-EXPORT_SYMBOL(cfg80211_send_reg_change_event);
-
static void handle_channel_custom(struct wiphy *wiphy,
struct ieee80211_channel *chan,
const struct ieee80211_regdomain *regd)
@@ -2257,7 +2247,22 @@ out_free:
reg_free_request(reg_request);
}
-static bool reg_only_self_managed_wiphys(struct regulatory_request *reg_request)
+static void notify_self_managed_wiphys(struct regulatory_request *request)
+{
+ struct cfg80211_registered_device *rdev;
+ struct wiphy *wiphy;
+
+ list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+ wiphy = &rdev->wiphy;
+ if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
+ request->initiator == NL80211_REGDOM_SET_BY_USER &&
+ request->user_reg_hint_type ==
+ NL80211_USER_REG_HINT_CELL_BASE)
+ reg_call_notifier(wiphy, request);
+ }
+}
+
+static bool reg_only_self_managed_wiphys(void)
{
struct cfg80211_registered_device *rdev;
struct wiphy *wiphy;
@@ -2267,12 +2272,10 @@ static bool reg_only_self_managed_wiphys(struct regulatory_request *reg_request)
list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
wiphy = &rdev->wiphy;
- if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
+ if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
self_managed_found = true;
- reg_call_notifier(wiphy, reg_request);
- } else {
+ else
return false;
- }
}
/* make sure at least one self-managed wiphy exists */
@@ -2310,7 +2313,8 @@ static void reg_process_pending_hints(void)
spin_unlock(&reg_requests_lock);
- if (reg_only_self_managed_wiphys(reg_request)) {
+ notify_self_managed_wiphys(reg_request);
+ if (reg_only_self_managed_wiphys()) {
reg_free_request(reg_request);
return;
}
@@ -3188,17 +3192,26 @@ EXPORT_SYMBOL(regulatory_set_wiphy_regd_sync_rtnl);
void wiphy_regulatory_register(struct wiphy *wiphy)
{
- struct regulatory_request *lr;
+ struct regulatory_request *lr = get_last_request();
- /* self-managed devices ignore external hints */
- if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
+ /* self-managed devices ignore beacon hints and country IE */
+ if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS |
REGULATORY_COUNTRY_IE_IGNORE;
+ /*
+ * The last request may have been received before this
+ * registration call. Call the driver notifier if
+ * initiator is USER and user type is CELL_BASE.
+ */
+ if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
+ lr->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE)
+ reg_call_notifier(wiphy, lr);
+ }
+
if (!reg_dev_ignore_cell_hint(wiphy))
reg_num_devs_support_basehint++;
- lr = get_last_request();
wiphy_update_regulatory(wiphy, lr->initiator);
}