]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/wireless/util.c
Merge tag 'at91-ab-4.13-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/abellon...
[mirror_ubuntu-bionic-kernel.git] / net / wireless / util.c
index 68e5f2ecee1aa22f17ab9a55eb566124e585740b..4992f1025c9d3749bddd5f22948d2dad791aa9a9 100644 (file)
@@ -454,6 +454,8 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
        if (iftype == NL80211_IFTYPE_MESH_POINT)
                skb_copy_bits(skb, hdrlen, &mesh_flags, 1);
 
+       mesh_flags &= MESH_FLAGS_AE;
+
        switch (hdr->frame_control &
                cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
        case cpu_to_le16(IEEE80211_FCTL_TODS):
@@ -469,9 +471,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
                             iftype != NL80211_IFTYPE_STATION))
                        return -1;
                if (iftype == NL80211_IFTYPE_MESH_POINT) {
-                       if (mesh_flags & MESH_FLAGS_AE_A4)
+                       if (mesh_flags == MESH_FLAGS_AE_A4)
                                return -1;
-                       if (mesh_flags & MESH_FLAGS_AE_A5_A6) {
+                       if (mesh_flags == MESH_FLAGS_AE_A5_A6) {
                                skb_copy_bits(skb, hdrlen +
                                        offsetof(struct ieee80211s_hdr, eaddr1),
                                        tmp.h_dest, 2 * ETH_ALEN);
@@ -487,9 +489,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
                     ether_addr_equal(tmp.h_source, addr)))
                        return -1;
                if (iftype == NL80211_IFTYPE_MESH_POINT) {
-                       if (mesh_flags & MESH_FLAGS_AE_A5_A6)
+                       if (mesh_flags == MESH_FLAGS_AE_A5_A6)
                                return -1;
-                       if (mesh_flags & MESH_FLAGS_AE_A4)
+                       if (mesh_flags == MESH_FLAGS_AE_A4)
                                skb_copy_bits(skb, hdrlen +
                                        offsetof(struct ieee80211s_hdr, eaddr1),
                                        tmp.h_source, ETH_ALEN);
@@ -659,7 +661,7 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame,
                            int offset, int len)
 {
        struct skb_shared_info *sh = skb_shinfo(skb);
-       const skb_frag_t *frag = &sh->frags[-1];
+       const skb_frag_t *frag = &sh->frags[0];
        struct page *frag_page;
        void *frag_ptr;
        int frag_len, frag_size;
@@ -672,10 +674,10 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame,
 
        while (offset >= frag_size) {
                offset -= frag_size;
-               frag++;
                frag_page = skb_frag_page(frag);
                frag_ptr = skb_frag_address(frag);
                frag_size = skb_frag_size(frag);
+               frag++;
        }
 
        frag_ptr += offset;
@@ -687,12 +689,12 @@ __ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame,
        len -= cur_len;
 
        while (len > 0) {
-               frag++;
                frag_len = skb_frag_size(frag);
                cur_len = min(len, frag_len);
                __frame_add_frag(frame, skb_frag_page(frag),
                                 skb_frag_address(frag), cur_len, frag_len);
                len -= cur_len;
+               frag++;
        }
 }
 
@@ -914,11 +916,11 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
                        netdev_err(dev, "failed to set key %d\n", i);
                        continue;
                }
-               if (wdev->connect_keys->def == i)
-                       if (rdev_set_default_key(rdev, dev, i, true, true)) {
-                               netdev_err(dev, "failed to set defkey %d\n", i);
-                               continue;
-                       }
+               if (wdev->connect_keys->def == i &&
+                   rdev_set_default_key(rdev, dev, i, true, true)) {
+                       netdev_err(dev, "failed to set defkey %d\n", i);
+                       continue;
+               }
        }
 
        kzfree(wdev->connect_keys);
@@ -929,7 +931,6 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
 {
        struct cfg80211_event *ev;
        unsigned long flags;
-       const u8 *bssid = NULL;
 
        spin_lock_irqsave(&wdev->event_lock, flags);
        while (!list_empty(&wdev->event_list)) {
@@ -941,20 +942,13 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
                wdev_lock(wdev);
                switch (ev->type) {
                case EVENT_CONNECT_RESULT:
-                       if (!is_zero_ether_addr(ev->cr.bssid))
-                               bssid = ev->cr.bssid;
                        __cfg80211_connect_result(
-                               wdev->netdev, bssid,
-                               ev->cr.req_ie, ev->cr.req_ie_len,
-                               ev->cr.resp_ie, ev->cr.resp_ie_len,
-                               ev->cr.status,
-                               ev->cr.status == WLAN_STATUS_SUCCESS,
-                               ev->cr.bss, ev->cr.timeout_reason);
+                               wdev->netdev,
+                               &ev->cr,
+                               ev->cr.status == WLAN_STATUS_SUCCESS);
                        break;
                case EVENT_ROAMED:
-                       __cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,
-                                         ev->rm.req_ie_len, ev->rm.resp_ie,
-                                         ev->rm.resp_ie_len);
+                       __cfg80211_roamed(wdev, &ev->rm);
                        break;
                case EVENT_DISCONNECTED:
                        __cfg80211_disconnected(wdev->netdev,
@@ -991,7 +985,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
 
 int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
                          struct net_device *dev, enum nl80211_iftype ntype,
-                         u32 *flags, struct vif_params *params)
+                         struct vif_params *params)
 {
        int err;
        enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
@@ -1049,7 +1043,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
                cfg80211_process_rdev_events(rdev);
        }
 
-       err = rdev_change_virtual_intf(rdev, dev, ntype, flags, params);
+       err = rdev_change_virtual_intf(rdev, dev, ntype, params);
 
        WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
 
@@ -1097,6 +1091,35 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
        return err;
 }
 
+static u32 cfg80211_calculate_bitrate_ht(struct rate_info *rate)
+{
+       int modulation, streams, bitrate;
+
+       /* the formula below does only work for MCS values smaller than 32 */
+       if (WARN_ON_ONCE(rate->mcs >= 32))
+               return 0;
+
+       modulation = rate->mcs & 7;
+       streams = (rate->mcs >> 3) + 1;
+
+       bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000;
+
+       if (modulation < 4)
+               bitrate *= (modulation + 1);
+       else if (modulation == 4)
+               bitrate *= (modulation + 2);
+       else
+               bitrate *= (modulation + 3);
+
+       bitrate *= streams;
+
+       if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
+               bitrate = (bitrate / 9) * 10;
+
+       /* do NOT round down here */
+       return (bitrate + 50000) / 100000;
+}
+
 static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
 {
        static const u32 __mcs2bitrate[] = {
@@ -1230,39 +1253,14 @@ static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
 
 u32 cfg80211_calculate_bitrate(struct rate_info *rate)
 {
-       int modulation, streams, bitrate;
-
-       if (!(rate->flags & RATE_INFO_FLAGS_MCS) &&
-           !(rate->flags & RATE_INFO_FLAGS_VHT_MCS))
-               return rate->legacy;
+       if (rate->flags & RATE_INFO_FLAGS_MCS)
+               return cfg80211_calculate_bitrate_ht(rate);
        if (rate->flags & RATE_INFO_FLAGS_60G)
                return cfg80211_calculate_bitrate_60g(rate);
        if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
                return cfg80211_calculate_bitrate_vht(rate);
 
-       /* the formula below does only work for MCS values smaller than 32 */
-       if (WARN_ON_ONCE(rate->mcs >= 32))
-               return 0;
-
-       modulation = rate->mcs & 7;
-       streams = (rate->mcs >> 3) + 1;
-
-       bitrate = (rate->bw == RATE_INFO_BW_40) ? 13500000 : 6500000;
-
-       if (modulation < 4)
-               bitrate *= (modulation + 1);
-       else if (modulation == 4)
-               bitrate *= (modulation + 2);
-       else
-               bitrate *= (modulation + 3);
-
-       bitrate *= streams;
-
-       if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
-               bitrate = (bitrate / 9) * 10;
-
-       /* do NOT round down here */
-       return (bitrate + 50000) / 100000;
+       return rate->legacy;
 }
 EXPORT_SYMBOL(cfg80211_calculate_bitrate);