d43618b73392fd06e96447d578a8386dc6cf2b4e
[librecmc/librecmc.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 @@ -3368,7 +3367,7 @@
116                 ((ic->ic_opmode == IEEE80211_M_HOSTAP) &&
117                  (ic->ic_protmode != IEEE80211_PROT_NONE)))
118                 rfilt |= HAL_RX_FILTER_BEACON;
119 -       if (sc->sc_nmonvaps > 0)
120 +       if ((sc->sc_nmonvaps > 0) || ((sc->sc_nvaps > 0) && (sc->sc_nibssvaps > 0)))
121                 rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
122                           HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
123         return rfilt;
124 @@ -5809,12 +5801,19 @@
125                         type = ieee80211_input(ni, skb, rs->rs_rssi, rs->rs_tstamp);
126                         ieee80211_unref_node(&ni);
127                 } else {
128 +                       const struct ieee80211_frame_min *wh = (const struct ieee80211_frame_min *) skb->data;
129                         /*
130                          * No key index or no entry, do a lookup and
131                          * add the node to the mapping table if possible.
132                          */
133 -                       ni = ieee80211_find_rxnode(ic,
134 -                               (const struct ieee80211_frame_min *) skb->data);
135 +                       if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PROBE_REQ)
136 +                               /* if this is a probe request, send it to all vaps
137 +                                * when looking up nodes, hostap will be preferred over ibss,
138 +                                * because ibss will catch all nodes */
139 +                               ni = NULL;
140 +                       else
141 +                               ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
142 +
143                         if (ni != NULL) {
144                                 struct ath_node *an = ATH_NODE(ni);
145                                 ieee80211_keyix_t keyix;
146 diff -ur madwifi.old/ath/if_athvar.h madwifi.dev/ath/if_athvar.h
147 --- madwifi.old/ath/if_athvar.h 2007-06-01 12:22:06.642518120 +0200
148 +++ madwifi.dev/ath/if_athvar.h 2007-06-01 12:21:54.640342728 +0200
149 @@ -199,7 +199,7 @@
150  #define        ATH_RXBUF       40              /* number of RX buffers */
151  #define        ATH_TXBUF       200             /* number of TX buffers */
152  
153 -#define        ATH_BCBUF       4               /* number of beacon buffers */
154 +#define        ATH_BCBUF       8               /* number of beacon buffers */
155  
156  /* free buffer threshold to restart net dev */
157  #define        ATH_TXBUF_FREE_THRESHOLD  (ATH_TXBUF / 20)
158 @@ -594,6 +594,7 @@
159         u_int16_t sc_nvaps;                     /* # of active virtual ap's */
160         u_int8_t sc_nstavaps;                   /* # of active station vaps */
161         u_int8_t sc_nmonvaps;                   /* # of monitor vaps */
162 +       u_int8_t sc_nibssvaps;                  /* # of active ibss vaps */
163         u_int8_t sc_nbcnvaps;                   /* # of vaps sending beacons */
164         u_int sc_fftxqmin;                      /* aggregation threshold */
165         HAL_INT sc_imask;                       /* interrupt mask copy */
166 diff -ur madwifi.old/net80211/ieee80211_beacon.c madwifi.dev/net80211/ieee80211_beacon.c
167 --- madwifi.old/net80211/ieee80211_beacon.c     2007-06-01 12:22:06.642518120 +0200
168 +++ madwifi.dev/net80211/ieee80211_beacon.c     2007-06-01 12:21:54.640342728 +0200
169 @@ -111,7 +111,7 @@
170         bo->bo_tim = frm;
171  
172         /* IBSS/TIM */
173 -       if (vap->iv_opmode == IEEE80211_M_IBSS) {
174 +       if (ic->ic_opmode == IEEE80211_M_IBSS) {
175                 *frm++ = IEEE80211_ELEMID_IBSSPARMS;
176                 *frm++ = 2;
177                 *frm++ = 0; *frm++ = 0;         /* TODO: ATIM window */
178 diff -ur madwifi.old/net80211/ieee80211_input.c madwifi.dev/net80211/ieee80211_input.c
179 --- madwifi.old/net80211/ieee80211_input.c      2007-06-01 12:22:06.645517664 +0200
180 +++ madwifi.dev/net80211/ieee80211_input.c      2007-06-01 12:21:54.642342424 +0200
181 @@ -2953,7 +2953,13 @@
182                         return;
183                 }
184                 if (ni == vap->iv_bss) {
185 -                       if (vap->iv_opmode == IEEE80211_M_IBSS) {
186 +                       /* this probe request may have been sent to all vaps
187 +                        * to give each a chance of creating a node for this.
188 +                        * important for hostap+ibss mode */
189 +                       ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
190 +                       if (ni) {
191 +                               allocbs = 0;
192 +                       } else if (vap->iv_opmode == IEEE80211_M_IBSS) {
193                                 /*
194                                  * XXX Cannot tell if the sender is operating
195                                  * in ibss mode.  But we need a new node to
196 @@ -2962,12 +2968,13 @@
197                                  */
198                                 ni = ieee80211_fakeup_adhoc_node(vap,
199                                         wh->i_addr2);
200 +                               allocbs = 1;
201                         } else {
202                                 ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
203 +                               allocbs = 1;
204                         }
205                         if (ni == NULL)
206                                 return;
207 -                       allocbs = 1;
208                 }
209  
210                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
211 diff -ur madwifi.old/net80211/ieee80211_node.c madwifi.dev/net80211/ieee80211_node.c
212 --- madwifi.old/net80211/ieee80211_node.c       2007-06-01 12:22:06.646517512 +0200
213 +++ madwifi.dev/net80211/ieee80211_node.c       2007-06-01 12:21:54.644342120 +0200
214 @@ -1082,8 +1082,25 @@
215         IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
216  
217         hash = IEEE80211_NODE_HASH(macaddr);
218 +       
219 +       /* look for non-ibss nodes first */
220         LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
221 -               if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
222 +               if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && ni->ni_vap->iv_opmode != IEEE80211_M_IBSS) {
223 +                       ieee80211_ref_node(ni); /* mark referenced */
224 +#ifdef IEEE80211_DEBUG_REFCNT
225 +                       IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,
226 +                               "%s (%s:%u) %p<%s> refcnt %d\n", __func__,
227 +                               func, line,
228 +                               ni, ether_sprintf(ni->ni_macaddr),
229 +                               ieee80211_node_refcnt(ni));
230 +#endif
231 +                       return ni;
232 +               }
233 +       }
234 +
235 +       /* now look for ibss nodes */
236 +       LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
237 +               if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr) && ni->ni_vap->iv_opmode == IEEE80211_M_IBSS) {
238                         ieee80211_ref_node(ni); /* mark referenced */
239  #ifdef IEEE80211_DEBUG_REFCNT
240                         IEEE80211_DPRINTF(ni->ni_vap, IEEE80211_MSG_NODE,