ath5k: channel change fix
[openwrt/staging/yousong.git] / package / kernel / mac80211 / patches / 307-ath9k-fix-regression-in-bssidmask-calculation.patch
1 From: Ben Greear <greearb@candelatech.com>
2 Date: Tue, 4 Nov 2014 15:22:50 -0800
3 Subject: [PATCH] ath9k: fix regression in bssidmask calculation
4
5 The commit that went into 3.17:
6
7 ath9k: Summarize hw state per channel context
8
9 Group and set hw state (opmode, primary_sta, beacon conf) per
10 channel context instead of whole list of vifs. This would allow
11 each channel context to run in different mode (STA/AP).
12
13 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
14 Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
15 Signed-off-by: John W. Linville <linville@tuxdriver.com>
16
17 broke multi-vif configuration due to not properly calculating
18 the bssid mask.
19
20 The test case that caught this was:
21
22 create wlan0 and sta0-4 (6 total), not sure how much that matters.
23 associate all 6 (works fine)
24 disconnect 5 of them, leaving sta0 up
25 Start trying to bring up the other 5 one at a time. It will
26 fail, with iw events looking like this (in these logs, several
27 sta are trying to come up, but symptom is the same with just one)
28
29 The patch causing the regression made quite a few changes, but
30 the part I think caused this particular problem was not
31 recalculating the bssid mask when adding and removing interfaces.
32
33 Re-adding those calls fixes my test case. Fix bad comment
34 as well.
35
36 Signed-off-by: Ben Greear <greearb@candelatech.com>
37 ---
38
39 --- a/drivers/net/wireless/ath/ath9k/main.c
40 +++ b/drivers/net/wireless/ath/ath9k/main.c
41 @@ -994,9 +994,8 @@ void ath9k_calculate_iter_data(struct at
42 struct ath_vif *avp;
43
44 /*
45 - * Pick the MAC address of the first interface as the new hardware
46 - * MAC address. The hardware will use it together with the BSSID mask
47 - * when matching addresses.
48 + * The hardware will use primary station addr together with the
49 + * BSSID mask when matching addresses.
50 */
51 memset(iter_data, 0, sizeof(*iter_data));
52 memset(&iter_data->mask, 0xff, ETH_ALEN);
53 @@ -1225,6 +1224,8 @@ static int ath9k_add_interface(struct ie
54 list_add_tail(&avp->list, &avp->chanctx->vifs);
55 }
56
57 + ath9k_calculate_summary_state(sc, avp->chanctx);
58 +
59 ath9k_assign_hw_queues(hw, vif);
60
61 an->sc = sc;
62 @@ -1294,6 +1295,8 @@ static void ath9k_remove_interface(struc
63
64 ath_tx_node_cleanup(sc, &avp->mcast_node);
65
66 + ath9k_calculate_summary_state(sc, avp->chanctx);
67 +
68 mutex_unlock(&sc->mutex);
69 }
70