diff options
Diffstat (limited to 'net/wireless/reg.c')
| -rw-r--r-- | net/wireless/reg.c | 59 |
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(®_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); } |
