7fe1251ea880a5e4e712bda1891f918128960650
[openwrt.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);