OSDN Git Service

BACKPORT: cfg80211: remove enum ieee80211_band
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / net / wireless / core.c
index ded9d6d..32870de 100644 (file)
@@ -3,6 +3,7 @@
  *
  * Copyright 2006-2010         Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
+ * Copyright 2015      Intel Deutschland GmbH
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -160,7 +161,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
        if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
                return -EOPNOTSUPP;
 
-       list_for_each_entry(wdev, &rdev->wdev_list, list) {
+       list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
                if (!wdev->netdev)
                        continue;
                wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
@@ -174,7 +175,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
                /* failed -- clean up to old netns */
                net = wiphy_net(&rdev->wiphy);
 
-               list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list,
+               list_for_each_entry_continue_reverse(wdev,
+                                                    &rdev->wiphy.wdev_list,
                                                     list) {
                        if (!wdev->netdev)
                                continue;
@@ -233,7 +235,7 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
 
        ASSERT_RTNL();
 
-       list_for_each_entry(wdev, &rdev->wdev_list, list) {
+       list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
                if (wdev->netdev) {
                        dev_close(wdev->netdev);
                        continue;
@@ -301,7 +303,8 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
                kfree(item);
                spin_unlock_irq(&rdev->destroy_list_lock);
 
-               list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) {
+               list_for_each_entry_safe(wdev, tmp,
+                                        &rdev->wiphy.wdev_list, list) {
                        if (nlportid == wdev->owner_nlportid)
                                rdev_del_virtual_intf(rdev, wdev);
                }
@@ -409,7 +412,7 @@ use_default_name:
                }
        }
 
-       INIT_LIST_HEAD(&rdev->wdev_list);
+       INIT_LIST_HEAD(&rdev->wiphy.wdev_list);
        INIT_LIST_HEAD(&rdev->beacon_registrations);
        spin_lock_init(&rdev->beacon_registrations_lock);
        spin_lock_init(&rdev->bss_lock);
@@ -556,7 +559,7 @@ int wiphy_register(struct wiphy *wiphy)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
        int res;
-       enum ieee80211_band band;
+       enum nl80211_band band;
        struct ieee80211_supported_band *sband;
        bool have_band = false;
        int i;
@@ -625,6 +628,13 @@ int wiphy_register(struct wiphy *wiphy)
                     !rdev->ops->set_mac_acl)))
                return -EINVAL;
 
+       /* assure only valid behaviours are flagged by driver
+        * hence subtract 2 as bit 0 is invalid.
+        */
+       if (WARN_ON(wiphy->bss_select_support &&
+                   (wiphy->bss_select_support & ~(BIT(__NL80211_BSS_SELECT_ATTR_AFTER_LAST) - 2))))
+               return -EINVAL;
+
        if (wiphy->addresses)
                memcpy(wiphy->perm_addr, wiphy->addresses[0].addr, ETH_ALEN);
 
@@ -639,7 +649,7 @@ int wiphy_register(struct wiphy *wiphy)
                return res;
 
        /* sanity check supported bands/channels */
-       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+       for (band = 0; band < NUM_NL80211_BANDS; band++) {
                sband = wiphy->bands[band];
                if (!sband)
                        continue;
@@ -651,7 +661,7 @@ int wiphy_register(struct wiphy *wiphy)
                 * on 60GHz band, there are no legacy rates, so
                 * n_bitrates is 0
                 */
-               if (WARN_ON(band != IEEE80211_BAND_60GHZ &&
+               if (WARN_ON(band != NL80211_BAND_60GHZ &&
                            !sband->n_bitrates))
                        return -EINVAL;
 
@@ -661,7 +671,7 @@ int wiphy_register(struct wiphy *wiphy)
                 * global structure for that.
                 */
                if (cfg80211_disable_40mhz_24ghz &&
-                   band == IEEE80211_BAND_2GHZ &&
+                   band == NL80211_BAND_2GHZ &&
                    sband->ht_cap.ht_supported) {
                        sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
                        sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
@@ -739,6 +749,36 @@ int wiphy_register(struct wiphy *wiphy)
                nl80211_send_reg_change_event(&request);
        }
 
+       /* Check that nobody globally advertises any capabilities they do not
+        * advertise on all possible interface types.
+        */
+       if (wiphy->extended_capabilities_len &&
+           wiphy->num_iftype_ext_capab &&
+           wiphy->iftype_ext_capab) {
+               u8 supported_on_all, j;
+               const struct wiphy_iftype_ext_capab *capab;
+
+               capab = wiphy->iftype_ext_capab;
+               for (j = 0; j < wiphy->extended_capabilities_len; j++) {
+                       if (capab[0].extended_capabilities_len > j)
+                               supported_on_all =
+                                       capab[0].extended_capabilities[j];
+                       else
+                               supported_on_all = 0x00;
+                       for (i = 1; i < wiphy->num_iftype_ext_capab; i++) {
+                               if (j >= capab[i].extended_capabilities_len) {
+                                       supported_on_all = 0x00;
+                                       break;
+                               }
+                               supported_on_all &=
+                                       capab[i].extended_capabilities[j];
+                       }
+                       if (WARN_ON(wiphy->extended_capabilities[j] &
+                                   ~supported_on_all))
+                               break;
+               }
+       }
+
        rdev->wiphy.registered = true;
        rtnl_unlock();
 
@@ -791,7 +831,7 @@ void wiphy_unregister(struct wiphy *wiphy)
        nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
        rdev->wiphy.registered = false;
 
-       WARN_ON(!list_empty(&rdev->wdev_list));
+       WARN_ON(!list_empty(&rdev->wiphy.wdev_list));
 
        /*
         * First remove the hardware from everywhere, this makes
@@ -914,7 +954,6 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
                sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
                if (sched_scan_req && dev == sched_scan_req->dev)
                        __cfg80211_stop_sched_scan(rdev, false);
-
 #ifdef CONFIG_CFG80211_WEXT
                kfree(wdev->wext.ie);
                wdev->wext.ie = NULL;
@@ -923,6 +962,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
 #endif
                cfg80211_disconnect(rdev, dev,
                                    WLAN_REASON_DEAUTH_LEAVING, true);
+               cfg80211_mlme_down(rdev, dev);
                break;
        case NL80211_IFTYPE_MESH_POINT:
                __cfg80211_leave_mesh(rdev, dev);
@@ -949,6 +989,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
                /* invalid */
                break;
        }
+       wdev->beacon_interval = 0;
 }
 
 void cfg80211_leave(struct cfg80211_registered_device *rdev,
@@ -1013,7 +1054,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
                spin_lock_init(&wdev->mgmt_registrations_lock);
 
                wdev->identifier = ++rdev->wdev_id;
-               list_add_rcu(&wdev->list, &rdev->wdev_list);
+               list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
                rdev->devlist_generation++;
                /* can only change netns with wiphy */
                dev->features |= NETIF_F_NETNS_LOCAL;
@@ -1040,6 +1081,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
                     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
                     wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
                        dev->priv_flags |= IFF_DONT_BRIDGE;
+               INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
                break;
        case NETDEV_GOING_DOWN:
                cfg80211_leave(rdev, wdev);
@@ -1125,6 +1167,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
 #ifdef CONFIG_CFG80211_WEXT
                        kzfree(wdev->wext.keys);
 #endif
+                       flush_work(&wdev->disconnect_wk);
                }
                /*
                 * synchronise (so that we won't find this netdev