summaryrefslogtreecommitdiffstats
path: root/package/madwifi/patches/448-beacon_handling_fixes.patch
blob: 7fe1251ea880a5e4e712bda1891f918128960650 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
--- a/ath/if_ath.c
+++ b/ath/if_ath.c
@@ -512,7 +512,7 @@ MODULE_PARM_DESC(ieee80211_debug, "Load-
  * and use the higher bits as the index of the VAP.
  */
 #define ATH_SET_VAP_BSSID_MASK(bssid_mask)				\
-	((bssid_mask)[0] &= ~(((ath_maxvaps-1) << 2) | 0x02))
+	((bssid_mask)[0] &= ~(((ATH_MAXVAPS_MAX-1) << 2) | 0x02))
 #define ATH_GET_VAP_ID(bssid)                   ((bssid)[0] >> 2)
 #define ATH_SET_VAP_BSSID(bssid, id)					\
 		do {							\
@@ -604,8 +604,8 @@ ath_attach(u_int16_t devid, struct net_d
 
 	/* Allocate space for dynamically determined maximum VAP count */
 	sc->sc_bslot = 
-		kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
-	memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap*));
+		kmalloc(ATH_MAXVAPS_MAX * sizeof(struct ieee80211vap*), GFP_KERNEL);
+	memset(sc->sc_bslot, 0, ATH_MAXVAPS_MAX * sizeof(struct ieee80211vap*));
 
 	/*
 	 * Cache line size is used to size and align various
@@ -1349,11 +1349,8 @@ ath_vap_create(struct ieee80211com *ic, 
 		return NULL;
 	}
 
-	if (sc->sc_nvaps >= ath_maxvaps) {
-		EPRINTF(sc, "Too many virtual APs (%d already exist).\n", 
-				sc->sc_nvaps);
-		return NULL;
-	}
+	if ((sc->sc_nvaps >= ath_maxvaps) && (ath_maxvaps < ATH_MAXVAPS_MAX))
+		ath_maxvaps++;
 
 	dev = alloc_etherdev(sizeof(struct ath_vap) + sc->sc_rc->arc_vap_space);
 	if (dev == NULL) {
@@ -1451,11 +1448,11 @@ ath_vap_create(struct ieee80211com *ic, 
 		/* Assign the VAP to a beacon xmit slot.  As
 		 * above, this cannot fail to find one. */
 		avp->av_bslot = 0;
-		for (slot = 0; slot < ath_maxvaps; slot++)
+		for (slot = 0; slot < ATH_MAXVAPS_MAX; slot++)
 			if (sc->sc_bslot[slot] == NULL) {
 				/* XXX: Hack, space out slots to better
 				 * deal with misses. */
-				if (slot + 1 < ath_maxvaps &&
+				if (slot + 1 < ATH_MAXVAPS_DEFAULT &&
 				    sc->sc_bslot[slot+1] == NULL) {
 					avp->av_bslot = slot + 1;
 					break;
@@ -1463,11 +1460,16 @@ ath_vap_create(struct ieee80211com *ic, 
 				avp->av_bslot = slot;
 				/* NB: keep looking for a double slot */
 			}
-		KASSERT(sc->sc_bslot[avp->av_bslot] == NULL,
-			("beacon slot %u not empty?", avp->av_bslot));
+
+		/* No beacon slot found? */
+		if (sc->sc_bslot[avp->av_bslot]) {
+			free_netdev(dev);
+			return NULL;
+		}
 		sc->sc_bslot[avp->av_bslot] = vap;
 		sc->sc_nbcnvaps++;
 
+#if 0
 		if ((opmode == IEEE80211_M_HOSTAP) && (sc->sc_hastsfadd)) {
 			/*
 			 * Multiple VAPs are to transmit beacons and we
@@ -1485,6 +1487,9 @@ ath_vap_create(struct ieee80211com *ic, 
 				sc->sc_stagbeacons = 1;
 			}
 		}
+#else
+		sc->sc_stagbeacons = sc->sc_hastsfadd;
+#endif
 		DPRINTF(sc, ATH_DEBUG_BEACON, "sc->sc_stagbeacons %sabled\n", 
 				(sc->sc_stagbeacons ? "en" : "dis"));
 	}
@@ -4968,7 +4973,7 @@ ath_beacon_alloc_internal(struct ath_sof
 		 * has a timestamp in one beacon interval while the
 		 * others get a timestamp aligned to the next interval.
 		 */
-		tuadjust = (ni->ni_intval * (ath_maxvaps - avp->av_bslot)) / ath_maxvaps;
+		tuadjust = (ni->ni_intval * (ATH_MAXVAPS_DEFAULT - avp->av_bslot)) / ATH_MAXVAPS_DEFAULT;
 		tsfadjust = cpu_to_le64(tuadjust << 10);	/* TU->TSF */
 
 		DPRINTF(sc, ATH_DEBUG_BEACON,
@@ -5358,21 +5363,40 @@ ath_beacon_send(struct ath_softc *sc, in
 	 */
 	if (sc->sc_stagbeacons) {		/* staggered beacons */
 		struct ieee80211com *ic = &sc->sc_ic;
+		u_int32_t *bflink = NULL;
 		u_int32_t tsftu;
 
 		tsftu = hw_tsf >> 10; /* NB: 64 -> 32: See note far above. */
-		slot = ((tsftu % ic->ic_lintval) * ath_maxvaps) / ic->ic_lintval;
-		vap = sc->sc_bslot[(slot + 1) % ath_maxvaps];
+		slot = ((tsftu % ic->ic_lintval) * ATH_MAXVAPS_DEFAULT) / ic->ic_lintval;
 		DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
 			"Slot %d [tsf %llu tsftu %llu intval %u] vap %p\n",
 			slot, (unsigned long long)hw_tsf, 
 			(unsigned long long)tsftu, ic->ic_lintval, vap);
 		bfaddr = 0;
-		if (vap != NULL) {
+		while (slot < ATH_MAXVAPS_MAX) {
+			vap = sc->sc_bslot[slot];
+			if (vap == NULL)
+				goto next;
+
 			bf = ath_beacon_generate(sc, vap, needmark);
-			if (bf != NULL)
+			if (bf == NULL)
+				break;
+
+			if (bflink != NULL)
+#ifdef AH_NEED_DESC_SWAP
+				*bflink = cpu_to_le32(bf->bf_daddr);
+#else
+				*bflink = bf->bf_daddr;
+#endif
+			else
 				bfaddr = bf->bf_daddr;
+
+			bflink = &bf->bf_desc->ds_link;
+next:
+			slot += ATH_MAXVAPS_DEFAULT;
 		}
+		if (bflink != NULL)
+			*bflink = 0;		/* link of last frame */
 	} else {				/* burst'd beacons */
 		u_int32_t *bflink = NULL;
 
@@ -5567,7 +5591,7 @@ ath_beacon_config(struct ath_softc *sc, 
 		/* NB: the beacon interval is kept internally in TUs */
 		intval = ic->ic_lintval & HAL_BEACON_PERIOD;
 		if (sc->sc_stagbeacons)
-			intval /= ath_maxvaps;	/* for staggered beacons */
+			intval /= ATH_MAXVAPS_DEFAULT;	/* for staggered beacons */
 		if ((sc->sc_nostabeacons) &&
 		    (vap->iv_opmode == IEEE80211_M_HOSTAP))
 			reset_tsf = 1;
@@ -5889,7 +5913,7 @@ ath_desc_alloc(struct ath_softc *sc)
 
 	/* XXX allocate beacon state together with VAP */
 	error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
-			"beacon", ath_maxvaps, 1);
+			"beacon", ATH_MAXVAPS_MAX, 1);
 	if (error != 0) {
 		ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
 			BUS_DMA_TODEVICE);