update to latest madwifi snapshot - fixes some noderef bugs
[15.05/openwrt.git] / package / madwifi / patches / 121-ibss_hostap.patch
1 Index: madwifi-ng-r2978-20071127/ath/if_ath.c
2 ===================================================================
3 --- madwifi-ng-r2978-20071127.orig/ath/if_ath.c 2007-11-27 21:18:24.910671912 +0100
4 +++ madwifi-ng-r2978-20071127/ath/if_ath.c      2007-11-27 21:21:37.137626301 +0100
5 @@ -515,7 +515,6 @@
6   */
7  #define ATH_SET_VAP_BSSID_MASK(bssid_mask)                             \
8         ((bssid_mask)[0] &= ~(((ATH_BCBUF-1) << 2) | 0x02))
9 -#define ATH_GET_VAP_ID(bssid)                   ((bssid)[0] >> 2)
10  #define ATH_SET_VAP_BSSID(bssid, id)                                   \
11                 do {                                                    \
12                         if (id)                                         \
13 @@ -1203,7 +1202,11 @@
14         case IEEE80211_M_IBSS:
15                 if ((sc->sc_nvaps != 0) && (ic->ic_opmode == IEEE80211_M_STA))
16                         return NULL;
17 -               ic_opmode = opmode;
18 +               else if (sc->sc_nvaps == 0)
19 +                       ic_opmode = opmode;
20 +               else
21 +                       ic_opmode = IEEE80211_M_HOSTAP;
22 +               sc->sc_nibssvaps++;
23                 break;
24         case IEEE80211_M_AHDEMO:
25         case IEEE80211_M_MONITOR:
26 @@ -1233,7 +1236,7 @@
27                 return NULL;
28         }
29  
30 -       if (sc->sc_nvaps >= ATH_BCBUF) {
31 +       if (sc->sc_nvaps + sc->sc_nibssvaps >= ATH_BCBUF) {
32                 printk(KERN_WARNING "too many virtual APs (already got %d)\n", 
33                                 sc->sc_nvaps);
34                 return NULL;
35 @@ -1288,6 +1291,7 @@
36                 /* Use RadioTAP interface type for monitor mode. */
37                 dev->type = ARPHRD_IEEE80211_RADIOTAP;
38  
39 +       avp->av_bslot = -1;
40         if ((flags & IEEE80211_CLONE_BSSID) && sc->sc_hasbmask) {
41                 struct ieee80211vap *v;
42                 unsigned int id_mask, id;
43 @@ -1301,18 +1305,22 @@
44  
45                 /* do a full search to mark all the allocated VAPs */
46                 id_mask = 0;
47 -               TAILQ_FOREACH(v, &ic->ic_vaps, iv_next)
48 -                       id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr));
49 +               TAILQ_FOREACH(v, &ic->ic_vaps, iv_next) {
50 +                       struct ath_vap *a = (struct ath_vap *) v->iv_dev->priv;
51 +                       if (a->av_bslot >= 0)
52 +                               id_mask |= (1 << a->av_bslot);
53 +               }
54  
55 -               for (id = 1; id < ATH_BCBUF; id++) {
56 +               /* IBSS mode has local always set, so don't hand out beacon slot 0 to an IBSS vap */
57 +               for (id = (opmode == IEEE80211_M_IBSS ? 1 : 0); id < ATH_BCBUF; id++) {
58                         /* get the first available slot */
59                         if ((id_mask & (1 << id)) == 0) {
60                                 ATH_SET_VAP_BSSID(vap->iv_myaddr, id);
61 +                               avp->av_bslot = id;
62                                 break;
63                         }
64                 }
65         }
66 -       avp->av_bslot = -1;
67         STAILQ_INIT(&avp->av_mcastq.axq_q);
68         ATH_TXQ_LOCK_INIT(&avp->av_mcastq);
69         if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_IBSS) {
70 @@ -1322,33 +1330,14 @@
71                  */
72                 avp->av_bcbuf = STAILQ_FIRST(&sc->sc_bbuf);
73                 STAILQ_REMOVE_HEAD(&sc->sc_bbuf, bf_list);
74 -               if (opmode == IEEE80211_M_HOSTAP || !sc->sc_hasveol) {
75 +               if ((opmode == IEEE80211_M_IBSS) || (opmode == IEEE80211_M_HOSTAP) || !sc->sc_hasveol) {
76                         unsigned int slot;
77 -                       /*
78 -                        * Assign the VAP to a beacon xmit slot.  As
79 -                        * above, this cannot fail to find one.
80 -                        */
81 -                       avp->av_bslot = 0;
82 -                       for (slot = 0; slot < ATH_BCBUF; slot++)
83 -                               if (sc->sc_bslot[slot] == NULL) {
84 -                                       /*
85 -                                        * XXX hack, space out slots to better
86 -                                        * deal with misses
87 -                                        */
88 -                                       if (slot + 1 < ATH_BCBUF &&
89 -                                           sc->sc_bslot[slot+1] == NULL) {
90 -                                               avp->av_bslot = slot + 1;
91 -                                               break;
92 -                                       }
93 -                                       avp->av_bslot = slot;
94 -                                       /* NB: keep looking for a double slot */
95 -                               }
96                         KASSERT(sc->sc_bslot[avp->av_bslot] == NULL,
97                                 ("beacon slot %u not empty?", avp->av_bslot));
98                         sc->sc_bslot[avp->av_bslot] = vap;
99                         sc->sc_nbcnvaps++;
100                 }
101 -               if ((opmode == IEEE80211_M_HOSTAP) && (sc->sc_hastsfadd)) {
102 +               if ((sc->sc_opmode == IEEE80211_M_HOSTAP) && (sc->sc_hastsfadd)) {
103                         /*
104                          * Multiple VAPs are to transmit beacons and we
105                          * have h/w support for TSF adjusting; enable use
106 @@ -1460,7 +1449,9 @@
107                         sc->sc_stagbeacons = 0;
108         }
109  
110 -       if (vap->iv_opmode == IEEE80211_M_STA) {
111 +       if (vap->iv_opmode == IEEE80211_M_IBSS) {
112 +               sc->sc_nibssvaps--;
113 +       } else if (vap->iv_opmode == IEEE80211_M_STA) {
114                 sc->sc_nstavaps--;
115                 sc->sc_nostabeacons = 0;
116         } else if (vap->iv_opmode == IEEE80211_M_MONITOR)
117 @@ -3816,7 +3807,7 @@
118             sc->sc_opmode == HAL_M_IBSS ||      /* NB: AHDEMO too */
119             (sc->sc_nostabeacons) || sc->sc_scanning)
120                 rfilt |= HAL_RX_FILTER_BEACON;
121 -       if (sc->sc_nmonvaps > 0)
122 +       if ((sc->sc_nmonvaps > 0) || ((sc->sc_nvaps > 0) && (sc->sc_nibssvaps > 0)))
123                 rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
124                           HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
125         return rfilt;
126 @@ -6284,12 +6275,20 @@
127                         type = ieee80211_input(ni, skb, rs->rs_rssi, bf->bf_tsf);
128                         ieee80211_unref_node(&ni);
129                 } else {
130 +                       const struct ieee80211_frame_min *wh = (const struct ieee80211_frame_min *) skb->data;
131                         /*
132                          * No key index or no entry, do a lookup and
133                          * add the node to the mapping table if possible.
134                          */
135 -                       ni = ieee80211_find_rxnode(ic,
136 -                               (const struct ieee80211_frame_min *) skb->data);
137 +                       if (((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PROBE_REQ) &&
138 +                                       (sc->sc_nibssvaps > 0))
139 +                               /* if this is a probe request, send it to all vaps
140 +                                * when looking up nodes, hostap will be preferred over ibss,
141 +                                * because ibss will catch all nodes */
142 +                               ni = NULL;
143 +                       else
144 +                               ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
145 +
146                         if (ni != NULL) {
147                                 struct ath_node *an = ATH_NODE(ni);
148                                 ieee80211_keyix_t keyix;
149 Index: madwifi-ng-r2978-20071127/ath/if_athvar.h
150 ===================================================================
151 --- madwifi-ng-r2978-20071127.orig/ath/if_athvar.h      2007-11-27 21:18:08.257722921 +0100
152 +++ madwifi-ng-r2978-20071127/ath/if_athvar.h   2007-11-27 21:18:30.026963473 +0100
153 @@ -209,7 +209,7 @@
154  #define        ATH_RXBUF       40              /* number of RX buffers */
155  #define        ATH_TXBUF       200             /* number of TX buffers */
156  
157 -#define        ATH_BCBUF       4               /* number of beacon buffers */
158 +#define        ATH_BCBUF       8               /* number of beacon buffers */
159  
160  /* free buffer threshold to restart net dev */
161  #define        ATH_TXBUF_FREE_THRESHOLD  (ATH_TXBUF / 20)
162 @@ -667,6 +667,7 @@
163         u_int16_t sc_nvaps;                     /* # of active virtual APs */
164         u_int8_t sc_nstavaps;                   /* # of active station VAPs */
165         u_int8_t sc_nmonvaps;                   /* # of monitor VAPs */
166 +       u_int8_t sc_nibssvaps;                  /* # of active ibss vaps */
167         u_int8_t sc_nbcnvaps;                   /* # of vaps sending beacons */
168         u_int sc_fftxqmin;                      /* aggregation threshold */
169         HAL_INT sc_imask;                       /* interrupt mask copy */
170 Index: madwifi-ng-r2978-20071127/net80211/ieee80211_beacon.c
171 ===================================================================
172 --- madwifi-ng-r2978-20071127.orig/net80211/ieee80211_beacon.c  2007-11-27 21:18:08.265723374 +0100
173 +++ madwifi-ng-r2978-20071127/net80211/ieee80211_beacon.c       2007-11-27 21:18:30.034963929 +0100
174 @@ -111,7 +111,7 @@
175         bo->bo_tim = frm;
176  
177         /* IBSS/TIM */
178 -       if (vap->iv_opmode == IEEE80211_M_IBSS) {
179 +       if (ic->ic_opmode == IEEE80211_M_IBSS) {
180                 *frm++ = IEEE80211_ELEMID_IBSSPARMS;
181                 *frm++ = 2;
182                 *frm++ = 0; *frm++ = 0;         /* TODO: ATIM window */
183 Index: madwifi-ng-r2978-20071127/net80211/ieee80211_input.c
184 ===================================================================
185 --- madwifi-ng-r2978-20071127.orig/net80211/ieee80211_input.c   2007-11-27 21:18:08.269723596 +0100
186 +++ madwifi-ng-r2978-20071127/net80211/ieee80211_input.c        2007-11-27 21:18:30.038964155 +0100
187 @@ -3069,7 +3069,13 @@
188                         return;
189                 }
190                 if (ni == vap->iv_bss) {
191 -                       if (vap->iv_opmode == IEEE80211_M_IBSS) {
192 +                       /* this probe request may have been sent to all vaps
193 +                        * to give each a chance of creating a node for this.
194 +                        * important for hostap+ibss mode */
195 +                       ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
196 +                       if (ni) {
197 +                               allocbs = 0;
198 +                       } else if (vap->iv_opmode == IEEE80211_M_IBSS) {
199                                 /*
200                                  * XXX Cannot tell if the sender is operating
201                                  * in ibss mode.  But we need a new node to
202 @@ -3078,12 +3084,13 @@
203                                  */
204                                 ni = ieee80211_fakeup_adhoc_node(vap,
205                                         wh->i_addr2);
206 +                               allocbs = 1;
207                         } else {
208                                 ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
209 +                               allocbs = 1;
210                         }
211                         if (ni == NULL)
212                                 return;
213 -                       allocbs = 1;
214                 }
215  
216                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
217 Index: madwifi-ng-r2978-20071127/net80211/ieee80211_node.c
218 ===================================================================
219 --- madwifi-ng-r2978-20071127.orig/net80211/ieee80211_node.c    2007-11-27 21:18:08.281724279 +0100
220 +++ madwifi-ng-r2978-20071127/net80211/ieee80211_node.c 2007-11-27 21:24:30.083481925 +0100
221 @@ -1326,13 +1326,26 @@
222         IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
223  
224         hash = IEEE80211_NODE_HASH(macaddr);
225 +
226 +       /* look for non-ibss nodes first */
227         LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
228 -               if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
229 +               if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && ni->ni_vap->iv_opmode != IEEE80211_M_IBSS) {
230  #ifdef IEEE80211_DEBUG_REFCNT
231                         ieee80211_ref_node_debug(ni, func, line);
232  #else
233                         ieee80211_ref_node(ni);
234 -#endif 
235 +#endif
236 +                       return ni;
237 +               }
238 +       }
239 +
240 +       LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
241 +               if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && ni->ni_vap->iv_opmode == IEEE80211_M_IBSS) {
242 +#ifdef IEEE80211_DEBUG_REFCNT
243 +                       ieee80211_ref_node_debug(ni, func, line);
244 +#else
245 +                       ieee80211_ref_node(ni);
246 +#endif
247                         return ni;
248                 }
249         }
250 @@ -1345,7 +1358,7 @@
251                         return ieee80211_ref_node_debug(wds->wds_ni, func, line);
252  #else
253                         return ieee80211_ref_node(wds->wds_ni);
254 -#endif 
255 +#endif
256                 }
257         }
258         return NULL;