mac80211: merge a bunch of pending fixes
authorFelix Fietkau <nbd@openwrt.org>
Thu, 28 Jan 2016 22:42:10 +0000 (22:42 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 28 Jan 2016 22:42:10 +0000 (22:42 +0000)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 48536

package/kernel/mac80211/patches/312-mac80211-fix-txq-queue-related-crashes.patch [new file with mode: 0644]
package/kernel/mac80211/patches/313-mac80211-fix-unnecessary-frame-drops-in-mesh-fwding.patch [new file with mode: 0644]
package/kernel/mac80211/patches/314-mac80211-Requeue-work-after-scan-complete-for-all-VI.patch [new file with mode: 0644]
package/kernel/mac80211/patches/315-mac80211-fix-ibss-scan-parameters.patch [new file with mode: 0644]
package/kernel/mac80211/patches/316-net-mac80211-agg-rx.c-fix-use-of-uninitialised-value.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/312-mac80211-fix-txq-queue-related-crashes.patch b/package/kernel/mac80211/patches/312-mac80211-fix-txq-queue-related-crashes.patch
new file mode 100644 (file)
index 0000000..61cafc7
--- /dev/null
@@ -0,0 +1,27 @@
+From: Michal Kazior <michal.kazior@tieto.com>
+Date: Thu, 21 Jan 2016 14:23:07 +0100
+Subject: [PATCH] mac80211: fix txq queue related crashes
+
+The driver can access the queue simultanously
+while mac80211 tears down the interface. Without
+spinlock protection this could lead to corrupting
+sk_buff_head and subsequently to an invalid
+pointer dereference.
+
+Fixes: ba8c3d6f16a1 ("mac80211: add an intermediate software queue implementation")
+Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
+---
+
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -977,7 +977,10 @@ static void ieee80211_do_stop(struct iee
+       if (sdata->vif.txq) {
+               struct txq_info *txqi = to_txq_info(sdata->vif.txq);
++              spin_lock_bh(&txqi->queue.lock);
+               ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
++              spin_unlock_bh(&txqi->queue.lock);
++
+               atomic_set(&sdata->txqs_len[txqi->txq.ac], 0);
+       }
diff --git a/package/kernel/mac80211/patches/313-mac80211-fix-unnecessary-frame-drops-in-mesh-fwding.patch b/package/kernel/mac80211/patches/313-mac80211-fix-unnecessary-frame-drops-in-mesh-fwding.patch
new file mode 100644 (file)
index 0000000..844d43b
--- /dev/null
@@ -0,0 +1,57 @@
+From: Michal Kazior <michal.kazior@tieto.com>
+Date: Mon, 25 Jan 2016 14:43:24 +0100
+Subject: [PATCH] mac80211: fix unnecessary frame drops in mesh fwding
+
+The ieee80211_queue_stopped() expects hw queue
+number but it was given raw WMM AC number instead.
+
+This could cause frame drops and problems with
+traffic in some cases - most notably if driver
+doesn't map AC numbers to queue numbers 1:1 and
+uses ieee80211_stop_queues() and
+ieee80211_wake_queue() only without ever calling
+ieee80211_wake_queues().
+
+On ath10k it was possible to hit this problem in
+the following case:
+
+  1. wlan0 uses queue 0
+     (ath10k maps queues per vif)
+  2. offchannel uses queue 15
+  3. queues 1-14 are unused
+  4. ieee80211_stop_queues()
+  5. ieee80211_wake_queue(q=0)
+  6. ieee80211_wake_queue(q=15)
+     (other queues are not woken up because both
+      driver and mac80211 know other queues are
+      unused)
+  7. ieee80211_rx_h_mesh_fwding()
+  8. ieee80211_select_queue_80211() returns 2
+  9. ieee80211_queue_stopped(q=2) returns true
+ 10. frame is dropped (oops!)
+
+Fixes: d3c1597b8d1b ("mac80211: fix forwarded mesh frame queue mapping")
+Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
+---
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2235,7 +2235,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
+       struct ieee80211_local *local = rx->local;
+       struct ieee80211_sub_if_data *sdata = rx->sdata;
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+-      u16 q, hdrlen;
++      u16 ac, q, hdrlen;
+       hdr = (struct ieee80211_hdr *) skb->data;
+       hdrlen = ieee80211_hdrlen(hdr->frame_control);
+@@ -2304,7 +2304,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
+           ether_addr_equal(sdata->vif.addr, hdr->addr3))
+               return RX_CONTINUE;
+-      q = ieee80211_select_queue_80211(sdata, skb, hdr);
++      ac = ieee80211_select_queue_80211(sdata, skb, hdr);
++      q = sdata->vif.hw_queue[ac];
+       if (ieee80211_queue_stopped(&local->hw, q)) {
+               IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
+               return RX_DROP_MONITOR;
diff --git a/package/kernel/mac80211/patches/314-mac80211-Requeue-work-after-scan-complete-for-all-VI.patch b/package/kernel/mac80211/patches/314-mac80211-Requeue-work-after-scan-complete-for-all-VI.patch
new file mode 100644 (file)
index 0000000..5b3efbd
--- /dev/null
@@ -0,0 +1,103 @@
+From: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com>
+Date: Tue, 12 Jan 2016 14:30:19 +0530
+Subject: [PATCH] mac80211: Requeue work after scan complete for all VIF
+ types.
+
+During a sw scan ieee80211_iface_work ignores work items for all vifs.
+However after the scan complete work is requeued only for STA, ADHOC
+and MESH iftypes.
+
+This occasionally results in event processing getting delayed/not
+processed for iftype AP when it coexists with a STA. This can result
+in data halt and eventually disconnection on the AP interface.
+
+Signed-off-by: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com>
+Cc: linux-wireless@vger.kernel.org
+Cc: johannes@sipsolutions.net
+---
+
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -1731,7 +1731,6 @@ void ieee80211_ibss_notify_scan_complete
+               if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
+                       continue;
+               sdata->u.ibss.last_scan_completed = jiffies;
+-              ieee80211_queue_work(&local->hw, &sdata->work);
+       }
+       mutex_unlock(&local->iflist_mtx);
+ }
+--- a/net/mac80211/mesh.c
++++ b/net/mac80211/mesh.c
+@@ -1369,17 +1369,6 @@ out:
+       sdata_unlock(sdata);
+ }
+-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
+-{
+-      struct ieee80211_sub_if_data *sdata;
+-
+-      rcu_read_lock();
+-      list_for_each_entry_rcu(sdata, &local->interfaces, list)
+-              if (ieee80211_vif_is_mesh(&sdata->vif) &&
+-                  ieee80211_sdata_running(sdata))
+-                      ieee80211_queue_work(&local->hw, &sdata->work);
+-      rcu_read_unlock();
+-}
+ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
+ {
+--- a/net/mac80211/mesh.h
++++ b/net/mac80211/mesh.h
+@@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp
+       return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
+ }
+-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
+-
+ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
+ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
+ void ieee80211s_stop(void);
+ #else
+-static inline void
+-ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
+ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+ { return false; }
+ static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -3978,8 +3978,6 @@ static void ieee80211_restart_sta_timer(
+               if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
+                       ieee80211_queue_work(&sdata->local->hw,
+                                            &sdata->u.mgd.monitor_work);
+-              /* and do all the other regular work too */
+-              ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+       }
+ }
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(s
+       bool was_scanning = local->scanning;
+       struct cfg80211_scan_request *scan_req;
+       struct ieee80211_sub_if_data *scan_sdata;
++      struct ieee80211_sub_if_data *sdata;
+       lockdep_assert_held(&local->mtx);
+@@ -373,7 +374,15 @@ static void __ieee80211_scan_completed(s
+       ieee80211_mlme_notify_scan_completed(local);
+       ieee80211_ibss_notify_scan_completed(local);
+-      ieee80211_mesh_notify_scan_completed(local);
++
++      /* Requeue all the work that might have been ignored while
++       * the scan was in progress
++       */
++      list_for_each_entry_rcu(sdata, &local->interfaces, list) {
++              if (ieee80211_sdata_running(sdata))
++                      ieee80211_queue_work(&sdata->local->hw, &sdata->work);
++      }
++
+       if (was_scanning)
+               ieee80211_start_next_roc(local);
+ }
diff --git a/package/kernel/mac80211/patches/315-mac80211-fix-ibss-scan-parameters.patch b/package/kernel/mac80211/patches/315-mac80211-fix-ibss-scan-parameters.patch
new file mode 100644 (file)
index 0000000..52fecb9
--- /dev/null
@@ -0,0 +1,57 @@
+From: Sara Sharon <sara.sharon@intel.com>
+Date: Mon, 25 Jan 2016 15:46:35 +0200
+Subject: [PATCH] mac80211: fix ibss scan parameters
+
+When joining IBSS a full scan should be initiated in order to search
+for existing cell, unless the fixed_channel parameter was set.
+A default channel to create the IBSS on if no cell was found is
+provided as well.
+However - a scan is initiated only on the default channel provided
+regardless of whether ifibss->fixed_channel is set or not, with the
+obvious result of the cell not joining existing IBSS cell that is
+on another channel.
+
+Fixes: 76bed0f43b27 ("mac80211: IBSS fix scan request")
+Signed-off-by: Sara Sharon <sara.sharon@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+---
+
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -7,6 +7,7 @@
+  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
+  * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
+  * Copyright 2013-2014  Intel Mobile Communications GmbH
++ * Copyright(c) 2016 Intel Deutschland GmbH
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+@@ -1483,14 +1484,21 @@ static void ieee80211_sta_find_ibss(stru
+               sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
+-              num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
+-                                                       &ifibss->chandef,
+-                                                       channels,
+-                                                       ARRAY_SIZE(channels));
+               scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
+-              ieee80211_request_ibss_scan(sdata, ifibss->ssid,
+-                                          ifibss->ssid_len, channels, num,
+-                                          scan_width);
++
++              if (ifibss->fixed_channel) {
++                      num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
++                                                               &ifibss->chandef,
++                                                               channels,
++                                                               ARRAY_SIZE(channels));
++                      ieee80211_request_ibss_scan(sdata, ifibss->ssid,
++                                                  ifibss->ssid_len, channels,
++                                                  num, scan_width);
++              } else {
++                      ieee80211_request_ibss_scan(sdata, ifibss->ssid,
++                                                  ifibss->ssid_len, NULL,
++                                                  0, scan_width);
++              }
+       } else {
+               int interval = IEEE80211_SCAN_INTERVAL;
diff --git a/package/kernel/mac80211/patches/316-net-mac80211-agg-rx.c-fix-use-of-uninitialised-value.patch b/package/kernel/mac80211/patches/316-net-mac80211-agg-rx.c-fix-use-of-uninitialised-value.patch
new file mode 100644 (file)
index 0000000..e78df36
--- /dev/null
@@ -0,0 +1,50 @@
+From: Chris Bainbridge <chris.bainbridge@gmail.com>
+Date: Wed, 27 Jan 2016 15:46:18 +0000
+Subject: [PATCH] net/mac80211/agg-rx.c: fix use of uninitialised values
+
+Use kzalloc instead of kmalloc for struct tid_ampdu_rx. Fixes:
+
+[    7.976605] UBSAN: Undefined behaviour in net/mac80211/rx.c:932:29
+[    7.976608] load of value 2 is not a valid value for type '_Bool'
+[    7.976611] CPU: 3 PID: 1134 Comm: kworker/u16:7 Not tainted 4.5.0-rc1+ #265
+[    7.976613] Hardware name: Apple Inc. MacBookPro10,2/Mac-AFD8A9D944EA4843, BIOS MBP102.88Z.0106.B0A.1509130955 09/13/2015
+[    7.976616] Workqueue: phy0 rt2x00usb_work_rxdone
+[    7.976619]  0000000000000004 ffff880254a7ba50 ffffffff8181d866 0000000000000007
+[    7.976622]  ffff880254a7ba78 ffff880254a7ba68 ffffffff8188422d ffffffff8379b500
+[    7.976626]  ffff880254a7bab8 ffffffff81884747 0000000000000202 0000000348620032
+[    7.976629] Call Trace:
+[    7.976633]  [<ffffffff8181d866>] dump_stack+0x45/0x5f
+[    7.976637]  [<ffffffff8188422d>] ubsan_epilogue+0xd/0x40
+[    7.976642]  [<ffffffff81884747>] __ubsan_handle_load_invalid_value+0x67/0x70
+[    7.976646]  [<ffffffff82227b4d>] ieee80211_sta_reorder_release.isra.16+0x5ed/0x730
+[    7.976650]  [<ffffffff8222ca14>] ieee80211_prepare_and_rx_handle+0xd04/0x1c00
+[    7.976654]  [<ffffffff81cb27ce>] ? usb_hcd_map_urb_for_dma+0x65e/0x960
+[    7.976659]  [<ffffffff8222db03>] __ieee80211_rx_handle_packet+0x1f3/0x750
+[    7.976663]  [<ffffffff8222e4a7>] ieee80211_rx_napi+0x447/0x990
+[    7.976667]  [<ffffffff81c5fb85>] rt2x00lib_rxdone+0x305/0xbd0
+[    7.976670]  [<ffffffff811ac23f>] ? dequeue_task_fair+0x64f/0x1de0
+[    7.976674]  [<ffffffff811a1516>] ? sched_clock_cpu+0xe6/0x150
+[    7.976678]  [<ffffffff81c6c45c>] rt2x00usb_work_rxdone+0x7c/0x140
+[    7.976682]  [<ffffffff8117aef6>] process_one_work+0x226/0x860
+[    7.976686]  [<ffffffff8117b58c>] worker_thread+0x5c/0x680
+[    7.976690]  [<ffffffff8117b530>] ? process_one_work+0x860/0x860
+[    7.976693]  [<ffffffff81184f86>] kthread+0xf6/0x150
+[    7.976697]  [<ffffffff81184e90>] ? kthread_worker_fn+0x310/0x310
+[    7.976700]  [<ffffffff822a94df>] ret_from_fork+0x3f/0x70
+[    7.976703]  [<ffffffff81184e90>] ? kthread_worker_fn+0x310/0x310
+
+Link: https://lkml.org/lkml/2016/1/26/230
+Signed-off-by: Chris Bainbridge <chris.bainbridge@gmail.com>
+---
+
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -327,7 +327,7 @@ void __ieee80211_start_rx_ba_session(str
+       }
+       /* prepare A-MPDU MLME for Rx aggregation */
+-      tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
++      tid_agg_rx = kzalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
+       if (!tid_agg_rx)
+               goto end;