wlan - Update wlan from Adrian / FreeBSD
[dragonfly.git] / sys / netproto / 802_11 / wlan / ieee80211_ht.c
1 /*-
2  * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 #ifdef __FreeBSD__
28 __FBSDID("$FreeBSD$");
29 #endif
30
31 /*
32  * IEEE 802.11n protocol support.
33  */
34
35 #include "opt_inet.h"
36 #include "opt_wlan.h"
37
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/systm.h> 
41 #include <sys/endian.h>
42  
43 #include <sys/socket.h>
44
45 #include <net/if.h>
46 #include <net/if_var.h>
47 #include <net/if_media.h>
48 #include <net/ethernet.h>
49
50 #include <netproto/802_11/ieee80211_var.h>
51 #include <netproto/802_11/ieee80211_action.h>
52 #include <netproto/802_11/ieee80211_input.h>
53
54 /* define here, used throughout file */
55 #define MS(_v, _f)      (((_v) & _f) >> _f##_S)
56 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
57
58 const struct ieee80211_mcs_rates ieee80211_htrates[IEEE80211_HTRATE_MAXSIZE] = {
59         {  13,  14,   27,   30 },       /* MCS 0 */
60         {  26,  29,   54,   60 },       /* MCS 1 */
61         {  39,  43,   81,   90 },       /* MCS 2 */
62         {  52,  58,  108,  120 },       /* MCS 3 */
63         {  78,  87,  162,  180 },       /* MCS 4 */
64         { 104, 116,  216,  240 },       /* MCS 5 */
65         { 117, 130,  243,  270 },       /* MCS 6 */
66         { 130, 144,  270,  300 },       /* MCS 7 */
67         {  26,  29,   54,   60 },       /* MCS 8 */
68         {  52,  58,  108,  120 },       /* MCS 9 */
69         {  78,  87,  162,  180 },       /* MCS 10 */
70         { 104, 116,  216,  240 },       /* MCS 11 */
71         { 156, 173,  324,  360 },       /* MCS 12 */
72         { 208, 231,  432,  480 },       /* MCS 13 */
73         { 234, 260,  486,  540 },       /* MCS 14 */
74         { 260, 289,  540,  600 },       /* MCS 15 */
75         {  39,  43,   81,   90 },       /* MCS 16 */
76         {  78,  87,  162,  180 },       /* MCS 17 */
77         { 117, 130,  243,  270 },       /* MCS 18 */
78         { 156, 173,  324,  360 },       /* MCS 19 */
79         { 234, 260,  486,  540 },       /* MCS 20 */
80         { 312, 347,  648,  720 },       /* MCS 21 */
81         { 351, 390,  729,  810 },       /* MCS 22 */
82         { 390, 433,  810,  900 },       /* MCS 23 */
83         {  52,  58,  108,  120 },       /* MCS 24 */
84         { 104, 116,  216,  240 },       /* MCS 25 */
85         { 156, 173,  324,  360 },       /* MCS 26 */
86         { 208, 231,  432,  480 },       /* MCS 27 */
87         { 312, 347,  648,  720 },       /* MCS 28 */
88         { 416, 462,  864,  960 },       /* MCS 29 */
89         { 468, 520,  972, 1080 },       /* MCS 30 */
90         { 520, 578, 1080, 1200 },       /* MCS 31 */
91         {   0,   0,   12,   13 },       /* MCS 32 */
92         {  78,  87,  162,  180 },       /* MCS 33 */
93         { 104, 116,  216,  240 },       /* MCS 34 */
94         { 130, 144,  270,  300 },       /* MCS 35 */
95         { 117, 130,  243,  270 },       /* MCS 36 */
96         { 156, 173,  324,  360 },       /* MCS 37 */
97         { 195, 217,  405,  450 },       /* MCS 38 */
98         { 104, 116,  216,  240 },       /* MCS 39 */
99         { 130, 144,  270,  300 },       /* MCS 40 */
100         { 130, 144,  270,  300 },       /* MCS 41 */
101         { 156, 173,  324,  360 },       /* MCS 42 */
102         { 182, 202,  378,  420 },       /* MCS 43 */
103         { 182, 202,  378,  420 },       /* MCS 44 */
104         { 208, 231,  432,  480 },       /* MCS 45 */
105         { 156, 173,  324,  360 },       /* MCS 46 */
106         { 195, 217,  405,  450 },       /* MCS 47 */
107         { 195, 217,  405,  450 },       /* MCS 48 */
108         { 234, 260,  486,  540 },       /* MCS 49 */
109         { 273, 303,  567,  630 },       /* MCS 50 */
110         { 273, 303,  567,  630 },       /* MCS 51 */
111         { 312, 347,  648,  720 },       /* MCS 52 */
112         { 130, 144,  270,  300 },       /* MCS 53 */
113         { 156, 173,  324,  360 },       /* MCS 54 */
114         { 182, 202,  378,  420 },       /* MCS 55 */
115         { 156, 173,  324,  360 },       /* MCS 56 */
116         { 182, 202,  378,  420 },       /* MCS 57 */
117         { 208, 231,  432,  480 },       /* MCS 58 */
118         { 234, 260,  486,  540 },       /* MCS 59 */
119         { 208, 231,  432,  480 },       /* MCS 60 */
120         { 234, 260,  486,  540 },       /* MCS 61 */
121         { 260, 289,  540,  600 },       /* MCS 62 */
122         { 260, 289,  540,  600 },       /* MCS 63 */
123         { 286, 318,  594,  660 },       /* MCS 64 */
124         { 195, 217,  405,  450 },       /* MCS 65 */
125         { 234, 260,  486,  540 },       /* MCS 66 */
126         { 273, 303,  567,  630 },       /* MCS 67 */
127         { 234, 260,  486,  540 },       /* MCS 68 */
128         { 273, 303,  567,  630 },       /* MCS 69 */
129         { 312, 347,  648,  720 },       /* MCS 70 */
130         { 351, 390,  729,  810 },       /* MCS 71 */
131         { 312, 347,  648,  720 },       /* MCS 72 */
132         { 351, 390,  729,  810 },       /* MCS 73 */
133         { 390, 433,  810,  900 },       /* MCS 74 */
134         { 390, 433,  810,  900 },       /* MCS 75 */
135         { 429, 477,  891,  990 },       /* MCS 76 */
136 };
137
138 #ifdef IEEE80211_AMPDU_AGE
139 static  int ieee80211_ampdu_age = -1;   /* threshold for ampdu reorder q (ms) */
140 SYSCTL_PROC(_net_wlan, OID_AUTO, ampdu_age, CTLTYPE_INT | CTLFLAG_RW,
141         &ieee80211_ampdu_age, 0, ieee80211_sysctl_msecs_ticks, "I",
142         "AMPDU max reorder age (ms)");
143 #endif
144
145 static  int ieee80211_recv_bar_ena = 1;
146 SYSCTL_INT(_net_wlan, OID_AUTO, recv_bar, CTLFLAG_RW, &ieee80211_recv_bar_ena,
147             0, "BAR frame processing (ena/dis)");
148
149 static  int ieee80211_addba_timeout = -1;/* timeout for ADDBA response */
150 SYSCTL_PROC(_net_wlan, OID_AUTO, addba_timeout, CTLTYPE_INT | CTLFLAG_RW,
151         &ieee80211_addba_timeout, 0, ieee80211_sysctl_msecs_ticks, "I",
152         "ADDBA request timeout (ms)");
153 static  int ieee80211_addba_backoff = -1;/* backoff after max ADDBA requests */
154 SYSCTL_PROC(_net_wlan, OID_AUTO, addba_backoff, CTLTYPE_INT | CTLFLAG_RW,
155         &ieee80211_addba_backoff, 0, ieee80211_sysctl_msecs_ticks, "I",
156         "ADDBA request backoff (ms)");
157 static  int ieee80211_addba_maxtries = 3;/* max ADDBA requests before backoff */
158 SYSCTL_INT(_net_wlan, OID_AUTO, addba_maxtries, CTLFLAG_RW,
159         &ieee80211_addba_maxtries, 0, "max ADDBA requests sent before backoff");
160
161 static  int ieee80211_bar_timeout = -1; /* timeout waiting for BAR response */
162 static  int ieee80211_bar_maxtries = 50;/* max BAR requests before DELBA */
163
164 static  ieee80211_recv_action_func ht_recv_action_ba_addba_request;
165 static  ieee80211_recv_action_func ht_recv_action_ba_addba_response;
166 static  ieee80211_recv_action_func ht_recv_action_ba_delba;
167 static  ieee80211_recv_action_func ht_recv_action_ht_mimopwrsave;
168 static  ieee80211_recv_action_func ht_recv_action_ht_txchwidth;
169
170 static  ieee80211_send_action_func ht_send_action_ba_addba;
171 static  ieee80211_send_action_func ht_send_action_ba_delba;
172 static  ieee80211_send_action_func ht_send_action_ht_txchwidth;
173
174 static void
175 ieee80211_ht_init(void)
176 {
177         /*
178          * Setup HT parameters that depends on the clock frequency.
179          */
180 #ifdef IEEE80211_AMPDU_AGE
181         ieee80211_ampdu_age = msecs_to_ticks(500);
182 #endif
183         ieee80211_addba_timeout = msecs_to_ticks(250);
184         ieee80211_addba_backoff = msecs_to_ticks(10*1000);
185         ieee80211_bar_timeout = msecs_to_ticks(250);
186         /*
187          * Register action frame handlers.
188          */
189         ieee80211_recv_action_register(IEEE80211_ACTION_CAT_BA, 
190             IEEE80211_ACTION_BA_ADDBA_REQUEST, ht_recv_action_ba_addba_request);
191         ieee80211_recv_action_register(IEEE80211_ACTION_CAT_BA, 
192             IEEE80211_ACTION_BA_ADDBA_RESPONSE, ht_recv_action_ba_addba_response);
193         ieee80211_recv_action_register(IEEE80211_ACTION_CAT_BA, 
194             IEEE80211_ACTION_BA_DELBA, ht_recv_action_ba_delba);
195         ieee80211_recv_action_register(IEEE80211_ACTION_CAT_HT, 
196             IEEE80211_ACTION_HT_MIMOPWRSAVE, ht_recv_action_ht_mimopwrsave);
197         ieee80211_recv_action_register(IEEE80211_ACTION_CAT_HT, 
198             IEEE80211_ACTION_HT_TXCHWIDTH, ht_recv_action_ht_txchwidth);
199
200         ieee80211_send_action_register(IEEE80211_ACTION_CAT_BA, 
201             IEEE80211_ACTION_BA_ADDBA_REQUEST, ht_send_action_ba_addba);
202         ieee80211_send_action_register(IEEE80211_ACTION_CAT_BA, 
203             IEEE80211_ACTION_BA_ADDBA_RESPONSE, ht_send_action_ba_addba);
204         ieee80211_send_action_register(IEEE80211_ACTION_CAT_BA, 
205             IEEE80211_ACTION_BA_DELBA, ht_send_action_ba_delba);
206         ieee80211_send_action_register(IEEE80211_ACTION_CAT_HT, 
207             IEEE80211_ACTION_HT_TXCHWIDTH, ht_send_action_ht_txchwidth);
208 }
209 SYSINIT(wlan_ht, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_ht_init, NULL);
210
211 static int ieee80211_ampdu_enable(struct ieee80211_node *ni,
212         struct ieee80211_tx_ampdu *tap);
213 static int ieee80211_addba_request(struct ieee80211_node *ni,
214         struct ieee80211_tx_ampdu *tap,
215         int dialogtoken, int baparamset, int batimeout);
216 static int ieee80211_addba_response(struct ieee80211_node *ni,
217         struct ieee80211_tx_ampdu *tap,
218         int code, int baparamset, int batimeout);
219 static void ieee80211_addba_stop(struct ieee80211_node *ni,
220         struct ieee80211_tx_ampdu *tap);
221 static void null_addba_response_timeout(struct ieee80211_node *ni,
222         struct ieee80211_tx_ampdu *tap);
223
224 static void ieee80211_bar_response(struct ieee80211_node *ni,
225         struct ieee80211_tx_ampdu *tap, int status);
226 static void ampdu_tx_stop(struct ieee80211_tx_ampdu *tap);
227 static void bar_stop_timer(struct ieee80211_tx_ampdu *tap);
228 static int ampdu_rx_start(struct ieee80211_node *, struct ieee80211_rx_ampdu *,
229         int baparamset, int batimeout, int baseqctl);
230 static void ampdu_rx_stop(struct ieee80211_node *, struct ieee80211_rx_ampdu *);
231
232 void
233 ieee80211_ht_attach(struct ieee80211com *ic)
234 {
235         /* setup default aggregation policy */
236         ic->ic_recv_action = ieee80211_recv_action;
237         ic->ic_send_action = ieee80211_send_action;
238         ic->ic_ampdu_enable = ieee80211_ampdu_enable;
239         ic->ic_addba_request = ieee80211_addba_request;
240         ic->ic_addba_response = ieee80211_addba_response;
241         ic->ic_addba_response_timeout = null_addba_response_timeout;
242         ic->ic_addba_stop = ieee80211_addba_stop;
243         ic->ic_bar_response = ieee80211_bar_response;
244         ic->ic_ampdu_rx_start = ampdu_rx_start;
245         ic->ic_ampdu_rx_stop = ampdu_rx_stop;
246
247         ic->ic_htprotmode = IEEE80211_PROT_RTSCTS;
248         ic->ic_curhtprotmode = IEEE80211_HTINFO_OPMODE_PURE;
249 }
250
251 void
252 ieee80211_ht_detach(struct ieee80211com *ic)
253 {
254 }
255
256 void
257 ieee80211_ht_vattach(struct ieee80211vap *vap)
258 {
259
260         /* driver can override defaults */
261         vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_8K;
262         vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_NA;
263         vap->iv_ampdu_limit = vap->iv_ampdu_rxmax;
264         vap->iv_amsdu_limit = vap->iv_htcaps & IEEE80211_HTCAP_MAXAMSDU;
265         /* tx aggregation traffic thresholds */
266         vap->iv_ampdu_mintraffic[WME_AC_BK] = 128;
267         vap->iv_ampdu_mintraffic[WME_AC_BE] = 64;
268         vap->iv_ampdu_mintraffic[WME_AC_VO] = 32;
269         vap->iv_ampdu_mintraffic[WME_AC_VI] = 32;
270
271         if (vap->iv_htcaps & IEEE80211_HTC_HT) {
272                 /*
273                  * Device is HT capable; enable all HT-related
274                  * facilities by default.
275                  * XXX these choices may be too aggressive.
276                  */
277                 vap->iv_flags_ht |= IEEE80211_FHT_HT
278                                  |  IEEE80211_FHT_HTCOMPAT
279                                  ;
280                 if (vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI20)
281                         vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI20;
282                 /* XXX infer from channel list? */
283                 if (vap->iv_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
284                         vap->iv_flags_ht |= IEEE80211_FHT_USEHT40;
285                         if (vap->iv_htcaps & IEEE80211_HTCAP_SHORTGI40)
286                                 vap->iv_flags_ht |= IEEE80211_FHT_SHORTGI40;
287                 }
288                 /* enable RIFS if capable */
289                 if (vap->iv_htcaps & IEEE80211_HTC_RIFS)
290                         vap->iv_flags_ht |= IEEE80211_FHT_RIFS;
291
292                 /* NB: A-MPDU and A-MSDU rx are mandated, these are tx only */
293                 vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_RX;
294                 if (vap->iv_htcaps & IEEE80211_HTC_AMPDU)
295                         vap->iv_flags_ht |= IEEE80211_FHT_AMPDU_TX;
296                 vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_RX;
297                 if (vap->iv_htcaps & IEEE80211_HTC_AMSDU)
298                         vap->iv_flags_ht |= IEEE80211_FHT_AMSDU_TX;
299         }
300         /* NB: disable default legacy WDS, too many issues right now */
301         if (vap->iv_flags_ext & IEEE80211_FEXT_WDSLEGACY)
302                 vap->iv_flags_ht &= ~IEEE80211_FHT_HT;
303 }
304
305 void
306 ieee80211_ht_vdetach(struct ieee80211vap *vap)
307 {
308 }
309
310 static int
311 ht_getrate(struct ieee80211com *ic, int index, enum ieee80211_phymode mode,
312     int ratetype)
313 {
314         int mword, rate;
315
316         mword = ieee80211_rate2media(ic, index | IEEE80211_RATE_MCS, mode);
317         if (IFM_SUBTYPE(mword) != IFM_IEEE80211_MCS)
318                 return (0);
319         switch (ratetype) {
320         case 0:
321                 rate = ieee80211_htrates[index].ht20_rate_800ns;
322                 break;
323         case 1:
324                 rate = ieee80211_htrates[index].ht20_rate_400ns;
325                 break;
326         case 2:
327                 rate = ieee80211_htrates[index].ht40_rate_800ns;
328                 break;
329         default:
330                 rate = ieee80211_htrates[index].ht40_rate_400ns;
331                 break;
332         }
333         return (rate);
334 }
335
336 static struct printranges {
337         int     minmcs;
338         int     maxmcs;
339         int     txstream;
340         int     ratetype;
341         int     htcapflags;
342 } ranges[] = {
343         {  0,  7, 1, 0, 0 },
344         {  8, 15, 2, 0, 0 },
345         { 16, 23, 3, 0, 0 },
346         { 24, 31, 4, 0, 0 },
347         { 32,  0, 1, 2, IEEE80211_HTC_TXMCS32 },
348         { 33, 38, 2, 0, IEEE80211_HTC_TXUNEQUAL },
349         { 39, 52, 3, 0, IEEE80211_HTC_TXUNEQUAL },
350         { 53, 76, 4, 0, IEEE80211_HTC_TXUNEQUAL },
351         {  0,  0, 0, 0, 0 },
352 };
353
354 static void
355 ht_rateprint(struct ieee80211com *ic, enum ieee80211_phymode mode, int ratetype)
356 {
357         struct ifnet *ifp = ic->ic_ifp;
358         int minrate, maxrate;
359         struct printranges *range;
360
361         for (range = ranges; range->txstream != 0; range++) {
362                 if (ic->ic_txstream < range->txstream)
363                         continue;
364                 if (range->htcapflags &&
365                     (ic->ic_htcaps & range->htcapflags) == 0)
366                         continue;
367                 if (ratetype < range->ratetype)
368                         continue;
369                 minrate = ht_getrate(ic, range->minmcs, mode, ratetype);
370                 maxrate = ht_getrate(ic, range->maxmcs, mode, ratetype);
371                 if (range->maxmcs) {
372                         if_printf(ifp, "MCS %d-%d: %d%sMbps - %d%sMbps\n",
373                             range->minmcs, range->maxmcs,
374                             minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""),
375                             maxrate/2, ((maxrate & 0x1) != 0 ? ".5" : ""));
376                 } else {
377                         if_printf(ifp, "MCS %d: %d%sMbps\n", range->minmcs,
378                             minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""));
379                 }
380         }
381 }
382
383 static void
384 ht_announce(struct ieee80211com *ic, enum ieee80211_phymode mode)
385 {
386         struct ifnet *ifp = ic->ic_ifp;
387         const char *modestr = ieee80211_phymode_name[mode];
388
389         if_printf(ifp, "%s MCS 20MHz\n", modestr);
390         ht_rateprint(ic, mode, 0);
391         if (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) {
392                 if_printf(ifp, "%s MCS 20MHz SGI\n", modestr);
393                 ht_rateprint(ic, mode, 1);
394         }
395         if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
396                 if_printf(ifp, "%s MCS 40MHz:\n", modestr);
397                 ht_rateprint(ic, mode, 2);
398         }
399         if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
400             (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) {
401                 if_printf(ifp, "%s MCS 40MHz SGI:\n", modestr);
402                 ht_rateprint(ic, mode, 3);
403         }
404 }
405
406 void
407 ieee80211_ht_announce(struct ieee80211com *ic)
408 {
409         struct ifnet *ifp = ic->ic_ifp;
410
411         if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) ||
412             isset(ic->ic_modecaps, IEEE80211_MODE_11NG))
413                 if_printf(ifp, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream);
414         if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA))
415                 ht_announce(ic, IEEE80211_MODE_11NA);
416         if (isset(ic->ic_modecaps, IEEE80211_MODE_11NG))
417                 ht_announce(ic, IEEE80211_MODE_11NG);
418 }
419
420 static struct ieee80211_htrateset htrateset;
421
422 const struct ieee80211_htrateset *
423 ieee80211_get_suphtrates(struct ieee80211com *ic,
424     const struct ieee80211_channel *c)
425 {
426 #define ADDRATE(x)      do {                                            \
427         htrateset.rs_rates[htrateset.rs_nrates] = x;                    \
428         htrateset.rs_nrates++;                                          \
429 } while (0)
430         int i;
431
432         memset(&htrateset, 0, sizeof(struct ieee80211_htrateset));
433         for (i = 0; i < ic->ic_txstream * 8; i++)
434                 ADDRATE(i);
435         if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
436             (ic->ic_htcaps & IEEE80211_HTC_TXMCS32))
437                 ADDRATE(32);
438         if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) {
439                 if (ic->ic_txstream >= 2) {
440                          for (i = 33; i <= 38; i++)
441                                 ADDRATE(i);
442                 }
443                 if (ic->ic_txstream >= 3) {
444                         for (i = 39; i <= 52; i++)
445                                 ADDRATE(i);
446                 }
447                 if (ic->ic_txstream == 4) {
448                         for (i = 53; i <= 76; i++)
449                                 ADDRATE(i);
450                 }
451         }
452         return &htrateset;
453 #undef  ADDRATE
454 }
455
456 /*
457  * Receive processing.
458  */
459
460 /*
461  * Decap the encapsulated A-MSDU frames and dispatch all but
462  * the last for delivery.  The last frame is returned for 
463  * delivery via the normal path.
464  */
465 struct mbuf *
466 ieee80211_decap_amsdu(struct ieee80211_node *ni, struct mbuf *m)
467 {
468         struct ieee80211vap *vap = ni->ni_vap;
469         int framelen;
470         struct mbuf *n;
471
472         /* discard 802.3 header inserted by ieee80211_decap */
473         m_adj(m, sizeof(struct ether_header));
474
475         vap->iv_stats.is_amsdu_decap++;
476
477         for (;;) {
478                 /*
479                  * Decap the first frame, bust it apart from the
480                  * remainder and deliver.  We leave the last frame
481                  * delivery to the caller (for consistency with other
482                  * code paths, could also do it here).
483                  */
484                 m = ieee80211_decap1(m, &framelen);
485                 if (m == NULL) {
486                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
487                             ni->ni_macaddr, "a-msdu", "%s", "decap failed");
488                         vap->iv_stats.is_amsdu_tooshort++;
489                         return NULL;
490                 }
491                 if (m->m_pkthdr.len == framelen)
492                         break;
493                 n = m_split(m, framelen, MB_DONTWAIT);
494                 if (n == NULL) {
495                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
496                             ni->ni_macaddr, "a-msdu",
497                             "%s", "unable to split encapsulated frames");
498                         vap->iv_stats.is_amsdu_split++;
499                         m_freem(m);                     /* NB: must reclaim */
500                         return NULL;
501                 }
502                 vap->iv_deliver_data(vap, ni, m);
503
504                 /*
505                  * Remove frame contents; each intermediate frame
506                  * is required to be aligned to a 4-byte boundary.
507                  */
508                 m = n;
509                 m_adj(m, roundup2(framelen, 4) - framelen);     /* padding */
510         }
511         return m;                               /* last delivered by caller */
512 }
513
514 /*
515  * Purge all frames in the A-MPDU re-order queue.
516  */
517 static void
518 ampdu_rx_purge(struct ieee80211_rx_ampdu *rap)
519 {
520         struct mbuf *m;
521         int i;
522
523         for (i = 0; i < rap->rxa_wnd; i++) {
524                 m = rap->rxa_m[i];
525                 if (m != NULL) {
526                         rap->rxa_m[i] = NULL;
527                         rap->rxa_qbytes -= m->m_pkthdr.len;
528                         m_freem(m);
529                         if (--rap->rxa_qframes == 0)
530                                 break;
531                 }
532         }
533         KASSERT(rap->rxa_qbytes == 0 && rap->rxa_qframes == 0,
534             ("lost %u data, %u frames on ampdu rx q",
535             rap->rxa_qbytes, rap->rxa_qframes));
536 }
537
538 /*
539  * Start A-MPDU rx/re-order processing for the specified TID.
540  */
541 static int
542 ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
543         int baparamset, int batimeout, int baseqctl)
544 {
545         int bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
546
547         if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) {
548                 /*
549                  * AMPDU previously setup and not terminated with a DELBA,
550                  * flush the reorder q's in case anything remains.
551                  */
552                 ampdu_rx_purge(rap);
553         }
554         memset(rap, 0, sizeof(*rap));
555         rap->rxa_wnd = (bufsiz == 0) ?
556             IEEE80211_AGGR_BAWMAX : min(bufsiz, IEEE80211_AGGR_BAWMAX);
557         rap->rxa_start = MS(baseqctl, IEEE80211_BASEQ_START);
558         rap->rxa_flags |=  IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND;
559
560         return 0;
561 }
562
563 /*
564  * Stop A-MPDU rx processing for the specified TID.
565  */
566 static void
567 ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
568 {
569
570         ampdu_rx_purge(rap);
571         rap->rxa_flags &= ~(IEEE80211_AGGR_RUNNING | IEEE80211_AGGR_XCHGPEND);
572 }
573
574 /*
575  * Dispatch a frame from the A-MPDU reorder queue.  The
576  * frame is fed back into ieee80211_input marked with an
577  * M_AMPDU_MPDU flag so it doesn't come back to us (it also
578  * permits ieee80211_input to optimize re-processing).
579  */
580 static __inline void
581 ampdu_dispatch(struct ieee80211_node *ni, struct mbuf *m)
582 {
583         m->m_flags |= M_AMPDU_MPDU;     /* bypass normal processing */
584         /* NB: rssi and noise are ignored w/ M_AMPDU_MPDU set */
585         (void) ieee80211_input(ni, m, 0, 0);
586 }
587
588 /*
589  * Dispatch as many frames as possible from the re-order queue.
590  * Frames will always be "at the front"; we process all frames
591  * up to the first empty slot in the window.  On completion we
592  * cleanup state if there are still pending frames in the current
593  * BA window.  We assume the frame at slot 0 is already handled
594  * by the caller; we always start at slot 1.
595  */
596 static void
597 ampdu_rx_dispatch(struct ieee80211_rx_ampdu *rap, struct ieee80211_node *ni)
598 {
599         struct ieee80211vap *vap = ni->ni_vap;
600         struct mbuf *m;
601         int i;
602
603         /* flush run of frames */
604         for (i = 1; i < rap->rxa_wnd; i++) {
605                 m = rap->rxa_m[i];
606                 if (m == NULL)
607                         break;
608                 rap->rxa_m[i] = NULL;
609                 rap->rxa_qbytes -= m->m_pkthdr.len;
610                 rap->rxa_qframes--;
611
612                 ampdu_dispatch(ni, m);
613         }
614         /*
615          * If frames remain, copy the mbuf pointers down so
616          * they correspond to the offsets in the new window.
617          */
618         if (rap->rxa_qframes != 0) {
619                 int n = rap->rxa_qframes, j;
620                 for (j = i+1; j < rap->rxa_wnd; j++) {
621                         if (rap->rxa_m[j] != NULL) {
622                                 rap->rxa_m[j-i] = rap->rxa_m[j];
623                                 rap->rxa_m[j] = NULL;
624                                 if (--n == 0)
625                                         break;
626                         }
627                 }
628                 KASSERT(n == 0, ("lost %d frames", n));
629                 vap->iv_stats.is_ampdu_rx_copy += rap->rxa_qframes;
630         }
631         /*
632          * Adjust the start of the BA window to
633          * reflect the frames just dispatched.
634          */
635         rap->rxa_start = IEEE80211_SEQ_ADD(rap->rxa_start, i);
636         vap->iv_stats.is_ampdu_rx_oor += i;
637 }
638
639 #ifdef IEEE80211_AMPDU_AGE
640 /*
641  * Dispatch all frames in the A-MPDU re-order queue.
642  */
643 static void
644 ampdu_rx_flush(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
645 {
646         struct ieee80211vap *vap = ni->ni_vap;
647         struct mbuf *m;
648         int i;
649
650         for (i = 0; i < rap->rxa_wnd; i++) {
651                 m = rap->rxa_m[i];
652                 if (m == NULL)
653                         continue;
654                 rap->rxa_m[i] = NULL;
655                 rap->rxa_qbytes -= m->m_pkthdr.len;
656                 rap->rxa_qframes--;
657                 vap->iv_stats.is_ampdu_rx_oor++;
658
659                 ampdu_dispatch(ni, m);
660                 if (rap->rxa_qframes == 0)
661                         break;
662         }
663 }
664 #endif /* IEEE80211_AMPDU_AGE */
665
666 /*
667  * Dispatch all frames in the A-MPDU re-order queue
668  * preceding the specified sequence number.  This logic
669  * handles window moves due to a received MSDU or BAR.
670  */
671 static void
672 ampdu_rx_flush_upto(struct ieee80211_node *ni,
673         struct ieee80211_rx_ampdu *rap, ieee80211_seq winstart)
674 {
675         struct ieee80211vap *vap = ni->ni_vap;
676         struct mbuf *m;
677         ieee80211_seq seqno;
678         int i;
679
680         /*
681          * Flush any complete MSDU's with a sequence number lower
682          * than winstart.  Gaps may exist.  Note that we may actually
683          * dispatch frames past winstart if a run continues; this is
684          * an optimization that avoids having to do a separate pass
685          * to dispatch frames after moving the BA window start.
686          */
687         seqno = rap->rxa_start;
688         for (i = 0; i < rap->rxa_wnd; i++) {
689                 m = rap->rxa_m[i];
690                 if (m != NULL) {
691                         rap->rxa_m[i] = NULL;
692                         rap->rxa_qbytes -= m->m_pkthdr.len;
693                         rap->rxa_qframes--;
694                         vap->iv_stats.is_ampdu_rx_oor++;
695
696                         ampdu_dispatch(ni, m);
697                 } else {
698                         if (!IEEE80211_SEQ_BA_BEFORE(seqno, winstart))
699                                 break;
700                 }
701                 seqno = IEEE80211_SEQ_INC(seqno);
702         }
703         /*
704          * If frames remain, copy the mbuf pointers down so
705          * they correspond to the offsets in the new window.
706          */
707         if (rap->rxa_qframes != 0) {
708                 int n = rap->rxa_qframes, j;
709
710                 /* NB: this loop assumes i > 0 and/or rxa_m[0] is NULL */
711                 KASSERT(rap->rxa_m[0] == NULL,
712                     ("%s: BA window slot 0 occupied", __func__));
713                 for (j = i+1; j < rap->rxa_wnd; j++) {
714                         if (rap->rxa_m[j] != NULL) {
715                                 rap->rxa_m[j-i] = rap->rxa_m[j];
716                                 rap->rxa_m[j] = NULL;
717                                 if (--n == 0)
718                                         break;
719                         }
720                 }
721                 KASSERT(n == 0, ("%s: lost %d frames, qframes %d off %d "
722                     "BA win <%d:%d> winstart %d",
723                     __func__, n, rap->rxa_qframes, i, rap->rxa_start,
724                     IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1),
725                     winstart));
726                 vap->iv_stats.is_ampdu_rx_copy += rap->rxa_qframes;
727         }
728         /*
729          * Move the start of the BA window; we use the
730          * sequence number of the last MSDU that was
731          * passed up the stack+1 or winstart if stopped on
732          * a gap in the reorder buffer.
733          */
734         rap->rxa_start = seqno;
735 }
736
737 /*
738  * Process a received QoS data frame for an HT station.  Handle
739  * A-MPDU reordering: if this frame is received out of order
740  * and falls within the BA window hold onto it.  Otherwise if
741  * this frame completes a run, flush any pending frames.  We
742  * return 1 if the frame is consumed.  A 0 is returned if
743  * the frame should be processed normally by the caller.
744  */
745 int
746 ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m)
747 {
748 #define IEEE80211_FC0_QOSDATA \
749         (IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_VERSION_0)
750 #define PROCESS         0       /* caller should process frame */
751 #define CONSUMED        1       /* frame consumed, caller does nothing */
752         struct ieee80211vap *vap = ni->ni_vap;
753         struct ieee80211_qosframe *wh;
754         struct ieee80211_rx_ampdu *rap;
755         ieee80211_seq rxseq;
756         uint8_t tid;
757         int off;
758
759         KASSERT((m->m_flags & (M_AMPDU | M_AMPDU_MPDU)) == M_AMPDU,
760             ("!a-mpdu or already re-ordered, flags 0x%x", m->m_flags));
761         KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta"));
762
763         /* NB: m_len known to be sufficient */
764         wh = mtod(m, struct ieee80211_qosframe *);
765         if (wh->i_fc[0] != IEEE80211_FC0_QOSDATA) {
766                 /*
767                  * Not QoS data, shouldn't get here but just
768                  * return it to the caller for processing.
769                  */
770                 return PROCESS;
771         }
772         if (IEEE80211_IS_DSTODS(wh))
773                 tid = ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0];
774         else
775                 tid = wh->i_qos[0];
776         tid &= IEEE80211_QOS_TID;
777         rap = &ni->ni_rx_ampdu[tid];
778         if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) {
779                 /*
780                  * No ADDBA request yet, don't touch.
781                  */
782                 return PROCESS;
783         }
784         rxseq = le16toh(*(uint16_t *)wh->i_seq);
785         if ((rxseq & IEEE80211_SEQ_FRAG_MASK) != 0) {
786                 /*
787                  * Fragments are not allowed; toss.
788                  */
789                 IEEE80211_DISCARD_MAC(vap,
790                     IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr,
791                     "A-MPDU", "fragment, rxseq 0x%x tid %u%s", rxseq, tid,
792                     wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : "");
793                 vap->iv_stats.is_ampdu_rx_drop++;
794                 IEEE80211_NODE_STAT(ni, rx_drop);
795                 m_freem(m);
796                 return CONSUMED;
797         }
798         rxseq >>= IEEE80211_SEQ_SEQ_SHIFT;
799         rap->rxa_nframes++;
800 again:
801         if (rxseq == rap->rxa_start) {
802                 /*
803                  * First frame in window.
804                  */
805                 if (rap->rxa_qframes != 0) {
806                         /*
807                          * Dispatch as many packets as we can.
808                          */
809                         KASSERT(rap->rxa_m[0] == NULL, ("unexpected dup"));
810                         ampdu_dispatch(ni, m);
811                         ampdu_rx_dispatch(rap, ni);
812                         return CONSUMED;
813                 } else {
814                         /*
815                          * In order; advance window and notify
816                          * caller to dispatch directly.
817                          */
818                         rap->rxa_start = IEEE80211_SEQ_INC(rxseq);
819                         return PROCESS;
820                 }
821         }
822         /*
823          * Frame is out of order; store if in the BA window.
824          */
825         /* calculate offset in BA window */
826         off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start);
827         if (off < rap->rxa_wnd) {
828                 /*
829                  * Common case (hopefully): in the BA window.
830                  * Sec 9.10.7.6.2 a) (p.137)
831                  */
832 #ifdef IEEE80211_AMPDU_AGE
833                 /* 
834                  * Check for frames sitting too long in the reorder queue.
835                  * This should only ever happen if frames are not delivered
836                  * without the sender otherwise notifying us (e.g. with a
837                  * BAR to move the window).  Typically this happens because
838                  * of vendor bugs that cause the sequence number to jump.
839                  * When this happens we get a gap in the reorder queue that
840                  * leaves frame sitting on the queue until they get pushed
841                  * out due to window moves.  When the vendor does not send
842                  * BAR this move only happens due to explicit packet sends
843                  *
844                  * NB: we only track the time of the oldest frame in the
845                  * reorder q; this means that if we flush we might push
846                  * frames that still "new"; if this happens then subsequent
847                  * frames will result in BA window moves which cost something
848                  * but is still better than a big throughput dip.
849                  */
850                 if (rap->rxa_qframes != 0) {
851                         /* XXX honor batimeout? */
852                         if (ticks - rap->rxa_age > ieee80211_ampdu_age) {
853                                 /*
854                                  * Too long since we received the first
855                                  * frame; flush the reorder buffer.
856                                  */
857                                 if (rap->rxa_qframes != 0) {
858                                         vap->iv_stats.is_ampdu_rx_age +=
859                                             rap->rxa_qframes;
860                                         ampdu_rx_flush(ni, rap);
861                                 }
862                                 rap->rxa_start = IEEE80211_SEQ_INC(rxseq);
863                                 return PROCESS;
864                         }
865                 } else {
866                         /*
867                          * First frame, start aging timer.
868                          */
869                         rap->rxa_age = ticks;
870                 }
871 #endif /* IEEE80211_AMPDU_AGE */
872                 /* save packet */
873                 if (rap->rxa_m[off] == NULL) {
874                         rap->rxa_m[off] = m;
875                         rap->rxa_qframes++;
876                         rap->rxa_qbytes += m->m_pkthdr.len;
877                         vap->iv_stats.is_ampdu_rx_reorder++;
878                 } else {
879                         IEEE80211_DISCARD_MAC(vap,
880                             IEEE80211_MSG_INPUT | IEEE80211_MSG_11N,
881                             ni->ni_macaddr, "a-mpdu duplicate",
882                             "seqno %u tid %u BA win <%u:%u>",
883                             rxseq, tid, rap->rxa_start,
884                             IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1));
885                         vap->iv_stats.is_rx_dup++;
886                         IEEE80211_NODE_STAT(ni, rx_dup);
887                         m_freem(m);
888                 }
889                 return CONSUMED;
890         }
891         if (off < IEEE80211_SEQ_BA_RANGE) {
892                 /*
893                  * Outside the BA window, but within range;
894                  * flush the reorder q and move the window.
895                  * Sec 9.10.7.6.2 b) (p.138)
896                  */
897                 IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
898                     "move BA win <%u:%u> (%u frames) rxseq %u tid %u",
899                     rap->rxa_start,
900                     IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1),
901                     rap->rxa_qframes, rxseq, tid);
902                 vap->iv_stats.is_ampdu_rx_move++;
903
904                 /*
905                  * The spec says to flush frames up to but not including:
906                  *      WinStart_B = rxseq - rap->rxa_wnd + 1
907                  * Then insert the frame or notify the caller to process
908                  * it immediately.  We can safely do this by just starting
909                  * over again because we know the frame will now be within
910                  * the BA window.
911                  */
912                 /* NB: rxa_wnd known to be >0 */
913                 ampdu_rx_flush_upto(ni, rap,
914                     IEEE80211_SEQ_SUB(rxseq, rap->rxa_wnd-1));
915                 goto again;
916         } else {
917                 /*
918                  * Outside the BA window and out of range; toss.
919                  * Sec 9.10.7.6.2 c) (p.138)
920                  */
921                 IEEE80211_DISCARD_MAC(vap,
922                     IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr,
923                     "MPDU", "BA win <%u:%u> (%u frames) rxseq %u tid %u%s",
924                     rap->rxa_start,
925                     IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1),
926                     rap->rxa_qframes, rxseq, tid,
927                     wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : "");
928                 vap->iv_stats.is_ampdu_rx_drop++;
929                 IEEE80211_NODE_STAT(ni, rx_drop);
930                 m_freem(m);
931                 return CONSUMED;
932         }
933 #undef CONSUMED
934 #undef PROCESS
935 #undef IEEE80211_FC0_QOSDATA
936 }
937
938 /*
939  * Process a BAR ctl frame.  Dispatch all frames up to
940  * the sequence number of the frame.  If this frame is
941  * out of range it's discarded.
942  */
943 void
944 ieee80211_recv_bar(struct ieee80211_node *ni, struct mbuf *m0)
945 {
946         struct ieee80211vap *vap = ni->ni_vap;
947         struct ieee80211_frame_bar *wh;
948         struct ieee80211_rx_ampdu *rap;
949         ieee80211_seq rxseq;
950         int tid, off;
951
952         if (!ieee80211_recv_bar_ena) {
953 #if 0
954                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_11N,
955                     ni->ni_macaddr, "BAR", "%s", "processing disabled");
956 #endif
957                 vap->iv_stats.is_ampdu_bar_bad++;
958                 return;
959         }
960         wh = mtod(m0, struct ieee80211_frame_bar *);
961         /* XXX check basic BAR */
962         tid = MS(le16toh(wh->i_ctl), IEEE80211_BAR_TID);
963         rap = &ni->ni_rx_ampdu[tid];
964         if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) {
965                 /*
966                  * No ADDBA request yet, don't touch.
967                  */
968                 IEEE80211_DISCARD_MAC(vap,
969                     IEEE80211_MSG_INPUT | IEEE80211_MSG_11N,
970                     ni->ni_macaddr, "BAR", "no BA stream, tid %u", tid);
971                 vap->iv_stats.is_ampdu_bar_bad++;
972                 return;
973         }
974         vap->iv_stats.is_ampdu_bar_rx++;
975         rxseq = le16toh(wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
976         if (rxseq == rap->rxa_start)
977                 return;
978         /* calculate offset in BA window */
979         off = IEEE80211_SEQ_SUB(rxseq, rap->rxa_start);
980         if (off < IEEE80211_SEQ_BA_RANGE) {
981                 /*
982                  * Flush the reorder q up to rxseq and move the window.
983                  * Sec 9.10.7.6.3 a) (p.138)
984                  */
985                 IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
986                     "BAR moves BA win <%u:%u> (%u frames) rxseq %u tid %u",
987                     rap->rxa_start,
988                     IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1),
989                     rap->rxa_qframes, rxseq, tid);
990                 vap->iv_stats.is_ampdu_bar_move++;
991
992                 ampdu_rx_flush_upto(ni, rap, rxseq);
993                 if (off >= rap->rxa_wnd) {
994                         /*
995                          * BAR specifies a window start to the right of BA
996                          * window; we must move it explicitly since
997                          * ampdu_rx_flush_upto will not.
998                          */
999                         rap->rxa_start = rxseq;
1000                 }
1001         } else {
1002                 /*
1003                  * Out of range; toss.
1004                  * Sec 9.10.7.6.3 b) (p.138)
1005                  */
1006                 IEEE80211_DISCARD_MAC(vap,
1007                     IEEE80211_MSG_INPUT | IEEE80211_MSG_11N, ni->ni_macaddr,
1008                     "BAR", "BA win <%u:%u> (%u frames) rxseq %u tid %u%s",
1009                     rap->rxa_start,
1010                     IEEE80211_SEQ_ADD(rap->rxa_start, rap->rxa_wnd-1),
1011                     rap->rxa_qframes, rxseq, tid,
1012                     wh->i_fc[1] & IEEE80211_FC1_RETRY ? " (retransmit)" : "");
1013                 vap->iv_stats.is_ampdu_bar_oow++;
1014                 IEEE80211_NODE_STAT(ni, rx_drop);
1015         }
1016 }
1017
1018 /*
1019  * Setup HT-specific state in a node.  Called only
1020  * when HT use is negotiated so we don't do extra
1021  * work for temporary and/or legacy sta's.
1022  */
1023 void
1024 ieee80211_ht_node_init(struct ieee80211_node *ni)
1025 {
1026         struct ieee80211_tx_ampdu *tap;
1027         int tid;
1028
1029         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
1030             ni,
1031             "%s: called",
1032             __func__);
1033
1034         if (ni->ni_flags & IEEE80211_NODE_HT) {
1035                 /*
1036                  * Clean AMPDU state on re-associate.  This handles the case
1037                  * where a station leaves w/o notifying us and then returns
1038                  * before node is reaped for inactivity.
1039                  */
1040                 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
1041                     ni,
1042                     "%s: calling cleanup",
1043                     __func__);
1044                 ieee80211_ht_node_cleanup(ni);
1045         }
1046         for (tid = 0; tid < WME_NUM_TID; tid++) {
1047                 tap = &ni->ni_tx_ampdu[tid];
1048                 tap->txa_tid = tid;
1049                 tap->txa_ni = ni;
1050                 /* NB: further initialization deferred */
1051         }
1052         ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
1053 }
1054
1055 /*
1056  * Cleanup HT-specific state in a node.  Called only
1057  * when HT use has been marked.
1058  */
1059 void
1060 ieee80211_ht_node_cleanup(struct ieee80211_node *ni)
1061 {
1062         struct ieee80211com *ic = ni->ni_ic;
1063         int i;
1064
1065         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
1066             ni,
1067             "%s: called",
1068             __func__);
1069
1070         KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT node"));
1071
1072         /* XXX optimize this */
1073         for (i = 0; i < WME_NUM_TID; i++) {
1074                 struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[i];
1075                 if (tap->txa_flags & IEEE80211_AGGR_SETUP)
1076                         ampdu_tx_stop(tap);
1077         }
1078         for (i = 0; i < WME_NUM_TID; i++)
1079                 ic->ic_ampdu_rx_stop(ni, &ni->ni_rx_ampdu[i]);
1080
1081         ni->ni_htcap = 0;
1082         ni->ni_flags &= ~IEEE80211_NODE_HT_ALL;
1083 }
1084
1085 /*
1086  * Age out HT resources for a station.
1087  */
1088 void
1089 ieee80211_ht_node_age(struct ieee80211_node *ni)
1090 {
1091 #ifdef IEEE80211_AMPDU_AGE
1092         struct ieee80211vap *vap = ni->ni_vap;
1093         uint8_t tid;
1094 #endif
1095
1096         KASSERT(ni->ni_flags & IEEE80211_NODE_HT, ("not an HT sta"));
1097
1098 #ifdef IEEE80211_AMPDU_AGE
1099         for (tid = 0; tid < WME_NUM_TID; tid++) {
1100                 struct ieee80211_rx_ampdu *rap;
1101
1102                 rap = &ni->ni_rx_ampdu[tid];
1103                 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0)
1104                         continue;
1105                 if (rap->rxa_qframes == 0)
1106                         continue;
1107                 /* 
1108                  * Check for frames sitting too long in the reorder queue.
1109                  * See above for more details on what's happening here.
1110                  */
1111                 /* XXX honor batimeout? */
1112                 if (ticks - rap->rxa_age > ieee80211_ampdu_age) {
1113                         /*
1114                          * Too long since we received the first
1115                          * frame; flush the reorder buffer.
1116                          */
1117                         vap->iv_stats.is_ampdu_rx_age += rap->rxa_qframes;
1118                         ampdu_rx_flush(ni, rap);
1119                 }
1120         }
1121 #endif /* IEEE80211_AMPDU_AGE */
1122 }
1123
1124 static struct ieee80211_channel *
1125 findhtchan(struct ieee80211com *ic, struct ieee80211_channel *c, int htflags)
1126 {
1127         return ieee80211_find_channel(ic, c->ic_freq,
1128             (c->ic_flags &~ IEEE80211_CHAN_HT) | htflags);
1129 }
1130
1131 /*
1132  * Adjust a channel to be HT/non-HT according to the vap's configuration.
1133  */
1134 struct ieee80211_channel *
1135 ieee80211_ht_adjust_channel(struct ieee80211com *ic,
1136         struct ieee80211_channel *chan, int flags)
1137 {
1138         struct ieee80211_channel *c;
1139
1140         if (flags & IEEE80211_FHT_HT) {
1141                 /* promote to HT if possible */
1142                 if (flags & IEEE80211_FHT_USEHT40) {
1143                         if (!IEEE80211_IS_CHAN_HT40(chan)) {
1144                                 /* NB: arbitrarily pick ht40+ over ht40- */
1145                                 c = findhtchan(ic, chan, IEEE80211_CHAN_HT40U);
1146                                 if (c == NULL)
1147                                         c = findhtchan(ic, chan,
1148                                                 IEEE80211_CHAN_HT40D);
1149                                 if (c == NULL)
1150                                         c = findhtchan(ic, chan,
1151                                                 IEEE80211_CHAN_HT20);
1152                                 if (c != NULL)
1153                                         chan = c;
1154                         }
1155                 } else if (!IEEE80211_IS_CHAN_HT20(chan)) {
1156                         c = findhtchan(ic, chan, IEEE80211_CHAN_HT20);
1157                         if (c != NULL)
1158                                 chan = c;
1159                 }
1160         } else if (IEEE80211_IS_CHAN_HT(chan)) {
1161                 /* demote to legacy, HT use is disabled */
1162                 c = ieee80211_find_channel(ic, chan->ic_freq,
1163                     chan->ic_flags &~ IEEE80211_CHAN_HT);
1164                 if (c != NULL)
1165                         chan = c;
1166         }
1167         return chan;
1168 }
1169
1170 /*
1171  * Setup HT-specific state for a legacy WDS peer.
1172  */
1173 void
1174 ieee80211_ht_wds_init(struct ieee80211_node *ni)
1175 {
1176         struct ieee80211vap *vap = ni->ni_vap;
1177         struct ieee80211_tx_ampdu *tap;
1178         int tid;
1179
1180         KASSERT(vap->iv_flags_ht & IEEE80211_FHT_HT, ("no HT requested"));
1181
1182         /* XXX check scan cache in case peer has an ap and we have info */
1183         /*
1184          * If setup with a legacy channel; locate an HT channel.
1185          * Otherwise if the inherited channel (from a companion
1186          * AP) is suitable use it so we use the same location
1187          * for the extension channel).
1188          */
1189         ni->ni_chan = ieee80211_ht_adjust_channel(ni->ni_ic,
1190             ni->ni_chan, ieee80211_htchanflags(ni->ni_chan));
1191
1192         ni->ni_htcap = 0;
1193         if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20)
1194                 ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI20;
1195         if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
1196                 ni->ni_htcap |= IEEE80211_HTCAP_CHWIDTH40;
1197                 ni->ni_chw = 40;
1198                 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
1199                         ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_ABOVE;
1200                 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
1201                         ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_BELOW;
1202                 if (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40)
1203                         ni->ni_htcap |= IEEE80211_HTCAP_SHORTGI40;
1204         } else {
1205                 ni->ni_chw = 20;
1206                 ni->ni_ht2ndchan = IEEE80211_HTINFO_2NDCHAN_NONE;
1207         }
1208         ni->ni_htctlchan = ni->ni_chan->ic_ieee;
1209         if (vap->iv_flags_ht & IEEE80211_FHT_RIFS)
1210                 ni->ni_flags |= IEEE80211_NODE_RIFS;
1211         /* XXX does it make sense to enable SMPS? */
1212
1213         ni->ni_htopmode = 0;            /* XXX need protection state */
1214         ni->ni_htstbc = 0;              /* XXX need info */
1215
1216         for (tid = 0; tid < WME_NUM_TID; tid++) {
1217                 tap = &ni->ni_tx_ampdu[tid];
1218                 tap->txa_tid = tid;
1219         }
1220         /* NB: AMPDU tx/rx governed by IEEE80211_FHT_AMPDU_{TX,RX} */
1221         ni->ni_flags |= IEEE80211_NODE_HT | IEEE80211_NODE_AMPDU;
1222 }
1223
1224 /*
1225  * Notify hostap vaps of a change in the HTINFO ie.
1226  */
1227 static void
1228 htinfo_notify(struct ieee80211com *ic)
1229 {
1230         struct ieee80211vap *vap;
1231         int first = 1;
1232
1233         IEEE80211_LOCK_ASSERT(ic);
1234
1235         TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
1236                 if (vap->iv_opmode != IEEE80211_M_HOSTAP)
1237                         continue;
1238                 if (vap->iv_state != IEEE80211_S_RUN ||
1239                     !IEEE80211_IS_CHAN_HT(vap->iv_bss->ni_chan))
1240                         continue;
1241                 if (first) {
1242                         IEEE80211_NOTE(vap,
1243                             IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N,
1244                             vap->iv_bss,
1245                             "HT bss occupancy change: %d sta, %d ht, "
1246                             "%d ht40%s, HT protmode now 0x%x"
1247                             , ic->ic_sta_assoc
1248                             , ic->ic_ht_sta_assoc
1249                             , ic->ic_ht40_sta_assoc
1250                             , (ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) ?
1251                                  ", non-HT sta present" : ""
1252                             , ic->ic_curhtprotmode);
1253                         first = 0;
1254                 }
1255                 ieee80211_beacon_notify(vap, IEEE80211_BEACON_HTINFO);
1256         }
1257 }
1258
1259 /*
1260  * Calculate HT protection mode from current
1261  * state and handle updates.
1262  */
1263 static void
1264 htinfo_update(struct ieee80211com *ic)
1265 {
1266         uint8_t protmode;
1267
1268         if (ic->ic_sta_assoc != ic->ic_ht_sta_assoc) {
1269                 protmode = IEEE80211_HTINFO_OPMODE_MIXED
1270                          | IEEE80211_HTINFO_NONHT_PRESENT;
1271         } else if (ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) {
1272                 protmode = IEEE80211_HTINFO_OPMODE_PROTOPT
1273                          | IEEE80211_HTINFO_NONHT_PRESENT;
1274         } else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
1275             IEEE80211_IS_CHAN_HT40(ic->ic_bsschan) && 
1276             ic->ic_sta_assoc != ic->ic_ht40_sta_assoc) {
1277                 protmode = IEEE80211_HTINFO_OPMODE_HT20PR;
1278         } else {
1279                 protmode = IEEE80211_HTINFO_OPMODE_PURE;
1280         }
1281         if (protmode != ic->ic_curhtprotmode) {
1282                 ic->ic_curhtprotmode = protmode;
1283                 htinfo_notify(ic);
1284         }
1285 }
1286
1287 /*
1288  * Handle an HT station joining a BSS.
1289  */
1290 void
1291 ieee80211_ht_node_join(struct ieee80211_node *ni)
1292 {
1293         struct ieee80211com *ic = ni->ni_ic;
1294
1295         IEEE80211_LOCK_ASSERT(ic);
1296
1297         if (ni->ni_flags & IEEE80211_NODE_HT) {
1298                 ic->ic_ht_sta_assoc++;
1299                 if (ni->ni_chw == 40)
1300                         ic->ic_ht40_sta_assoc++;
1301         }
1302         htinfo_update(ic);
1303 }
1304
1305 /*
1306  * Handle an HT station leaving a BSS.
1307  */
1308 void
1309 ieee80211_ht_node_leave(struct ieee80211_node *ni)
1310 {
1311         struct ieee80211com *ic = ni->ni_ic;
1312
1313         IEEE80211_LOCK_ASSERT(ic);
1314
1315         if (ni->ni_flags & IEEE80211_NODE_HT) {
1316                 ic->ic_ht_sta_assoc--;
1317                 if (ni->ni_chw == 40)
1318                         ic->ic_ht40_sta_assoc--;
1319         }
1320         htinfo_update(ic);
1321 }
1322
1323 /*
1324  * Public version of htinfo_update; used for processing
1325  * beacon frames from overlapping bss.
1326  *
1327  * Caller can specify either IEEE80211_HTINFO_OPMODE_MIXED
1328  * (on receipt of a beacon that advertises MIXED) or
1329  * IEEE80211_HTINFO_OPMODE_PROTOPT (on receipt of a beacon
1330  * from an overlapping legacy bss).  We treat MIXED with
1331  * a higher precedence than PROTOPT (i.e. we will not change
1332  * change PROTOPT -> MIXED; only MIXED -> PROTOPT).  This
1333  * corresponds to how we handle things in htinfo_update.
1334  */
1335 void
1336 ieee80211_htprot_update(struct ieee80211com *ic, int protmode)
1337 {
1338 #define OPMODE(x)       SM(x, IEEE80211_HTINFO_OPMODE)
1339         IEEE80211_LOCK(ic);
1340
1341         /* track non-HT station presence */
1342         KASSERT(protmode & IEEE80211_HTINFO_NONHT_PRESENT,
1343             ("protmode 0x%x", protmode));
1344         ic->ic_flags_ht |= IEEE80211_FHT_NONHT_PR;
1345         ic->ic_lastnonht = ticks;
1346
1347         if (protmode != ic->ic_curhtprotmode &&
1348             (OPMODE(ic->ic_curhtprotmode) != IEEE80211_HTINFO_OPMODE_MIXED ||
1349              OPMODE(protmode) == IEEE80211_HTINFO_OPMODE_PROTOPT)) {
1350                 /* push beacon update */
1351                 ic->ic_curhtprotmode = protmode;
1352                 htinfo_notify(ic);
1353         }
1354         IEEE80211_UNLOCK(ic);
1355 #undef OPMODE
1356 }
1357
1358 /*
1359  * Time out presence of an overlapping bss with non-HT
1360  * stations.  When operating in hostap mode we listen for
1361  * beacons from other stations and if we identify a non-HT
1362  * station is present we update the opmode field of the
1363  * HTINFO ie.  To identify when all non-HT stations are
1364  * gone we time out this condition.
1365  */
1366 void
1367 ieee80211_ht_timeout(struct ieee80211com *ic)
1368 {
1369         IEEE80211_LOCK_ASSERT(ic);
1370
1371         if ((ic->ic_flags_ht & IEEE80211_FHT_NONHT_PR) &&
1372             time_after(ticks, ic->ic_lastnonht + IEEE80211_NONHT_PRESENT_AGE)) {
1373 #if 0
1374                 IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
1375                     "%s", "time out non-HT STA present on channel");
1376 #endif
1377                 ic->ic_flags_ht &= ~IEEE80211_FHT_NONHT_PR;
1378                 htinfo_update(ic);
1379         }
1380 }
1381
1382 /* unalligned little endian access */     
1383 #define LE_READ_2(p)                                    \
1384         ((uint16_t)                                     \
1385          ((((const uint8_t *)(p))[0]      ) |           \
1386           (((const uint8_t *)(p))[1] <<  8)))
1387
1388 /*
1389  * Process an 802.11n HT capabilities ie.
1390  */
1391 void
1392 ieee80211_parse_htcap(struct ieee80211_node *ni, const uint8_t *ie)
1393 {
1394         if (ie[0] == IEEE80211_ELEMID_VENDOR) {
1395                 /*
1396                  * Station used Vendor OUI ie to associate;
1397                  * mark the node so when we respond we'll use
1398                  * the Vendor OUI's and not the standard ie's.
1399                  */
1400                 ni->ni_flags |= IEEE80211_NODE_HTCOMPAT;
1401                 ie += 4;
1402         } else
1403                 ni->ni_flags &= ~IEEE80211_NODE_HTCOMPAT;
1404
1405         ni->ni_htcap = LE_READ_2(ie +
1406                 __offsetof(struct ieee80211_ie_htcap, hc_cap));
1407         ni->ni_htparam = ie[__offsetof(struct ieee80211_ie_htcap, hc_param)];
1408 }
1409
1410 static void
1411 htinfo_parse(struct ieee80211_node *ni,
1412         const struct ieee80211_ie_htinfo *htinfo)
1413 {
1414         uint16_t w;
1415
1416         ni->ni_htctlchan = htinfo->hi_ctrlchannel;
1417         ni->ni_ht2ndchan = SM(htinfo->hi_byte1, IEEE80211_HTINFO_2NDCHAN);
1418         w = LE_READ_2(&htinfo->hi_byte2);
1419         ni->ni_htopmode = SM(w, IEEE80211_HTINFO_OPMODE);
1420         w = LE_READ_2(&htinfo->hi_byte45);
1421         ni->ni_htstbc = SM(w, IEEE80211_HTINFO_BASIC_STBCMCS);
1422 }
1423
1424 /*
1425  * Parse an 802.11n HT info ie and save useful information
1426  * to the node state.  Note this does not effect any state
1427  * changes such as for channel width change.
1428  */
1429 void
1430 ieee80211_parse_htinfo(struct ieee80211_node *ni, const uint8_t *ie)
1431 {
1432         if (ie[0] == IEEE80211_ELEMID_VENDOR)
1433                 ie += 4;
1434         htinfo_parse(ni, (const struct ieee80211_ie_htinfo *) ie);
1435 }
1436
1437 /*
1438  * Handle 11n channel switch.  Use the received HT ie's to
1439  * identify the right channel to use.  If we cannot locate it
1440  * in the channel table then fallback to legacy operation.
1441  * Note that we use this information to identify the node's
1442  * channel only; the caller is responsible for insuring any
1443  * required channel change is done (e.g. in sta mode when
1444  * parsing the contents of a beacon frame).
1445  */
1446 static int
1447 htinfo_update_chw(struct ieee80211_node *ni, int htflags)
1448 {
1449         struct ieee80211com *ic = ni->ni_ic;
1450         struct ieee80211_channel *c;
1451         int chanflags;
1452         int ret = 0;
1453
1454         chanflags = (ni->ni_chan->ic_flags &~ IEEE80211_CHAN_HT) | htflags;
1455         if (chanflags != ni->ni_chan->ic_flags) {
1456                 /* XXX not right for ht40- */
1457                 c = ieee80211_find_channel(ic, ni->ni_chan->ic_freq, chanflags);
1458                 if (c == NULL && (htflags & IEEE80211_CHAN_HT40)) {
1459                         /*
1460                          * No HT40 channel entry in our table; fall back
1461                          * to HT20 operation.  This should not happen.
1462                          */
1463                         c = findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT20);
1464 #if 0
1465                         IEEE80211_NOTE(ni->ni_vap,
1466                             IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, ni,
1467                             "no HT40 channel (freq %u), falling back to HT20",
1468                             ni->ni_chan->ic_freq);
1469 #endif
1470                         /* XXX stat */
1471                 }
1472                 if (c != NULL && c != ni->ni_chan) {
1473                         IEEE80211_NOTE(ni->ni_vap,
1474                             IEEE80211_MSG_ASSOC | IEEE80211_MSG_11N, ni,
1475                             "switch station to HT%d channel %u/0x%x",
1476                             IEEE80211_IS_CHAN_HT40(c) ? 40 : 20,
1477                             c->ic_freq, c->ic_flags);
1478                         ni->ni_chan = c;
1479                         ret = 1;
1480                 }
1481                 /* NB: caller responsible for forcing any channel change */
1482         }
1483         /* update node's tx channel width */
1484         ni->ni_chw = IEEE80211_IS_CHAN_HT40(ni->ni_chan)? 40 : 20;
1485         return (ret);
1486 }
1487
1488 /*
1489  * Update 11n MIMO PS state according to received htcap.
1490  */
1491 static __inline int
1492 htcap_update_mimo_ps(struct ieee80211_node *ni)
1493 {
1494         uint16_t oflags = ni->ni_flags;
1495
1496         switch (ni->ni_htcap & IEEE80211_HTCAP_SMPS) {
1497         case IEEE80211_HTCAP_SMPS_DYNAMIC:
1498                 ni->ni_flags |= IEEE80211_NODE_MIMO_PS;
1499                 ni->ni_flags |= IEEE80211_NODE_MIMO_RTS;
1500                 break;
1501         case IEEE80211_HTCAP_SMPS_ENA:
1502                 ni->ni_flags |= IEEE80211_NODE_MIMO_PS;
1503                 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS;
1504                 break;
1505         case IEEE80211_HTCAP_SMPS_OFF:
1506         default:                /* disable on rx of reserved value */
1507                 ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS;
1508                 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS;
1509                 break;
1510         }
1511         return (oflags ^ ni->ni_flags);
1512 }
1513
1514 /*
1515  * Update short GI state according to received htcap
1516  * and local settings.
1517  */
1518 static __inline void
1519 htcap_update_shortgi(struct ieee80211_node *ni)
1520 {
1521         struct ieee80211vap *vap = ni->ni_vap;
1522
1523         ni->ni_flags &= ~(IEEE80211_NODE_SGI20|IEEE80211_NODE_SGI40);
1524         if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) &&
1525             (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20))
1526                 ni->ni_flags |= IEEE80211_NODE_SGI20;
1527         if ((ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) &&
1528             (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40))
1529                 ni->ni_flags |= IEEE80211_NODE_SGI40;
1530 }
1531
1532 /*
1533  * Parse and update HT-related state extracted from
1534  * the HT cap and info ie's.
1535  */
1536 int
1537 ieee80211_ht_updateparams(struct ieee80211_node *ni,
1538         const uint8_t *htcapie, const uint8_t *htinfoie)
1539 {
1540         struct ieee80211vap *vap = ni->ni_vap;
1541         const struct ieee80211_ie_htinfo *htinfo;
1542         int htflags;
1543         int ret = 0;
1544
1545         ieee80211_parse_htcap(ni, htcapie);
1546         if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS)
1547                 htcap_update_mimo_ps(ni);
1548         htcap_update_shortgi(ni);
1549
1550         if (htinfoie[0] == IEEE80211_ELEMID_VENDOR)
1551                 htinfoie += 4;
1552         htinfo = (const struct ieee80211_ie_htinfo *) htinfoie;
1553         htinfo_parse(ni, htinfo);
1554
1555         htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ?
1556             IEEE80211_CHAN_HT20 : 0;
1557         /* NB: honor operating mode constraint */
1558         if ((htinfo->hi_byte1 & IEEE80211_HTINFO_TXWIDTH_2040) &&
1559             (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) {
1560                 if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_ABOVE)
1561                         htflags = IEEE80211_CHAN_HT40U;
1562                 else if (ni->ni_ht2ndchan == IEEE80211_HTINFO_2NDCHAN_BELOW)
1563                         htflags = IEEE80211_CHAN_HT40D;
1564         }
1565         if (htinfo_update_chw(ni, htflags))
1566                 ret = 1;
1567
1568         if ((htinfo->hi_byte1 & IEEE80211_HTINFO_RIFSMODE_PERM) &&
1569             (vap->iv_flags_ht & IEEE80211_FHT_RIFS))
1570                 ni->ni_flags |= IEEE80211_NODE_RIFS;
1571         else
1572                 ni->ni_flags &= ~IEEE80211_NODE_RIFS;
1573
1574         return (ret);
1575 }
1576
1577 /*
1578  * Parse and update HT-related state extracted from the HT cap ie
1579  * for a station joining an HT BSS.
1580  */
1581 void
1582 ieee80211_ht_updatehtcap(struct ieee80211_node *ni, const uint8_t *htcapie)
1583 {
1584         struct ieee80211vap *vap = ni->ni_vap;
1585         int htflags;
1586
1587         ieee80211_parse_htcap(ni, htcapie);
1588         if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS)
1589                 htcap_update_mimo_ps(ni);
1590         htcap_update_shortgi(ni);
1591
1592         /* NB: honor operating mode constraint */
1593         /* XXX 40 MHz intolerant */
1594         htflags = (vap->iv_flags_ht & IEEE80211_FHT_HT) ?
1595             IEEE80211_CHAN_HT20 : 0;
1596         if ((ni->ni_htcap & IEEE80211_HTCAP_CHWIDTH40) &&
1597             (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)) {
1598                 if (IEEE80211_IS_CHAN_HT40U(vap->iv_bss->ni_chan))
1599                         htflags = IEEE80211_CHAN_HT40U;
1600                 else if (IEEE80211_IS_CHAN_HT40D(vap->iv_bss->ni_chan))
1601                         htflags = IEEE80211_CHAN_HT40D;
1602         }
1603         (void) htinfo_update_chw(ni, htflags);
1604 }
1605
1606 /*
1607  * Install received HT rate set by parsing the HT cap ie.
1608  */
1609 int
1610 ieee80211_setup_htrates(struct ieee80211_node *ni, const uint8_t *ie, int flags)
1611 {
1612         struct ieee80211com *ic = ni->ni_ic;
1613         struct ieee80211vap *vap = ni->ni_vap;
1614         const struct ieee80211_ie_htcap *htcap;
1615         struct ieee80211_htrateset *rs;
1616         int i, maxequalmcs, maxunequalmcs;
1617
1618         maxequalmcs = ic->ic_txstream * 8 - 1;
1619         if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL) {
1620                 if (ic->ic_txstream >= 2)
1621                         maxunequalmcs = 38;
1622                 if (ic->ic_txstream >= 3)
1623                         maxunequalmcs = 52;
1624                 if (ic->ic_txstream >= 4)
1625                         maxunequalmcs = 76;
1626         } else
1627                 maxunequalmcs = 0;
1628
1629         rs = &ni->ni_htrates;
1630         memset(rs, 0, sizeof(*rs));
1631         if (ie != NULL) {
1632                 if (ie[0] == IEEE80211_ELEMID_VENDOR)
1633                         ie += 4;
1634                 htcap = (const struct ieee80211_ie_htcap *) ie;
1635                 for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++) {
1636                         if (isclr(htcap->hc_mcsset, i))
1637                                 continue;
1638                         if (rs->rs_nrates == IEEE80211_HTRATE_MAXSIZE) {
1639                                 IEEE80211_NOTE(vap,
1640                                     IEEE80211_MSG_XRATE | IEEE80211_MSG_11N, ni,
1641                                     "WARNING, HT rate set too large; only "
1642                                     "using %u rates", IEEE80211_HTRATE_MAXSIZE);
1643                                 vap->iv_stats.is_rx_rstoobig++;
1644                                 break;
1645                         }
1646                         if (i <= 31 && i > maxequalmcs)
1647                                 continue;
1648                         if (i == 32 &&
1649                             (ic->ic_htcaps & IEEE80211_HTC_TXMCS32) == 0)
1650                                 continue;
1651                         if (i > 32 && i > maxunequalmcs)
1652                                 continue;
1653                         rs->rs_rates[rs->rs_nrates++] = i;
1654                 }
1655         }
1656         return ieee80211_fix_rate(ni, (struct ieee80211_rateset *) rs, flags);
1657 }
1658
1659 /*
1660  * Mark rates in a node's HT rate set as basic according
1661  * to the information in the supplied HT info ie.
1662  */
1663 void
1664 ieee80211_setup_basic_htrates(struct ieee80211_node *ni, const uint8_t *ie)
1665 {
1666         const struct ieee80211_ie_htinfo *htinfo;
1667         struct ieee80211_htrateset *rs;
1668         int i, j;
1669
1670         if (ie[0] == IEEE80211_ELEMID_VENDOR)
1671                 ie += 4;
1672         htinfo = (const struct ieee80211_ie_htinfo *) ie;
1673         rs = &ni->ni_htrates;
1674         if (rs->rs_nrates == 0) {
1675                 IEEE80211_NOTE(ni->ni_vap,
1676                     IEEE80211_MSG_XRATE | IEEE80211_MSG_11N, ni,
1677                     "%s", "WARNING, empty HT rate set");
1678                 return;
1679         }
1680         for (i = 0; i < IEEE80211_HTRATE_MAXSIZE; i++) {
1681                 if (isclr(htinfo->hi_basicmcsset, i))
1682                         continue;
1683                 for (j = 0; j < rs->rs_nrates; j++)
1684                         if ((rs->rs_rates[j] & IEEE80211_RATE_VAL) == i)
1685                                 rs->rs_rates[j] |= IEEE80211_RATE_BASIC;
1686         }
1687 }
1688
1689 static void
1690 ampdu_tx_setup(struct ieee80211_tx_ampdu *tap)
1691 {
1692         callout_init_mp(&tap->txa_timer);
1693         tap->txa_flags |= IEEE80211_AGGR_SETUP;
1694 }
1695
1696 static void
1697 ampdu_tx_stop(struct ieee80211_tx_ampdu *tap)
1698 {
1699         struct ieee80211_node *ni = tap->txa_ni;
1700         struct ieee80211com *ic = ni->ni_ic;
1701
1702         IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N,
1703             tap->txa_ni,
1704             "%s: called",
1705             __func__);
1706
1707         KASSERT(tap->txa_flags & IEEE80211_AGGR_SETUP,
1708             ("txa_flags 0x%x tid %d ac %d", tap->txa_flags, tap->txa_tid,
1709             TID_TO_WME_AC(tap->txa_tid)));
1710
1711         /*
1712          * Stop BA stream if setup so driver has a chance
1713          * to reclaim any resources it might have allocated.
1714          */
1715         ic->ic_addba_stop(ni, tap);
1716         /*
1717          * Stop any pending BAR transmit.
1718          */
1719         bar_stop_timer(tap);
1720
1721         tap->txa_lastsample = 0;
1722         tap->txa_avgpps = 0;
1723         /* NB: clearing NAK means we may re-send ADDBA */ 
1724         tap->txa_flags &= ~(IEEE80211_AGGR_SETUP | IEEE80211_AGGR_NAK);
1725 }
1726
1727 /*
1728  * ADDBA response timeout.
1729  *
1730  * If software aggregation and per-TID queue management was done here,
1731  * that queue would be unpaused after the ADDBA timeout occurs.
1732  */
1733 static void
1734 addba_timeout(void *arg)
1735 {
1736         struct ieee80211_tx_ampdu *tap = arg;
1737         struct ieee80211_node *ni = tap->txa_ni;
1738         struct ieee80211com *ic = ni->ni_ic;
1739
1740         /* XXX ? */
1741         tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND;
1742         tap->txa_attempts++;
1743         ic->ic_addba_response_timeout(ni, tap);
1744 }
1745
1746 static void
1747 addba_start_timeout(struct ieee80211_tx_ampdu *tap)
1748 {
1749         /* XXX use CALLOUT_PENDING instead? */
1750         callout_reset(&tap->txa_timer, ieee80211_addba_timeout,
1751             addba_timeout, tap);
1752         tap->txa_flags |= IEEE80211_AGGR_XCHGPEND;
1753         tap->txa_nextrequest = ticks + ieee80211_addba_timeout;
1754 }
1755
1756 static void
1757 addba_stop_timeout(struct ieee80211_tx_ampdu *tap)
1758 {
1759         /* XXX use CALLOUT_PENDING instead? */
1760         if (tap->txa_flags & IEEE80211_AGGR_XCHGPEND) {
1761                 callout_stop(&tap->txa_timer);
1762                 tap->txa_flags &= ~IEEE80211_AGGR_XCHGPEND;
1763         }
1764 }
1765
1766 static void
1767 null_addba_response_timeout(struct ieee80211_node *ni,
1768     struct ieee80211_tx_ampdu *tap)
1769 {
1770 }
1771
1772 /*
1773  * Default method for requesting A-MPDU tx aggregation.
1774  * We setup the specified state block and start a timer
1775  * to wait for an ADDBA response frame.
1776  */
1777 static int
1778 ieee80211_addba_request(struct ieee80211_node *ni,
1779         struct ieee80211_tx_ampdu *tap,
1780         int dialogtoken, int baparamset, int batimeout)
1781 {
1782         int bufsiz;
1783
1784         /* XXX locking */
1785         tap->txa_token = dialogtoken;
1786         tap->txa_flags |= IEEE80211_AGGR_IMMEDIATE;
1787         bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
1788         tap->txa_wnd = (bufsiz == 0) ?
1789             IEEE80211_AGGR_BAWMAX : min(bufsiz, IEEE80211_AGGR_BAWMAX);
1790         addba_start_timeout(tap);
1791         return 1;
1792 }
1793
1794 /*
1795  * Default method for processing an A-MPDU tx aggregation
1796  * response.  We shutdown any pending timer and update the
1797  * state block according to the reply.
1798  */
1799 static int
1800 ieee80211_addba_response(struct ieee80211_node *ni,
1801         struct ieee80211_tx_ampdu *tap,
1802         int status, int baparamset, int batimeout)
1803 {
1804         int bufsiz, tid;
1805
1806         /* XXX locking */
1807         addba_stop_timeout(tap);
1808         if (status == IEEE80211_STATUS_SUCCESS) {
1809                 bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
1810                 /* XXX override our request? */
1811                 tap->txa_wnd = (bufsiz == 0) ?
1812                     IEEE80211_AGGR_BAWMAX : min(bufsiz, IEEE80211_AGGR_BAWMAX);
1813                 /* XXX AC/TID */
1814                 tid = MS(baparamset, IEEE80211_BAPS_TID);
1815                 tap->txa_flags |= IEEE80211_AGGR_RUNNING;
1816                 tap->txa_attempts = 0;
1817         } else {
1818                 /* mark tid so we don't try again */
1819                 tap->txa_flags |= IEEE80211_AGGR_NAK;
1820         }
1821         return 1;
1822 }
1823
1824 /*
1825  * Default method for stopping A-MPDU tx aggregation.
1826  * Any timer is cleared and we drain any pending frames.
1827  */
1828 static void
1829 ieee80211_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
1830 {
1831         /* XXX locking */
1832         addba_stop_timeout(tap);
1833         if (tap->txa_flags & IEEE80211_AGGR_RUNNING) {
1834                 /* XXX clear aggregation queue */
1835                 tap->txa_flags &= ~IEEE80211_AGGR_RUNNING;
1836         }
1837         tap->txa_attempts = 0;
1838 }
1839
1840 /*
1841  * Process a received action frame using the default aggregation
1842  * policy.  We intercept ADDBA-related frames and use them to
1843  * update our aggregation state.  All other frames are passed up
1844  * for processing by ieee80211_recv_action.
1845  */
1846 static int
1847 ht_recv_action_ba_addba_request(struct ieee80211_node *ni,
1848         const struct ieee80211_frame *wh,
1849         const uint8_t *frm, const uint8_t *efrm)
1850 {
1851         struct ieee80211com *ic = ni->ni_ic;
1852         struct ieee80211vap *vap = ni->ni_vap;
1853         struct ieee80211_rx_ampdu *rap;
1854         uint8_t dialogtoken;
1855         uint16_t baparamset, batimeout, baseqctl;
1856         uint16_t args[5];
1857         int tid;
1858
1859         dialogtoken = frm[2];
1860         baparamset = LE_READ_2(frm+3);
1861         batimeout = LE_READ_2(frm+5);
1862         baseqctl = LE_READ_2(frm+7);
1863
1864         tid = MS(baparamset, IEEE80211_BAPS_TID);
1865
1866         IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
1867             "recv ADDBA request: dialogtoken %u baparamset 0x%x "
1868             "(tid %d bufsiz %d) batimeout %d baseqctl %d:%d",
1869             dialogtoken, baparamset,
1870             tid, MS(baparamset, IEEE80211_BAPS_BUFSIZ),
1871             batimeout,
1872             MS(baseqctl, IEEE80211_BASEQ_START),
1873             MS(baseqctl, IEEE80211_BASEQ_FRAG));
1874
1875         rap = &ni->ni_rx_ampdu[tid];
1876
1877         /* Send ADDBA response */
1878         args[0] = dialogtoken;
1879         /*
1880          * NB: We ack only if the sta associated with HT and
1881          * the ap is configured to do AMPDU rx (the latter
1882          * violates the 11n spec and is mostly for testing).
1883          */
1884         if ((ni->ni_flags & IEEE80211_NODE_AMPDU_RX) &&
1885             (vap->iv_flags_ht & IEEE80211_FHT_AMPDU_RX)) {
1886                 /* XXX handle ampdu_rx_start failure */
1887                 ic->ic_ampdu_rx_start(ni, rap,
1888                     baparamset, batimeout, baseqctl);
1889
1890                 args[1] = IEEE80211_STATUS_SUCCESS;
1891         } else {
1892                 IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
1893                     ni, "reject ADDBA request: %s",
1894                     ni->ni_flags & IEEE80211_NODE_AMPDU_RX ?
1895                        "administratively disabled" :
1896                        "not negotiated for station");
1897                 vap->iv_stats.is_addba_reject++;
1898                 args[1] = IEEE80211_STATUS_UNSPECIFIED;
1899         }
1900         /* XXX honor rap flags? */
1901         args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE
1902                 | SM(tid, IEEE80211_BAPS_TID)
1903                 | SM(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ)
1904                 ;
1905         args[3] = 0;
1906         args[4] = 0;
1907         ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
1908                 IEEE80211_ACTION_BA_ADDBA_RESPONSE, args);
1909         return 0;
1910 }
1911
1912 static int
1913 ht_recv_action_ba_addba_response(struct ieee80211_node *ni,
1914         const struct ieee80211_frame *wh,
1915         const uint8_t *frm, const uint8_t *efrm)
1916 {
1917         struct ieee80211com *ic = ni->ni_ic;
1918         struct ieee80211vap *vap = ni->ni_vap;
1919         struct ieee80211_tx_ampdu *tap;
1920         uint8_t dialogtoken, policy;
1921         uint16_t baparamset, batimeout, code;
1922         int tid, bufsiz;
1923
1924         dialogtoken = frm[2];
1925         code = LE_READ_2(frm+3);
1926         baparamset = LE_READ_2(frm+5);
1927         tid = MS(baparamset, IEEE80211_BAPS_TID);
1928         bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ);
1929         policy = MS(baparamset, IEEE80211_BAPS_POLICY);
1930         batimeout = LE_READ_2(frm+7);
1931
1932         tap = &ni->ni_tx_ampdu[tid];
1933         if ((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0) {
1934                 IEEE80211_DISCARD_MAC(vap,
1935                     IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
1936                     ni->ni_macaddr, "ADDBA response",
1937                     "no pending ADDBA, tid %d dialogtoken %u "
1938                     "code %d", tid, dialogtoken, code);
1939                 vap->iv_stats.is_addba_norequest++;
1940                 return 0;
1941         }
1942         if (dialogtoken != tap->txa_token) {
1943                 IEEE80211_DISCARD_MAC(vap,
1944                     IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
1945                     ni->ni_macaddr, "ADDBA response",
1946                     "dialogtoken mismatch: waiting for %d, "
1947                     "received %d, tid %d code %d",
1948                     tap->txa_token, dialogtoken, tid, code);
1949                 vap->iv_stats.is_addba_badtoken++;
1950                 return 0;
1951         }
1952         /* NB: assumes IEEE80211_AGGR_IMMEDIATE is 1 */
1953         if (policy != (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE)) {
1954                 IEEE80211_DISCARD_MAC(vap,
1955                     IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
1956                     ni->ni_macaddr, "ADDBA response",
1957                     "policy mismatch: expecting %s, "
1958                     "received %s, tid %d code %d",
1959                     tap->txa_flags & IEEE80211_AGGR_IMMEDIATE,
1960                     policy, tid, code);
1961                 vap->iv_stats.is_addba_badpolicy++;
1962                 return 0;
1963         }
1964 #if 0
1965         /* XXX we take MIN in ieee80211_addba_response */
1966         if (bufsiz > IEEE80211_AGGR_BAWMAX) {
1967                 IEEE80211_DISCARD_MAC(vap,
1968                     IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
1969                     ni->ni_macaddr, "ADDBA response",
1970                     "BA window too large: max %d, "
1971                     "received %d, tid %d code %d",
1972                     bufsiz, IEEE80211_AGGR_BAWMAX, tid, code);
1973                 vap->iv_stats.is_addba_badbawinsize++;
1974                 return 0;
1975         }
1976 #endif
1977         IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
1978             "recv ADDBA response: dialogtoken %u code %d "
1979             "baparamset 0x%x (tid %d bufsiz %d) batimeout %d",
1980             dialogtoken, code, baparamset, tid, bufsiz,
1981             batimeout);
1982         ic->ic_addba_response(ni, tap, code, baparamset, batimeout);
1983         return 0;
1984 }
1985
1986 static int
1987 ht_recv_action_ba_delba(struct ieee80211_node *ni,
1988         const struct ieee80211_frame *wh,
1989         const uint8_t *frm, const uint8_t *efrm)
1990 {
1991         struct ieee80211com *ic = ni->ni_ic;
1992         struct ieee80211_rx_ampdu *rap;
1993         struct ieee80211_tx_ampdu *tap;
1994         uint16_t baparamset, code;
1995         int tid;
1996
1997         baparamset = LE_READ_2(frm+2);
1998         code = LE_READ_2(frm+4);
1999
2000         tid = MS(baparamset, IEEE80211_DELBAPS_TID);
2001
2002         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
2003             "recv DELBA: baparamset 0x%x (tid %d initiator %d) "
2004             "code %d", baparamset, tid,
2005             MS(baparamset, IEEE80211_DELBAPS_INIT), code);
2006
2007         if ((baparamset & IEEE80211_DELBAPS_INIT) == 0) {
2008                 tap = &ni->ni_tx_ampdu[tid];
2009                 ic->ic_addba_stop(ni, tap);
2010         } else {
2011                 rap = &ni->ni_rx_ampdu[tid];
2012                 ic->ic_ampdu_rx_stop(ni, rap);
2013         }
2014         return 0;
2015 }
2016
2017 static int
2018 ht_recv_action_ht_txchwidth(struct ieee80211_node *ni,
2019         const struct ieee80211_frame *wh,
2020         const uint8_t *frm, const uint8_t *efrm)
2021 {
2022         int chw;
2023
2024         chw = (frm[2] == IEEE80211_A_HT_TXCHWIDTH_2040) ? 40 : 20;
2025
2026         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
2027             "%s: HT txchwidth, width %d%s",
2028             __func__, chw, ni->ni_chw != chw ? "*" : "");
2029         if (chw != ni->ni_chw) {
2030                 ni->ni_chw = chw;
2031                 /* XXX notify on change */
2032         }
2033         return 0;
2034 }
2035
2036 static int
2037 ht_recv_action_ht_mimopwrsave(struct ieee80211_node *ni,
2038         const struct ieee80211_frame *wh,
2039         const uint8_t *frm, const uint8_t *efrm)
2040 {
2041         const struct ieee80211_action_ht_mimopowersave *mps =
2042             (const struct ieee80211_action_ht_mimopowersave *) frm;
2043
2044         /* XXX check iv_htcaps */
2045         if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA)
2046                 ni->ni_flags |= IEEE80211_NODE_MIMO_PS;
2047         else
2048                 ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS;
2049         if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE)
2050                 ni->ni_flags |= IEEE80211_NODE_MIMO_RTS;
2051         else
2052                 ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS;
2053         /* XXX notify on change */
2054         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
2055             "%s: HT MIMO PS (%s%s)", __func__,
2056             (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ?  "on" : "off",
2057             (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ?  "+rts" : ""
2058         );
2059         return 0;
2060 }
2061
2062 /*
2063  * Transmit processing.
2064  */
2065
2066 /*
2067  * Check if A-MPDU should be requested/enabled for a stream.
2068  * We require a traffic rate above a per-AC threshold and we
2069  * also handle backoff from previous failed attempts.
2070  *
2071  * Drivers may override this method to bring in information
2072  * such as link state conditions in making the decision.
2073  */
2074 static int
2075 ieee80211_ampdu_enable(struct ieee80211_node *ni,
2076         struct ieee80211_tx_ampdu *tap)
2077 {
2078         struct ieee80211vap *vap = ni->ni_vap;
2079
2080         if (tap->txa_avgpps <
2081             vap->iv_ampdu_mintraffic[TID_TO_WME_AC(tap->txa_tid)])
2082                 return 0;
2083         /* XXX check rssi? */
2084         if (tap->txa_attempts >= ieee80211_addba_maxtries &&
2085             ticks < tap->txa_nextrequest) {
2086                 /*
2087                  * Don't retry too often; txa_nextrequest is set
2088                  * to the minimum interval we'll retry after
2089                  * ieee80211_addba_maxtries failed attempts are made.
2090                  */
2091                 return 0;
2092         }
2093         IEEE80211_NOTE(vap, IEEE80211_MSG_11N, ni,
2094             "enable AMPDU on tid %d (%s), avgpps %d pkts %d",
2095             tap->txa_tid, ieee80211_wme_acnames[TID_TO_WME_AC(tap->txa_tid)],
2096             tap->txa_avgpps, tap->txa_pkts);
2097         return 1;
2098 }
2099
2100 /*
2101  * Request A-MPDU tx aggregation.  Setup local state and
2102  * issue an ADDBA request.  BA use will only happen after
2103  * the other end replies with ADDBA response.
2104  */
2105 int
2106 ieee80211_ampdu_request(struct ieee80211_node *ni,
2107         struct ieee80211_tx_ampdu *tap)
2108 {
2109         struct ieee80211com *ic = ni->ni_ic;
2110         uint16_t args[5];
2111         int tid, dialogtoken;
2112         static int tokens = 0;  /* XXX */
2113
2114         /* XXX locking */
2115         if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) {
2116                 /* do deferred setup of state */
2117                 ampdu_tx_setup(tap);
2118         }
2119         /* XXX hack for not doing proper locking */
2120         tap->txa_flags &= ~IEEE80211_AGGR_NAK;
2121
2122         dialogtoken = (tokens+1) % 63;          /* XXX */
2123         tid = tap->txa_tid;
2124         tap->txa_start = ni->ni_txseqs[tid];
2125
2126         args[0] = dialogtoken;
2127         args[1] = 0;    /* NB: status code not used */
2128         args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE
2129                 | SM(tid, IEEE80211_BAPS_TID)
2130                 | SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ)
2131                 ;
2132         args[3] = 0;    /* batimeout */
2133         /* NB: do first so there's no race against reply */
2134         if (!ic->ic_addba_request(ni, tap, dialogtoken, args[2], args[3])) {
2135                 /* unable to setup state, don't make request */
2136                 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2137                     ni, "%s: could not setup BA stream for TID %d AC %d",
2138                     __func__, tap->txa_tid, TID_TO_WME_AC(tap->txa_tid));
2139                 /* defer next try so we don't slam the driver with requests */
2140                 tap->txa_attempts = ieee80211_addba_maxtries;
2141                 /* NB: check in case driver wants to override */
2142                 if (tap->txa_nextrequest <= ticks)
2143                         tap->txa_nextrequest = ticks + ieee80211_addba_backoff;
2144                 return 0;
2145         }
2146         tokens = dialogtoken;                   /* allocate token */
2147         /* NB: after calling ic_addba_request so driver can set txa_start */
2148         args[4] = SM(tap->txa_start, IEEE80211_BASEQ_START)
2149                 | SM(0, IEEE80211_BASEQ_FRAG)
2150                 ;
2151         return ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
2152                 IEEE80211_ACTION_BA_ADDBA_REQUEST, args);
2153 }
2154
2155 /*
2156  * Terminate an AMPDU tx stream.  State is reclaimed
2157  * and the peer notified with a DelBA Action frame.
2158  */
2159 void
2160 ieee80211_ampdu_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
2161         int reason)
2162 {
2163         struct ieee80211com *ic = ni->ni_ic;
2164         struct ieee80211vap *vap = ni->ni_vap;
2165         uint16_t args[4];
2166
2167         /* XXX locking */
2168         tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
2169         if (IEEE80211_AMPDU_RUNNING(tap)) {
2170                 IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
2171                     ni, "%s: stop BA stream for TID %d (reason %d)",
2172                     __func__, tap->txa_tid, reason);
2173                 vap->iv_stats.is_ampdu_stop++;
2174
2175                 ic->ic_addba_stop(ni, tap);
2176                 args[0] = tap->txa_tid;
2177                 args[1] = IEEE80211_DELBAPS_INIT;
2178                 args[2] = reason;                       /* XXX reason code */
2179                 ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
2180                         IEEE80211_ACTION_BA_DELBA, args);
2181         } else {
2182                 IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
2183                     ni, "%s: BA stream for TID %d not running (reason %d)",
2184                     __func__, tap->txa_tid, reason);
2185                 vap->iv_stats.is_ampdu_stop_failed++;
2186         }
2187 }
2188
2189 /* XXX */
2190 static void bar_start_timer(struct ieee80211_tx_ampdu *tap);
2191
2192 static void
2193 bar_timeout(void *arg)
2194 {
2195         struct ieee80211_tx_ampdu *tap = arg;
2196         struct ieee80211_node *ni = tap->txa_ni;
2197
2198         KASSERT((tap->txa_flags & IEEE80211_AGGR_XCHGPEND) == 0,
2199             ("bar/addba collision, flags 0x%x", tap->txa_flags));
2200
2201         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2202             ni, "%s: tid %u flags 0x%x attempts %d", __func__,
2203             tap->txa_tid, tap->txa_flags, tap->txa_attempts);
2204
2205         /* guard against race with bar_tx_complete */
2206         if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0)
2207                 return;
2208         /* XXX ? */
2209         if (tap->txa_attempts >= ieee80211_bar_maxtries) {
2210                 struct ieee80211com *ic = ni->ni_ic;
2211
2212                 ni->ni_vap->iv_stats.is_ampdu_bar_tx_fail++;
2213                 /*
2214                  * If (at least) the last BAR TX timeout was due to
2215                  * an ieee80211_send_bar() failures, then we need
2216                  * to make sure we notify the driver that a BAR
2217                  * TX did occur and fail.  This gives the driver
2218                  * a chance to undo any queue pause that may
2219                  * have occured.
2220                  */
2221                 ic->ic_bar_response(ni, tap, 1);
2222                 ieee80211_ampdu_stop(ni, tap, IEEE80211_REASON_TIMEOUT);
2223         } else {
2224                 ni->ni_vap->iv_stats.is_ampdu_bar_tx_retry++;
2225                 if (ieee80211_send_bar(ni, tap, tap->txa_seqpending) != 0) {
2226                         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2227                             ni, "%s: failed to TX, starting timer\n",
2228                             __func__);
2229                         /*
2230                          * If ieee80211_send_bar() fails here, the
2231                          * timer may have stopped and/or the pending
2232                          * flag may be clear.  Because of this,
2233                          * fake the BARPEND and reset the timer.
2234                          * A retransmission attempt will then occur
2235                          * during the next timeout.
2236                          */
2237                         /* XXX locking */
2238                         tap->txa_flags |= IEEE80211_AGGR_BARPEND;
2239                         bar_start_timer(tap);
2240                 }
2241         }
2242 }
2243
2244 static void
2245 bar_start_timer(struct ieee80211_tx_ampdu *tap)
2246 {
2247         IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N,
2248             tap->txa_ni,
2249             "%s: called",
2250             __func__);
2251         callout_reset(&tap->txa_timer, ieee80211_bar_timeout, bar_timeout, tap);
2252 }
2253
2254 static void
2255 bar_stop_timer(struct ieee80211_tx_ampdu *tap)
2256 {
2257         IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N,
2258             tap->txa_ni,
2259             "%s: called",
2260             __func__);
2261         callout_stop(&tap->txa_timer);
2262 }
2263
2264 static void
2265 bar_tx_complete(struct ieee80211_node *ni, void *arg, int status)
2266 {
2267         struct ieee80211_tx_ampdu *tap = arg;
2268
2269         IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2270             ni, "%s: tid %u flags 0x%x pending %d status %d",
2271             __func__, tap->txa_tid, tap->txa_flags,
2272             callout_pending(&tap->txa_timer), status);
2273
2274         ni->ni_vap->iv_stats.is_ampdu_bar_tx++;
2275         /* XXX locking */
2276         if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) &&
2277             callout_pending(&tap->txa_timer)) {
2278                 struct ieee80211com *ic = ni->ni_ic;
2279
2280                 if (status == 0)                /* ACK'd */
2281                         bar_stop_timer(tap);
2282                 ic->ic_bar_response(ni, tap, status);
2283                 /* NB: just let timer expire so we pace requests */
2284         }
2285 }
2286
2287 static void
2288 ieee80211_bar_response(struct ieee80211_node *ni,
2289         struct ieee80211_tx_ampdu *tap, int status)
2290 {
2291
2292         IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N,
2293             tap->txa_ni,
2294             "%s: called",
2295             __func__);
2296         if (status == 0) {              /* got ACK */
2297                 IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
2298                     ni, "BAR moves BA win <%u:%u> (%u frames) txseq %u tid %u",
2299                     tap->txa_start,
2300                     IEEE80211_SEQ_ADD(tap->txa_start, tap->txa_wnd-1),
2301                     tap->txa_qframes, tap->txa_seqpending,
2302                     tap->txa_tid);
2303
2304                 /* NB: timer already stopped in bar_tx_complete */
2305                 tap->txa_start = tap->txa_seqpending;
2306                 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
2307         }
2308 }
2309
2310 /*
2311  * Transmit a BAR frame to the specified node.  The
2312  * BAR contents are drawn from the supplied aggregation
2313  * state associated with the node.
2314  *
2315  * NB: we only handle immediate ACK w/ compressed bitmap.
2316  */
2317 int
2318 ieee80211_send_bar(struct ieee80211_node *ni,
2319         struct ieee80211_tx_ampdu *tap, ieee80211_seq seq)
2320 {
2321 #define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0)
2322         struct ieee80211vap *vap = ni->ni_vap;
2323         struct ieee80211com *ic = ni->ni_ic;
2324         struct ieee80211_frame_bar *bar;
2325         struct mbuf *m;
2326         uint16_t barctl, barseqctl;
2327         uint8_t *frm;
2328         int tid, ret;
2329
2330
2331         IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N,
2332             tap->txa_ni,
2333             "%s: called",
2334             __func__);
2335
2336         if ((tap->txa_flags & IEEE80211_AGGR_RUNNING) == 0) {
2337                 /* no ADDBA response, should not happen */
2338                 /* XXX stat+msg */
2339                 return EINVAL;
2340         }
2341         /* XXX locking */
2342         bar_stop_timer(tap);
2343
2344         ieee80211_ref_node(ni);
2345
2346         m = ieee80211_getmgtframe(&frm, ic->ic_headroom, sizeof(*bar));
2347         if (m == NULL)
2348                 senderr(ENOMEM, is_tx_nobuf);
2349
2350         if (!ieee80211_add_callback(m, bar_tx_complete, tap)) {
2351                 m_freem(m);
2352                 senderr(ENOMEM, is_tx_nobuf);   /* XXX */
2353                 /* NOTREACHED */
2354         }
2355
2356         bar = mtod(m, struct ieee80211_frame_bar *);
2357         bar->i_fc[0] = IEEE80211_FC0_VERSION_0 |
2358                 IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR;
2359         bar->i_fc[1] = 0;
2360         IEEE80211_ADDR_COPY(bar->i_ra, ni->ni_macaddr);
2361         IEEE80211_ADDR_COPY(bar->i_ta, vap->iv_myaddr);
2362
2363         tid = tap->txa_tid;
2364         barctl  = (tap->txa_flags & IEEE80211_AGGR_IMMEDIATE ?
2365                         0 : IEEE80211_BAR_NOACK)
2366                 | IEEE80211_BAR_COMP
2367                 | SM(tid, IEEE80211_BAR_TID)
2368                 ;
2369         barseqctl = SM(seq, IEEE80211_BAR_SEQ_START);
2370         /* NB: known to have proper alignment */
2371         bar->i_ctl = htole16(barctl);
2372         bar->i_seq = htole16(barseqctl);
2373         m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_bar);
2374
2375         M_WME_SETAC(m, WME_AC_VO);
2376
2377         IEEE80211_NODE_STAT(ni, tx_mgmt);       /* XXX tx_ctl? */
2378
2379         /* XXX locking */
2380         /* init/bump attempts counter */
2381         if ((tap->txa_flags & IEEE80211_AGGR_BARPEND) == 0)
2382                 tap->txa_attempts = 1;
2383         else
2384                 tap->txa_attempts++;
2385         tap->txa_seqpending = seq;
2386         tap->txa_flags |= IEEE80211_AGGR_BARPEND;
2387
2388         IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_11N,
2389             ni, "send BAR: tid %u ctl 0x%x start %u (attempt %d)",
2390             tid, barctl, seq, tap->txa_attempts);
2391
2392         /*
2393          * ic_raw_xmit will free the node reference
2394          * regardless of queue/TX success or failure.
2395          */
2396         IEEE80211_TX_LOCK(ic);
2397         ret = ieee80211_raw_output(vap, ni, m, NULL);
2398         IEEE80211_TX_UNLOCK(ic);
2399         if (ret != 0) {
2400                 IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_11N,
2401                     ni, "send BAR: failed: (ret = %d)\n",
2402                     ret);
2403                 /* xmit failed, clear state flag */
2404                 tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
2405                 vap->iv_stats.is_ampdu_bar_tx_fail++;
2406                 return ret;
2407         }
2408         /* XXX hack against tx complete happening before timer is started */
2409         if (tap->txa_flags & IEEE80211_AGGR_BARPEND)
2410                 bar_start_timer(tap);
2411         return 0;
2412 bad:
2413         IEEE80211_NOTE(tap->txa_ni->ni_vap, IEEE80211_MSG_11N,
2414             tap->txa_ni,
2415             "%s: bad! ret=%d",
2416             __func__, ret);
2417         vap->iv_stats.is_ampdu_bar_tx_fail++;
2418         ieee80211_free_node(ni);
2419         return ret;
2420 #undef senderr
2421 }
2422
2423 static int
2424 ht_action_output(struct ieee80211_node *ni, struct mbuf *m)
2425 {
2426         struct ieee80211_bpf_params params;
2427
2428         memset(&params, 0, sizeof(params));
2429         params.ibp_pri = WME_AC_VO;
2430         params.ibp_rate0 = ni->ni_txparms->mgmtrate;
2431         /* NB: we know all frames are unicast */
2432         params.ibp_try0 = ni->ni_txparms->maxretry;
2433         params.ibp_power = ni->ni_txpower;
2434         return ieee80211_mgmt_output(ni, m, IEEE80211_FC0_SUBTYPE_ACTION,
2435              &params);
2436 }
2437
2438 #define ADDSHORT(frm, v) do {                   \
2439         frm[0] = (v) & 0xff;                    \
2440         frm[1] = (v) >> 8;                      \
2441         frm += 2;                               \
2442 } while (0)
2443
2444 /*
2445  * Send an action management frame.  The arguments are stuff
2446  * into a frame without inspection; the caller is assumed to
2447  * prepare them carefully (e.g. based on the aggregation state).
2448  */
2449 static int
2450 ht_send_action_ba_addba(struct ieee80211_node *ni,
2451         int category, int action, void *arg0)
2452 {
2453         struct ieee80211vap *vap = ni->ni_vap;
2454         struct ieee80211com *ic = ni->ni_ic;
2455         uint16_t *args = arg0;
2456         struct mbuf *m;
2457         uint8_t *frm;
2458
2459         IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
2460             "send ADDBA %s: dialogtoken %d status %d "
2461             "baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x",
2462             (action == IEEE80211_ACTION_BA_ADDBA_REQUEST) ?
2463                 "request" : "response",
2464             args[0], args[1], args[2], MS(args[2], IEEE80211_BAPS_TID),
2465             args[3], args[4]);
2466
2467         IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2468             "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2469             ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2470         ieee80211_ref_node(ni);
2471
2472         m = ieee80211_getmgtframe(&frm,
2473             ic->ic_headroom + sizeof(struct ieee80211_frame),
2474             sizeof(uint16_t)    /* action+category */
2475             /* XXX may action payload */
2476             + sizeof(struct ieee80211_action_ba_addbaresponse)
2477         );
2478         if (m != NULL) {
2479                 *frm++ = category;
2480                 *frm++ = action;
2481                 *frm++ = args[0];               /* dialog token */
2482                 if (action == IEEE80211_ACTION_BA_ADDBA_RESPONSE)
2483                         ADDSHORT(frm, args[1]); /* status code */
2484                 ADDSHORT(frm, args[2]);         /* baparamset */
2485                 ADDSHORT(frm, args[3]);         /* batimeout */
2486                 if (action == IEEE80211_ACTION_BA_ADDBA_REQUEST)
2487                         ADDSHORT(frm, args[4]); /* baseqctl */
2488                 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2489                 return ht_action_output(ni, m);
2490         } else {
2491                 vap->iv_stats.is_tx_nobuf++;
2492                 ieee80211_free_node(ni);
2493                 return ENOMEM;
2494         }
2495 }
2496
2497 static int
2498 ht_send_action_ba_delba(struct ieee80211_node *ni,
2499         int category, int action, void *arg0)
2500 {
2501         struct ieee80211vap *vap = ni->ni_vap;
2502         struct ieee80211com *ic = ni->ni_ic;
2503         uint16_t *args = arg0;
2504         struct mbuf *m;
2505         uint16_t baparamset;
2506         uint8_t *frm;
2507
2508         baparamset = SM(args[0], IEEE80211_DELBAPS_TID)
2509                    | args[1]
2510                    ;
2511         IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
2512             "send DELBA action: tid %d, initiator %d reason %d",
2513             args[0], args[1], args[2]);
2514
2515         IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2516             "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2517             ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2518         ieee80211_ref_node(ni);
2519
2520         m = ieee80211_getmgtframe(&frm,
2521             ic->ic_headroom + sizeof(struct ieee80211_frame),
2522             sizeof(uint16_t)    /* action+category */
2523             /* XXX may action payload */
2524             + sizeof(struct ieee80211_action_ba_addbaresponse)
2525         );
2526         if (m != NULL) {
2527                 *frm++ = category;
2528                 *frm++ = action;
2529                 ADDSHORT(frm, baparamset);
2530                 ADDSHORT(frm, args[2]);         /* reason code */
2531                 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2532                 return ht_action_output(ni, m);
2533         } else {
2534                 vap->iv_stats.is_tx_nobuf++;
2535                 ieee80211_free_node(ni);
2536                 return ENOMEM;
2537         }
2538 }
2539
2540 static int
2541 ht_send_action_ht_txchwidth(struct ieee80211_node *ni,
2542         int category, int action, void *arg0)
2543 {
2544         struct ieee80211vap *vap = ni->ni_vap;
2545         struct ieee80211com *ic = ni->ni_ic;
2546         struct mbuf *m;
2547         uint8_t *frm;
2548
2549         IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
2550             "send HT txchwidth: width %d",
2551             IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20);
2552
2553         IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
2554             "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
2555             ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
2556         ieee80211_ref_node(ni);
2557
2558         m = ieee80211_getmgtframe(&frm,
2559             ic->ic_headroom + sizeof(struct ieee80211_frame),
2560             sizeof(uint16_t)    /* action+category */
2561             /* XXX may action payload */
2562             + sizeof(struct ieee80211_action_ba_addbaresponse)
2563         );
2564         if (m != NULL) {
2565                 *frm++ = category;
2566                 *frm++ = action;
2567                 *frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 
2568                         IEEE80211_A_HT_TXCHWIDTH_2040 :
2569                         IEEE80211_A_HT_TXCHWIDTH_20;
2570                 m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
2571                 return ht_action_output(ni, m);
2572         } else {
2573                 vap->iv_stats.is_tx_nobuf++;
2574                 ieee80211_free_node(ni);
2575                 return ENOMEM;
2576         }
2577 }
2578 #undef ADDSHORT
2579
2580 /*
2581  * Construct the MCS bit mask for inclusion in an HT capabilities
2582  * information element.
2583  */
2584 static void
2585 ieee80211_set_mcsset(struct ieee80211com *ic, uint8_t *frm)
2586 {
2587         int i;
2588         uint8_t txparams;
2589
2590         KASSERT((ic->ic_rxstream > 0 && ic->ic_rxstream <= 4),
2591             ("ic_rxstream %d out of range", ic->ic_rxstream));
2592         KASSERT((ic->ic_txstream > 0 && ic->ic_txstream <= 4),
2593             ("ic_txstream %d out of range", ic->ic_txstream));
2594
2595         for (i = 0; i < ic->ic_rxstream * 8; i++)
2596                 setbit(frm, i);
2597         if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
2598             (ic->ic_htcaps & IEEE80211_HTC_RXMCS32))
2599                 setbit(frm, 32);
2600         if (ic->ic_htcaps & IEEE80211_HTC_RXUNEQUAL) {
2601                 if (ic->ic_rxstream >= 2) {
2602                         for (i = 33; i <= 38; i++)
2603                                 setbit(frm, i);
2604                 }
2605                 if (ic->ic_rxstream >= 3) {
2606                         for (i = 39; i <= 52; i++)
2607                                 setbit(frm, i);
2608                 }
2609                 if (ic->ic_txstream >= 4) {
2610                         for (i = 53; i <= 76; i++)
2611                                 setbit(frm, i);
2612                 }
2613         }
2614
2615         if (ic->ic_rxstream != ic->ic_txstream) {
2616                 txparams = 0x1;                 /* TX MCS set defined */
2617                 txparams |= 0x2;                /* TX RX MCS not equal */
2618                 txparams |= (ic->ic_txstream - 1) << 2; /* num TX streams */
2619                 if (ic->ic_htcaps & IEEE80211_HTC_TXUNEQUAL)
2620                         txparams |= 0x16;       /* TX unequal modulation sup */
2621         } else
2622                 txparams = 0;
2623         frm[12] = txparams;
2624 }
2625
2626 /*
2627  * Add body of an HTCAP information element.
2628  */
2629 static uint8_t *
2630 ieee80211_add_htcap_body(uint8_t *frm, struct ieee80211_node *ni)
2631 {
2632 #define ADDSHORT(frm, v) do {                   \
2633         frm[0] = (v) & 0xff;                    \
2634         frm[1] = (v) >> 8;                      \
2635         frm += 2;                               \
2636 } while (0)
2637         struct ieee80211com *ic = ni->ni_ic;
2638         struct ieee80211vap *vap = ni->ni_vap;
2639         uint16_t caps, extcaps;
2640         int rxmax, density;
2641
2642         /* HT capabilities */
2643         caps = vap->iv_htcaps & 0xffff;
2644         /*
2645          * Note channel width depends on whether we are operating as
2646          * a sta or not.  When operating as a sta we are generating
2647          * a request based on our desired configuration.  Otherwise
2648          * we are operational and the channel attributes identify
2649          * how we've been setup (which might be different if a fixed
2650          * channel is specified).
2651          */
2652         if (vap->iv_opmode == IEEE80211_M_STA) {
2653                 /* override 20/40 use based on config */
2654                 if (vap->iv_flags_ht & IEEE80211_FHT_USEHT40)
2655                         caps |= IEEE80211_HTCAP_CHWIDTH40;
2656                 else
2657                         caps &= ~IEEE80211_HTCAP_CHWIDTH40;
2658                 /* use advertised setting (XXX locally constraint) */
2659                 rxmax = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
2660                 density = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
2661
2662                 /*
2663                  * NB: Hardware might support HT40 on some but not all
2664                  * channels. We can't determine this earlier because only
2665                  * after association the channel is upgraded to HT based
2666                  * on the negotiated capabilities.
2667                  */
2668                 if (ni->ni_chan != IEEE80211_CHAN_ANYC &&
2669                     findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40U) == NULL &&
2670                     findhtchan(ic, ni->ni_chan, IEEE80211_CHAN_HT40D) == NULL)
2671                         caps &= ~IEEE80211_HTCAP_CHWIDTH40;
2672         } else {
2673                 /* override 20/40 use based on current channel */
2674                 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan))
2675                         caps |= IEEE80211_HTCAP_CHWIDTH40;
2676                 else
2677                         caps &= ~IEEE80211_HTCAP_CHWIDTH40;
2678                 rxmax = vap->iv_ampdu_rxmax;
2679                 density = vap->iv_ampdu_density;
2680         }
2681         /* adjust short GI based on channel and config */
2682         if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0)
2683                 caps &= ~IEEE80211_HTCAP_SHORTGI20;
2684         if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0 ||
2685             (caps & IEEE80211_HTCAP_CHWIDTH40) == 0)
2686                 caps &= ~IEEE80211_HTCAP_SHORTGI40;
2687         ADDSHORT(frm, caps);
2688
2689         /* HT parameters */
2690         *frm = SM(rxmax, IEEE80211_HTCAP_MAXRXAMPDU)
2691              | SM(density, IEEE80211_HTCAP_MPDUDENSITY)
2692              ;
2693         frm++;
2694
2695         /* pre-zero remainder of ie */
2696         memset(frm, 0, sizeof(struct ieee80211_ie_htcap) - 
2697                 __offsetof(struct ieee80211_ie_htcap, hc_mcsset));
2698
2699         /* supported MCS set */
2700         /*
2701          * XXX: For sta mode the rate set should be restricted based
2702          * on the AP's capabilities, but ni_htrates isn't setup when
2703          * we're called to form an AssocReq frame so for now we're
2704          * restricted to the device capabilities.
2705          */
2706         ieee80211_set_mcsset(ni->ni_ic, frm);
2707
2708         frm += __offsetof(struct ieee80211_ie_htcap, hc_extcap) -
2709                 __offsetof(struct ieee80211_ie_htcap, hc_mcsset);
2710
2711         /* HT extended capabilities */
2712         extcaps = vap->iv_htextcaps & 0xffff;
2713
2714         ADDSHORT(frm, extcaps);
2715
2716         frm += sizeof(struct ieee80211_ie_htcap) -
2717                 __offsetof(struct ieee80211_ie_htcap, hc_txbf);
2718
2719         return frm;
2720 #undef ADDSHORT
2721 }
2722
2723 /*
2724  * Add 802.11n HT capabilities information element
2725  */
2726 uint8_t *
2727 ieee80211_add_htcap(uint8_t *frm, struct ieee80211_node *ni)
2728 {
2729         frm[0] = IEEE80211_ELEMID_HTCAP;
2730         frm[1] = sizeof(struct ieee80211_ie_htcap) - 2;
2731         return ieee80211_add_htcap_body(frm + 2, ni);
2732 }
2733
2734 /*
2735  * Add Broadcom OUI wrapped standard HTCAP ie; this is
2736  * used for compatibility w/ pre-draft implementations.
2737  */
2738 uint8_t *
2739 ieee80211_add_htcap_vendor(uint8_t *frm, struct ieee80211_node *ni)
2740 {
2741         frm[0] = IEEE80211_ELEMID_VENDOR;
2742         frm[1] = 4 + sizeof(struct ieee80211_ie_htcap) - 2;
2743         frm[2] = (BCM_OUI >> 0) & 0xff;
2744         frm[3] = (BCM_OUI >> 8) & 0xff;
2745         frm[4] = (BCM_OUI >> 16) & 0xff;
2746         frm[5] = BCM_OUI_HTCAP;
2747         return ieee80211_add_htcap_body(frm + 6, ni);
2748 }
2749
2750 /*
2751  * Construct the MCS bit mask of basic rates
2752  * for inclusion in an HT information element.
2753  */
2754 static void
2755 ieee80211_set_basic_htrates(uint8_t *frm, const struct ieee80211_htrateset *rs)
2756 {
2757         int i;
2758
2759         for (i = 0; i < rs->rs_nrates; i++) {
2760                 int r = rs->rs_rates[i] & IEEE80211_RATE_VAL;
2761                 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
2762                     r < IEEE80211_HTRATE_MAXSIZE) {
2763                         /* NB: this assumes a particular implementation */
2764                         setbit(frm, r);
2765                 }
2766         }
2767 }
2768
2769 /*
2770  * Update the HTINFO ie for a beacon frame.
2771  */
2772 void
2773 ieee80211_ht_update_beacon(struct ieee80211vap *vap,
2774         struct ieee80211_beacon_offsets *bo)
2775 {
2776 #define PROTMODE        (IEEE80211_HTINFO_OPMODE|IEEE80211_HTINFO_NONHT_PRESENT)
2777         struct ieee80211_node *ni;
2778         const struct ieee80211_channel *bsschan;
2779         struct ieee80211com *ic = vap->iv_ic;
2780         struct ieee80211_ie_htinfo *ht =
2781            (struct ieee80211_ie_htinfo *) bo->bo_htinfo;
2782
2783         ni = ieee80211_ref_node(vap->iv_bss);
2784         bsschan = ni->ni_chan;
2785
2786         /* XXX only update on channel change */
2787         ht->hi_ctrlchannel = ieee80211_chan2ieee(ic, bsschan);
2788         if (vap->iv_flags_ht & IEEE80211_FHT_RIFS)
2789                 ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PERM;
2790         else
2791                 ht->hi_byte1 = IEEE80211_HTINFO_RIFSMODE_PROH;
2792         if (IEEE80211_IS_CHAN_HT40U(bsschan))
2793                 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_ABOVE;
2794         else if (IEEE80211_IS_CHAN_HT40D(bsschan))
2795                 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_BELOW;
2796         else
2797                 ht->hi_byte1 |= IEEE80211_HTINFO_2NDCHAN_NONE;
2798         if (IEEE80211_IS_CHAN_HT40(bsschan))
2799                 ht->hi_byte1 |= IEEE80211_HTINFO_TXWIDTH_2040;
2800
2801         /* protection mode */
2802         ht->hi_byte2 = (ht->hi_byte2 &~ PROTMODE) | ic->ic_curhtprotmode;
2803
2804         ieee80211_free_node(ni);
2805
2806         /* XXX propagate to vendor ie's */
2807 #undef PROTMODE
2808 }
2809
2810 /*
2811  * Add body of an HTINFO information element.
2812  *
2813  * NB: We don't use struct ieee80211_ie_htinfo because we can
2814  * be called to fillin both a standard ie and a compat ie that
2815  * has a vendor OUI at the front.
2816  */
2817 static uint8_t *
2818 ieee80211_add_htinfo_body(uint8_t *frm, struct ieee80211_node *ni)
2819 {
2820         struct ieee80211vap *vap = ni->ni_vap;
2821         struct ieee80211com *ic = ni->ni_ic;
2822
2823         /* pre-zero remainder of ie */
2824         memset(frm, 0, sizeof(struct ieee80211_ie_htinfo) - 2);
2825
2826         /* primary/control channel center */
2827         *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
2828
2829         if (vap->iv_flags_ht & IEEE80211_FHT_RIFS)
2830                 frm[0] = IEEE80211_HTINFO_RIFSMODE_PERM;
2831         else
2832                 frm[0] = IEEE80211_HTINFO_RIFSMODE_PROH;
2833         if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
2834                 frm[0] |= IEEE80211_HTINFO_2NDCHAN_ABOVE;
2835         else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
2836                 frm[0] |= IEEE80211_HTINFO_2NDCHAN_BELOW;
2837         else
2838                 frm[0] |= IEEE80211_HTINFO_2NDCHAN_NONE;
2839         if (IEEE80211_IS_CHAN_HT40(ni->ni_chan))
2840                 frm[0] |= IEEE80211_HTINFO_TXWIDTH_2040;
2841
2842         frm[1] = ic->ic_curhtprotmode;
2843
2844         frm += 5;
2845
2846         /* basic MCS set */
2847         ieee80211_set_basic_htrates(frm, &ni->ni_htrates);
2848         frm += sizeof(struct ieee80211_ie_htinfo) -
2849                 __offsetof(struct ieee80211_ie_htinfo, hi_basicmcsset);
2850         return frm;
2851 }
2852
2853 /*
2854  * Add 802.11n HT information information element.
2855  */
2856 uint8_t *
2857 ieee80211_add_htinfo(uint8_t *frm, struct ieee80211_node *ni)
2858 {
2859         frm[0] = IEEE80211_ELEMID_HTINFO;
2860         frm[1] = sizeof(struct ieee80211_ie_htinfo) - 2;
2861         return ieee80211_add_htinfo_body(frm + 2, ni);
2862 }
2863
2864 /*
2865  * Add Broadcom OUI wrapped standard HTINFO ie; this is
2866  * used for compatibility w/ pre-draft implementations.
2867  */
2868 uint8_t *
2869 ieee80211_add_htinfo_vendor(uint8_t *frm, struct ieee80211_node *ni)
2870 {
2871         frm[0] = IEEE80211_ELEMID_VENDOR;
2872         frm[1] = 4 + sizeof(struct ieee80211_ie_htinfo) - 2;
2873         frm[2] = (BCM_OUI >> 0) & 0xff;
2874         frm[3] = (BCM_OUI >> 8) & 0xff;
2875         frm[4] = (BCM_OUI >> 16) & 0xff;
2876         frm[5] = BCM_OUI_HTINFO;
2877         return ieee80211_add_htinfo_body(frm + 6, ni);
2878 }