summaryrefslogtreecommitdiff
path: root/package/mac80211/patches/560-ath9k_optimize_beacon_tx.patch
blob: cfa1eb7c375524fe05c616c303db9a3b6136c452 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -357,41 +357,12 @@ void ath_beacon_tasklet(unsigned long da
 	struct ieee80211_vif *vif;
 	bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
 	int slot;
-	u32 bfaddr, bc = 0;
-
-	/*
-	 * Check if the previous beacon has gone out.  If
-	 * not don't try to post another, skip this period
-	 * and wait for the next.  Missed beacons indicate
-	 * a problem and should not occur.  If we miss too
-	 * many consecutive beacons reset the device.
-	 */
-	if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
-		sc->beacon.bmisscnt++;
-
-		if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
-			ath_dbg(common, BSTUCK,
-				"missed %u consecutive beacons\n",
-				sc->beacon.bmisscnt);
-			ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
-			if (sc->beacon.bmisscnt > 3)
-				ath9k_hw_bstuck_nfcal(ah);
-		} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
-			ath_dbg(common, BSTUCK, "beacon is officially stuck\n");
-			sc->sc_flags |= SC_OP_TSF_RESET;
-			ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
-		}
-
-		return;
-	}
 
 	/*
 	 * Generate beacon frames. we are sending frames
 	 * staggered so calculate the slot for this frame based
 	 * on the tsf to safeguard against missing an swba.
 	 */
-
-
 	if (ah->opmode == NL80211_IFTYPE_AP) {
 		u16 intval;
 		u32 tsftu;
@@ -412,23 +383,6 @@ void ath_beacon_tasklet(unsigned long da
 		vif = sc->beacon.bslot[slot];
 	}
 
-
-	bfaddr = 0;
-	if (vif) {
-		bf = ath_beacon_generate(sc->hw, vif);
-		if (bf != NULL) {
-			bfaddr = bf->bf_daddr;
-			bc = 1;
-		}
-
-		if (sc->beacon.bmisscnt != 0) {
-			ath_dbg(common, BSTUCK,
-				"resume beacon xmit after %u misses\n",
-				sc->beacon.bmisscnt);
-			sc->beacon.bmisscnt = 0;
-		}
-	}
-
 	/*
 	 * Handle slot time change when a non-ERP station joins/leaves
 	 * an 11g network.  The 802.11 layer notifies us via callback,
@@ -453,15 +407,54 @@ void ath_beacon_tasklet(unsigned long da
 		ath9k_hw_init_global_settings(ah);
 		sc->beacon.updateslot = OK;
 	}
-	if (bfaddr != 0) {
-		/* NB: cabq traffic should already be queued and primed */
-		ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
 
-		if (!edma)
-			ath9k_hw_txstart(ah, sc->beacon.beaconq);
+	if (!vif)
+		return;
+
+	/*
+	 * Check if the previous beacon has gone out.  If
+	 * not don't try to post another, skip this period
+	 * and wait for the next.  Missed beacons indicate
+	 * a problem and should not occur.  If we miss too
+	 * many consecutive beacons reset the device.
+	 */
+	if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
+		sc->beacon.bmisscnt++;
+
+		if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
+			ath_dbg(common, BSTUCK,
+				"missed %u consecutive beacons\n",
+				sc->beacon.bmisscnt);
+			ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
+			if (sc->beacon.bmisscnt > 3)
+				ath9k_hw_bstuck_nfcal(ah);
+		} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
+			ath_dbg(common, BSTUCK, "beacon is officially stuck\n");
+			sc->sc_flags |= SC_OP_TSF_RESET;
+			ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
+		}
+
+		return;
+	}
+
+	bf = ath_beacon_generate(sc->hw, vif);
+	if (!bf)
+		return;
 
-		sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
+	if (sc->beacon.bmisscnt != 0) {
+		ath_dbg(common, BSTUCK,
+			"resume beacon xmit after %u misses\n",
+			sc->beacon.bmisscnt);
+		sc->beacon.bmisscnt = 0;
 	}
+
+	/* NB: cabq traffic should already be queued and primed */
+	ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
+
+	if (!edma)
+		ath9k_hw_txstart(ah, sc->beacon.beaconq);
+
+	sc->beacon.ast_be_xmit++;
 }
 
 static void ath9k_beacon_init(struct ath_softc *sc,