mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 23:42:43 +00:00
mac80211: merge a bunch of pending fixes
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 48536
This commit is contained in:
parent
c0edf30bdc
commit
c1e6ef488f
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
@ -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);
|
||||||
|
}
|
@ -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;
|
||||||
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user