madwifi: fix beacon slot handling and add support for more than 4 vaps (useful for...
[openwrt/svn-archive/archive.git] / package / madwifi / patches / 448-beacon_handling_fixes.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -512,7 +512,7 @@ MODULE_PARM_DESC(ieee80211_debug, "Load-
4 * and use the higher bits as the index of the VAP.
5 */
6 #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
7 - ((bssid_mask)[0] &= ~(((ath_maxvaps-1) << 2) | 0x02))
8 + ((bssid_mask)[0] &= ~(((ATH_MAXVAPS_MAX-1) << 2) | 0x02))
9 #define ATH_GET_VAP_ID(bssid) ((bssid)[0] >> 2)
10 #define ATH_SET_VAP_BSSID(bssid, id) \
11 do { \
12 @@ -604,8 +604,8 @@ ath_attach(u_int16_t devid, struct net_d
13
14 /* Allocate space for dynamically determined maximum VAP count */
15 sc->sc_bslot =
16 - kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
17 - memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap*));
18 + kmalloc(ATH_MAXVAPS_MAX * sizeof(struct ieee80211vap*), GFP_KERNEL);
19 + memset(sc->sc_bslot, 0, ATH_MAXVAPS_MAX * sizeof(struct ieee80211vap*));
20
21 /*
22 * Cache line size is used to size and align various
23 @@ -1349,11 +1349,8 @@ ath_vap_create(struct ieee80211com *ic,
24 return NULL;
25 }
26
27 - if (sc->sc_nvaps >= ath_maxvaps) {
28 - EPRINTF(sc, "Too many virtual APs (%d already exist).\n",
29 - sc->sc_nvaps);
30 - return NULL;
31 - }
32 + if ((sc->sc_nvaps >= ath_maxvaps) && (ath_maxvaps < ATH_MAXVAPS_MAX))
33 + ath_maxvaps++;
34
35 dev = alloc_etherdev(sizeof(struct ath_vap) + sc->sc_rc->arc_vap_space);
36 if (dev == NULL) {
37 @@ -1451,11 +1448,11 @@ ath_vap_create(struct ieee80211com *ic,
38 /* Assign the VAP to a beacon xmit slot. As
39 * above, this cannot fail to find one. */
40 avp->av_bslot = 0;
41 - for (slot = 0; slot < ath_maxvaps; slot++)
42 + for (slot = 0; slot < ATH_MAXVAPS_MAX; slot++)
43 if (sc->sc_bslot[slot] == NULL) {
44 /* XXX: Hack, space out slots to better
45 * deal with misses. */
46 - if (slot + 1 < ath_maxvaps &&
47 + if (slot + 1 < ATH_MAXVAPS_DEFAULT &&
48 sc->sc_bslot[slot+1] == NULL) {
49 avp->av_bslot = slot + 1;
50 break;
51 @@ -1463,11 +1460,16 @@ ath_vap_create(struct ieee80211com *ic,
52 avp->av_bslot = slot;
53 /* NB: keep looking for a double slot */
54 }
55 - KASSERT(sc->sc_bslot[avp->av_bslot] == NULL,
56 - ("beacon slot %u not empty?", avp->av_bslot));
57 +
58 + /* No beacon slot found? */
59 + if (sc->sc_bslot[avp->av_bslot]) {
60 + free_netdev(dev);
61 + return NULL;
62 + }
63 sc->sc_bslot[avp->av_bslot] = vap;
64 sc->sc_nbcnvaps++;
65
66 +#if 0
67 if ((opmode == IEEE80211_M_HOSTAP) && (sc->sc_hastsfadd)) {
68 /*
69 * Multiple VAPs are to transmit beacons and we
70 @@ -1485,6 +1487,9 @@ ath_vap_create(struct ieee80211com *ic,
71 sc->sc_stagbeacons = 1;
72 }
73 }
74 +#else
75 + sc->sc_stagbeacons = sc->sc_hastsfadd;
76 +#endif
77 DPRINTF(sc, ATH_DEBUG_BEACON, "sc->sc_stagbeacons %sabled\n",
78 (sc->sc_stagbeacons ? "en" : "dis"));
79 }
80 @@ -4968,7 +4973,7 @@ ath_beacon_alloc_internal(struct ath_sof
81 * has a timestamp in one beacon interval while the
82 * others get a timestamp aligned to the next interval.
83 */
84 - tuadjust = (ni->ni_intval * (ath_maxvaps - avp->av_bslot)) / ath_maxvaps;
85 + tuadjust = (ni->ni_intval * (ATH_MAXVAPS_DEFAULT - avp->av_bslot)) / ATH_MAXVAPS_DEFAULT;
86 tsfadjust = cpu_to_le64(tuadjust << 10); /* TU->TSF */
87
88 DPRINTF(sc, ATH_DEBUG_BEACON,
89 @@ -5358,21 +5363,40 @@ ath_beacon_send(struct ath_softc *sc, in
90 */
91 if (sc->sc_stagbeacons) { /* staggered beacons */
92 struct ieee80211com *ic = &sc->sc_ic;
93 + u_int32_t *bflink = NULL;
94 u_int32_t tsftu;
95
96 tsftu = hw_tsf >> 10; /* NB: 64 -> 32: See note far above. */
97 - slot = ((tsftu % ic->ic_lintval) * ath_maxvaps) / ic->ic_lintval;
98 - vap = sc->sc_bslot[(slot + 1) % ath_maxvaps];
99 + slot = ((tsftu % ic->ic_lintval) * ATH_MAXVAPS_DEFAULT) / ic->ic_lintval;
100 DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
101 "Slot %d [tsf %llu tsftu %llu intval %u] vap %p\n",
102 slot, (unsigned long long)hw_tsf,
103 (unsigned long long)tsftu, ic->ic_lintval, vap);
104 bfaddr = 0;
105 - if (vap != NULL) {
106 + while (slot < ATH_MAXVAPS_MAX) {
107 + vap = sc->sc_bslot[slot];
108 + if (vap == NULL)
109 + goto next;
110 +
111 bf = ath_beacon_generate(sc, vap, needmark);
112 - if (bf != NULL)
113 + if (bf == NULL)
114 + break;
115 +
116 + if (bflink != NULL)
117 +#ifdef AH_NEED_DESC_SWAP
118 + *bflink = cpu_to_le32(bf->bf_daddr);
119 +#else
120 + *bflink = bf->bf_daddr;
121 +#endif
122 + else
123 bfaddr = bf->bf_daddr;
124 +
125 + bflink = &bf->bf_desc->ds_link;
126 +next:
127 + slot += ATH_MAXVAPS_DEFAULT;
128 }
129 + if (bflink != NULL)
130 + *bflink = 0; /* link of last frame */
131 } else { /* burst'd beacons */
132 u_int32_t *bflink = NULL;
133
134 @@ -5567,7 +5591,7 @@ ath_beacon_config(struct ath_softc *sc,
135 /* NB: the beacon interval is kept internally in TUs */
136 intval = ic->ic_lintval & HAL_BEACON_PERIOD;
137 if (sc->sc_stagbeacons)
138 - intval /= ath_maxvaps; /* for staggered beacons */
139 + intval /= ATH_MAXVAPS_DEFAULT; /* for staggered beacons */
140 if ((sc->sc_nostabeacons) &&
141 (vap->iv_opmode == IEEE80211_M_HOSTAP))
142 reset_tsf = 1;
143 @@ -5889,7 +5913,7 @@ ath_desc_alloc(struct ath_softc *sc)
144
145 /* XXX allocate beacon state together with VAP */
146 error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
147 - "beacon", ath_maxvaps, 1);
148 + "beacon", ATH_MAXVAPS_MAX, 1);
149 if (error != 0) {
150 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf,
151 BUS_DMA_TODEVICE);