]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/wireless/util.c
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
[karo-tx-linux.git] / net / wireless / util.c
index 1b7a08df933c79bf4ffe62455747464468c84bdb..8f2d68fc3a444b3c90a699d29d50bf5e48cbb31f 100644 (file)
@@ -370,7 +370,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
                     iftype != NL80211_IFTYPE_P2P_CLIENT &&
                     iftype != NL80211_IFTYPE_MESH_POINT) ||
                    (is_multicast_ether_addr(dst) &&
-                    !compare_ether_addr(src, addr)))
+                    ether_addr_equal(src, addr)))
                        return -1;
                if (iftype == NL80211_IFTYPE_MESH_POINT) {
                        struct ieee80211s_hdr *meshdr =
@@ -398,9 +398,9 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
        payload = skb->data + hdrlen;
        ethertype = (payload[6] << 8) | payload[7];
 
-       if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
+       if (likely((ether_addr_equal(payload, rfc1042_header) &&
                    ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-                  compare_ether_addr(payload, bridge_tunnel_header) == 0)) {
+                  ether_addr_equal(payload, bridge_tunnel_header))) {
                /* remove RFC1042 or Bridge-Tunnel encapsulation and
                 * replace EtherType */
                skb_pull(skb, hdrlen + 6);
@@ -609,10 +609,9 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
                payload = frame->data;
                ethertype = (payload[6] << 8) | payload[7];
 
-               if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
+               if (likely((ether_addr_equal(payload, rfc1042_header) &&
                            ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-                          compare_ether_addr(payload,
-                                             bridge_tunnel_header) == 0)) {
+                          ether_addr_equal(payload, bridge_tunnel_header))) {
                        /* remove RFC1042 or Bridge-Tunnel
                         * encapsulation and replace EtherType */
                        skb_pull(frame, 6);
@@ -880,7 +879,7 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
                return rate->legacy;
 
        /* the formula below does only work for MCS values smaller than 32 */
-       if (rate->mcs >= 32)
+       if (WARN_ON_ONCE(rate->mcs >= 32))
                return 0;
 
        modulation = rate->mcs & 7;
@@ -936,6 +935,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
                                  enum nl80211_iftype iftype)
 {
        struct wireless_dev *wdev_iter;
+       u32 used_iftypes = BIT(iftype);
        int num[NUM_NL80211_IFTYPES];
        int total = 1;
        int i, j;
@@ -946,13 +946,6 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
        if (rdev->wiphy.software_iftypes & BIT(iftype))
                return 0;
 
-       /*
-        * Drivers will gradually all set this flag, until all
-        * have it we only enforce for those that set it.
-        */
-       if (!(rdev->wiphy.flags & WIPHY_FLAG_ENFORCE_COMBINATIONS))
-               return 0;
-
        memset(num, 0, sizeof(num));
 
        num[iftype] = 1;
@@ -969,12 +962,17 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
 
                num[wdev_iter->iftype]++;
                total++;
+               used_iftypes |= BIT(wdev_iter->iftype);
        }
        mutex_unlock(&rdev->devlist_mtx);
 
+       if (total == 1)
+               return 0;
+
        for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
                const struct ieee80211_iface_combination *c;
                struct ieee80211_iface_limit *limits;
+               u32 all_iftypes = 0;
 
                c = &rdev->wiphy.iface_combinations[i];
 
@@ -989,14 +987,28 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
                        if (rdev->wiphy.software_iftypes & BIT(iftype))
                                continue;
                        for (j = 0; j < c->n_limits; j++) {
-                               if (!(limits[j].types & iftype))
+                               all_iftypes |= limits[j].types;
+                               if (!(limits[j].types & BIT(iftype)))
                                        continue;
                                if (limits[j].max < num[iftype])
                                        goto cont;
                                limits[j].max -= num[iftype];
                        }
                }
-               /* yay, it fits */
+
+               /*
+                * Finally check that all iftypes that we're currently
+                * using are actually part of this combination. If they
+                * aren't then we can't use this combination and have
+                * to continue to the next.
+                */
+               if ((all_iftypes & used_iftypes) != used_iftypes)
+                       goto cont;
+
+               /*
+                * This combination covered all interface types and
+                * supported the requested numbers, so we're good.
+                */
                kfree(limits);
                return 0;
  cont: