]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/wireless/reg.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[karo-tx-linux.git] / net / wireless / reg.c
index 47be6163381caadf41afab40122d74f4a19448e6..d39d1cbc86b1663f1902e6662dfe372c50978327 100644 (file)
@@ -1530,39 +1530,40 @@ static void reg_call_notifier(struct wiphy *wiphy,
 
 static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
-       struct ieee80211_channel *ch;
        struct cfg80211_chan_def chandef;
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
-       bool ret = true;
+       enum nl80211_iftype iftype;
 
        wdev_lock(wdev);
+       iftype = wdev->iftype;
 
+       /* make sure the interface is active */
        if (!wdev->netdev || !netif_running(wdev->netdev))
-               goto out;
+               goto wdev_inactive_unlock;
 
-       switch (wdev->iftype) {
+       switch (iftype) {
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_P2P_GO:
                if (!wdev->beacon_interval)
-                       goto out;
-
-               ret = cfg80211_reg_can_beacon(wiphy,
-                                             &wdev->chandef, wdev->iftype);
+                       goto wdev_inactive_unlock;
+               chandef = wdev->chandef;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               if (!wdev->ssid_len)
+                       goto wdev_inactive_unlock;
+               chandef = wdev->chandef;
                break;
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_P2P_CLIENT:
-       case NL80211_IFTYPE_ADHOC:
                if (!wdev->current_bss ||
                    !wdev->current_bss->pub.channel)
-                       goto out;
+                       goto wdev_inactive_unlock;
 
-               ch = wdev->current_bss->pub.channel;
-               if (rdev->ops->get_channel &&
-                   !rdev_get_channel(rdev, wdev, &chandef))
-                       ret = cfg80211_chandef_usable(wiphy, &chandef,
-                                                     IEEE80211_CHAN_DISABLED);
-               else
-                       ret = !(ch->flags & IEEE80211_CHAN_DISABLED);
+               if (!rdev->ops->get_channel ||
+                   rdev_get_channel(rdev, wdev, &chandef))
+                       cfg80211_chandef_create(&chandef,
+                                               wdev->current_bss->pub.channel,
+                                               NL80211_CHAN_NO_HT);
                break;
        case NL80211_IFTYPE_MONITOR:
        case NL80211_IFTYPE_AP_VLAN:
@@ -1575,9 +1576,26 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
                break;
        }
 
-out:
        wdev_unlock(wdev);
-       return ret;
+
+       switch (iftype) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_P2P_GO:
+       case NL80211_IFTYPE_ADHOC:
+               return cfg80211_reg_can_beacon(wiphy, &chandef, iftype);
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_P2P_CLIENT:
+               return cfg80211_chandef_usable(wiphy, &chandef,
+                                              IEEE80211_CHAN_DISABLED);
+       default:
+               break;
+       }
+
+       return true;
+
+wdev_inactive_unlock:
+       wdev_unlock(wdev);
+       return true;
 }
 
 static void reg_leave_invalid_chans(struct wiphy *wiphy)
@@ -1907,7 +1925,7 @@ static enum reg_request_treatment
 reg_process_hint_driver(struct wiphy *wiphy,
                        struct regulatory_request *driver_request)
 {
-       const struct ieee80211_regdomain *regd;
+       const struct ieee80211_regdomain *regd, *tmp;
        enum reg_request_treatment treatment;
 
        treatment = __reg_process_hint_driver(driver_request);
@@ -1927,7 +1945,10 @@ reg_process_hint_driver(struct wiphy *wiphy,
                        reg_free_request(driver_request);
                        return REG_REQ_IGNORE;
                }
+
+               tmp = get_wiphy_regdom(wiphy);
                rcu_assign_pointer(wiphy->regd, regd);
+               rcu_free_regdom(tmp);
        }
 
 
@@ -1986,11 +2007,8 @@ __reg_process_hint_country_ie(struct wiphy *wiphy,
                        return REG_REQ_IGNORE;
                return REG_REQ_ALREADY_SET;
        }
-       /*
-        * Two consecutive Country IE hints on the same wiphy.
-        * This should be picked up early by the driver/stack
-        */
-       if (WARN_ON(regdom_changes(country_ie_request->alpha2)))
+
+       if (regdom_changes(country_ie_request->alpha2))
                return REG_REQ_OK;
        return REG_REQ_ALREADY_SET;
 }