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