1 /*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_proto.c,v 1.50 2008/10/23 19:57:13 des Exp $");
29
30 /*
31 * IEEE 802.11 protocol support.
32 */
33
34 #include "opt_inet.h"
35 #include "opt_wlan.h"
36
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 #include <sys/taskqueue.h>
41
42 #include <sys/socket.h>
43 #include <sys/sockio.h>
44
45 #include <net/if.h>
46 #include <net/if_media.h>
47 #include <net/ethernet.h> /* XXX for ether_sprintf */
48
49 #include <net80211/ieee80211_var.h>
50 #include <net80211/ieee80211_adhoc.h>
51 #include <net80211/ieee80211_sta.h>
52 #include <net80211/ieee80211_hostap.h>
53 #include <net80211/ieee80211_wds.h>
54 #include <net80211/ieee80211_monitor.h>
55 #include <net80211/ieee80211_input.h>
56
57 /* XXX tunables */
58 #define AGGRESSIVE_MODE_SWITCH_HYSTERESIS 3 /* pkts / 100ms */
59 #define HIGH_PRI_SWITCH_THRESH 10 /* pkts / 100ms */
60
61 const char *ieee80211_mgt_subtype_name[] = {
62 "assoc_req", "assoc_resp", "reassoc_req", "reassoc_resp",
63 "probe_req", "probe_resp", "reserved#6", "reserved#7",
64 "beacon", "atim", "disassoc", "auth",
65 "deauth", "action", "reserved#14", "reserved#15"
66 };
67 const char *ieee80211_ctl_subtype_name[] = {
68 "reserved#0", "reserved#1", "reserved#2", "reserved#3",
69 "reserved#3", "reserved#5", "reserved#6", "reserved#7",
70 "reserved#8", "reserved#9", "ps_poll", "rts",
71 "cts", "ack", "cf_end", "cf_end_ack"
72 };
73 const char *ieee80211_opmode_name[IEEE80211_OPMODE_MAX] = {
74 "IBSS", /* IEEE80211_M_IBSS */
75 "STA", /* IEEE80211_M_STA */
76 "WDS", /* IEEE80211_M_WDS */
77 "AHDEMO", /* IEEE80211_M_AHDEMO */
78 "HOSTAP", /* IEEE80211_M_HOSTAP */
79 "MONITOR" /* IEEE80211_M_MONITOR */
80 };
81 const char *ieee80211_state_name[IEEE80211_S_MAX] = {
82 "INIT", /* IEEE80211_S_INIT */
83 "SCAN", /* IEEE80211_S_SCAN */
84 "AUTH", /* IEEE80211_S_AUTH */
85 "ASSOC", /* IEEE80211_S_ASSOC */
86 "CAC", /* IEEE80211_S_CAC */
87 "RUN", /* IEEE80211_S_RUN */
88 "CSA", /* IEEE80211_S_CSA */
89 "SLEEP", /* IEEE80211_S_SLEEP */
90 };
91 const char *ieee80211_wme_acnames[] = {
92 "WME_AC_BE",
93 "WME_AC_BK",
94 "WME_AC_VI",
95 "WME_AC_VO",
96 "WME_UPSD",
97 };
98
99 static void parent_updown(void *, int);
100 static int ieee80211_new_state_locked(struct ieee80211vap *,
101 enum ieee80211_state, int);
102
103 static int
104 null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
105 const struct ieee80211_bpf_params *params)
106 {
107 struct ifnet *ifp = ni->ni_ic->ic_ifp;
108
109 if_printf(ifp, "missing ic_raw_xmit callback, drop frame\n");
110 m_freem(m);
111 return ENETDOWN;
112 }
113
114 void
115 ieee80211_proto_attach(struct ieee80211com *ic)
116 {
117 struct ifnet *ifp = ic->ic_ifp;
118
119 /* override the 802.3 setting */
120 ifp->if_hdrlen = ic->ic_headroom
121 + sizeof(struct ieee80211_qosframe_addr4)
122 + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN
123 + IEEE80211_WEP_EXTIVLEN;
124 /* XXX no way to recalculate on ifdetach */
125 if (ALIGN(ifp->if_hdrlen) > max_linkhdr) {
126 /* XXX sanity check... */
127 max_linkhdr = ALIGN(ifp->if_hdrlen);
128 max_hdr = max_linkhdr + max_protohdr;
129 max_datalen = MHLEN - max_hdr;
130 }
131 ic->ic_protmode = IEEE80211_PROT_CTSONLY;
132
133 TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ifp);
134
135 ic->ic_wme.wme_hipri_switch_hysteresis =
136 AGGRESSIVE_MODE_SWITCH_HYSTERESIS;
137
138 /* initialize management frame handlers */
139 ic->ic_send_mgmt = ieee80211_send_mgmt;
140 ic->ic_raw_xmit = null_raw_xmit;
141
142 ieee80211_adhoc_attach(ic);
143 ieee80211_sta_attach(ic);
144 ieee80211_wds_attach(ic);
145 ieee80211_hostap_attach(ic);
146 ieee80211_monitor_attach(ic);
147 }
148
149 void
150 ieee80211_proto_detach(struct ieee80211com *ic)
151 {
152 ieee80211_monitor_detach(ic);
153 ieee80211_hostap_detach(ic);
154 ieee80211_wds_detach(ic);
155 ieee80211_adhoc_detach(ic);
156 ieee80211_sta_detach(ic);
157 }
158
159 static void
160 null_update_beacon(struct ieee80211vap *vap, int item)
161 {
162 }
163
164 void
165 ieee80211_proto_vattach(struct ieee80211vap *vap)
166 {
167 struct ieee80211com *ic = vap->iv_ic;
168 struct ifnet *ifp = vap->iv_ifp;
169 int i;
170
171 /* override the 802.3 setting */
172 ifp->if_hdrlen = ic->ic_ifp->if_hdrlen;
173
174 vap->iv_rtsthreshold = IEEE80211_RTS_DEFAULT;
175 vap->iv_fragthreshold = IEEE80211_FRAG_DEFAULT;
176 vap->iv_bmiss_max = IEEE80211_BMISS_MAX;
177 callout_init(&vap->iv_swbmiss, CALLOUT_MPSAFE);
178 callout_init(&vap->iv_mgtsend, CALLOUT_MPSAFE);
179 /*
180 * Install default tx rate handling: no fixed rate, lowest
181 * supported rate for mgmt and multicast frames. Default
182 * max retry count. These settings can be changed by the
183 * driver and/or user applications.
184 */
185 for (i = IEEE80211_MODE_11A; i < IEEE80211_MODE_11NA; i++) {
186 const struct ieee80211_rateset *rs = &ic->ic_sup_rates[i];
187
188 vap->iv_txparms[i].ucastrate = IEEE80211_FIXED_RATE_NONE;
189 /* NB: we default to min supported rate for channel */
190 vap->iv_txparms[i].mgmtrate =
191 rs->rs_rates[0] & IEEE80211_RATE_VAL;
192 vap->iv_txparms[i].mcastrate =
193 rs->rs_rates[0] & IEEE80211_RATE_VAL;
194 vap->iv_txparms[i].maxretry = IEEE80211_TXMAX_DEFAULT;
195 }
196 for (; i < IEEE80211_MODE_MAX; i++) {
197 vap->iv_txparms[i].ucastrate = IEEE80211_FIXED_RATE_NONE;
198 /* NB: default to MCS 0 */
199 vap->iv_txparms[i].mgmtrate = 0 | 0x80;
200 vap->iv_txparms[i].mcastrate = 0 | 0x80;
201 vap->iv_txparms[i].maxretry = IEEE80211_TXMAX_DEFAULT;
202 }
203 vap->iv_roaming = IEEE80211_ROAMING_AUTO;
204
205 vap->iv_update_beacon = null_update_beacon;
206 vap->iv_deliver_data = ieee80211_deliver_data;
207
208 /* attach support for operating mode */
209 ic->ic_vattach[vap->iv_opmode](vap);
210 }
211
212 void
213 ieee80211_proto_vdetach(struct ieee80211vap *vap)
214 {
215 #define FREEAPPIE(ie) do { \
216 if (ie != NULL) \
217 FREE(ie, M_80211_NODE_IE); \
218 } while (0)
219 /*
220 * Detach operating mode module.
221 */
222 if (vap->iv_opdetach != NULL)
223 vap->iv_opdetach(vap);
224 /*
225 * This should not be needed as we detach when reseting
226 * the state but be conservative here since the
227 * authenticator may do things like spawn kernel threads.
228 */
229 if (vap->iv_auth->ia_detach != NULL)
230 vap->iv_auth->ia_detach(vap);
231 /*
232 * Detach any ACL'ator.
233 */
234 if (vap->iv_acl != NULL)
235 vap->iv_acl->iac_detach(vap);
236
237 FREEAPPIE(vap->iv_appie_beacon);
238 FREEAPPIE(vap->iv_appie_probereq);
239 FREEAPPIE(vap->iv_appie_proberesp);
240 FREEAPPIE(vap->iv_appie_assocreq);
241 FREEAPPIE(vap->iv_appie_assocresp);
242 FREEAPPIE(vap->iv_appie_wpa);
243 #undef FREEAPPIE
244 }
245
246 /*
247 * Simple-minded authenticator module support.
248 */
249
250 #define IEEE80211_AUTH_MAX (IEEE80211_AUTH_WPA+1)
251 /* XXX well-known names */
252 static const char *auth_modnames[IEEE80211_AUTH_MAX] = {
253 "wlan_internal", /* IEEE80211_AUTH_NONE */
254 "wlan_internal", /* IEEE80211_AUTH_OPEN */
255 "wlan_internal", /* IEEE80211_AUTH_SHARED */
256 "wlan_xauth", /* IEEE80211_AUTH_8021X */
257 "wlan_internal", /* IEEE80211_AUTH_AUTO */
258 "wlan_xauth", /* IEEE80211_AUTH_WPA */
259 };
260 static const struct ieee80211_authenticator *authenticators[IEEE80211_AUTH_MAX];
261
262 static const struct ieee80211_authenticator auth_internal = {
263 .ia_name = "wlan_internal",
264 .ia_attach = NULL,
265 .ia_detach = NULL,
266 .ia_node_join = NULL,
267 .ia_node_leave = NULL,
268 };
269
270 /*
271 * Setup internal authenticators once; they are never unregistered.
272 */
273 static void
274 ieee80211_auth_setup(void)
275 {
276 ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal);
277 ieee80211_authenticator_register(IEEE80211_AUTH_SHARED, &auth_internal);
278 ieee80211_authenticator_register(IEEE80211_AUTH_AUTO, &auth_internal);
279 }
280 SYSINIT(wlan_auth, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_auth_setup, NULL);
281
282 const struct ieee80211_authenticator *
283 ieee80211_authenticator_get(int auth)
284 {
285 if (auth >= IEEE80211_AUTH_MAX)
286 return NULL;
287 if (authenticators[auth] == NULL)
288 ieee80211_load_module(auth_modnames[auth]);
289 return authenticators[auth];
290 }
291
292 void
293 ieee80211_authenticator_register(int type,
294 const struct ieee80211_authenticator *auth)
295 {
296 if (type >= IEEE80211_AUTH_MAX)
297 return;
298 authenticators[type] = auth;
299 }
300
301 void
302 ieee80211_authenticator_unregister(int type)
303 {
304
305 if (type >= IEEE80211_AUTH_MAX)
306 return;
307 authenticators[type] = NULL;
308 }
309
310 /*
311 * Very simple-minded ACL module support.
312 */
313 /* XXX just one for now */
314 static const struct ieee80211_aclator *acl = NULL;
315
316 void
317 ieee80211_aclator_register(const struct ieee80211_aclator *iac)
318 {
319 printf("wlan: %s acl policy registered\n", iac->iac_name);
320 acl = iac;
321 }
322
323 void
324 ieee80211_aclator_unregister(const struct ieee80211_aclator *iac)
325 {
326 if (acl == iac)
327 acl = NULL;
328 printf("wlan: %s acl policy unregistered\n", iac->iac_name);
329 }
330
331 const struct ieee80211_aclator *
332 ieee80211_aclator_get(const char *name)
333 {
334 if (acl == NULL)
335 ieee80211_load_module("wlan_acl");
336 return acl != NULL && strcmp(acl->iac_name, name) == 0 ? acl : NULL;
337 }
338
339 void
340 ieee80211_print_essid(const uint8_t *essid, int len)
341 {
342 const uint8_t *p;
343 int i;
344
345 if (len > IEEE80211_NWID_LEN)
346 len = IEEE80211_NWID_LEN;
347 /* determine printable or not */
348 for (i = 0, p = essid; i < len; i++, p++) {
349 if (*p < ' ' || *p > 0x7e)
350 break;
351 }
352 if (i == len) {
353 printf("\"");
354 for (i = 0, p = essid; i < len; i++, p++)
355 printf("%c", *p);
356 printf("\"");
357 } else {
358 printf("0x");
359 for (i = 0, p = essid; i < len; i++, p++)
360 printf("%02x", *p);
361 }
362 }
363
364 void
365 ieee80211_dump_pkt(struct ieee80211com *ic,
366 const uint8_t *buf, int len, int rate, int rssi)
367 {
368 const struct ieee80211_frame *wh;
369 int i;
370
371 wh = (const struct ieee80211_frame *)buf;
372 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
373 case IEEE80211_FC1_DIR_NODS:
374 printf("NODS %s", ether_sprintf(wh->i_addr2));
375 printf("->%s", ether_sprintf(wh->i_addr1));
376 printf("(%s)", ether_sprintf(wh->i_addr3));
377 break;
378 case IEEE80211_FC1_DIR_TODS:
379 printf("TODS %s", ether_sprintf(wh->i_addr2));
380 printf("->%s", ether_sprintf(wh->i_addr3));
381 printf("(%s)", ether_sprintf(wh->i_addr1));
382 break;
383 case IEEE80211_FC1_DIR_FROMDS:
384 printf("FRDS %s", ether_sprintf(wh->i_addr3));
385 printf("->%s", ether_sprintf(wh->i_addr1));
386 printf("(%s)", ether_sprintf(wh->i_addr2));
387 break;
388 case IEEE80211_FC1_DIR_DSTODS:
389 printf("DSDS %s", ether_sprintf((const uint8_t *)&wh[1]));
390 printf("->%s", ether_sprintf(wh->i_addr3));
391 printf("(%s", ether_sprintf(wh->i_addr2));
392 printf("->%s)", ether_sprintf(wh->i_addr1));
393 break;
394 }
395 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
396 case IEEE80211_FC0_TYPE_DATA:
397 printf(" data");
398 break;
399 case IEEE80211_FC0_TYPE_MGT:
400 printf(" %s", ieee80211_mgt_subtype_name[
401 (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
402 >> IEEE80211_FC0_SUBTYPE_SHIFT]);
403 break;
404 default:
405 printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
406 break;
407 }
408 if (IEEE80211_QOS_HAS_SEQ(wh)) {
409 const struct ieee80211_qosframe *qwh =
410 (const struct ieee80211_qosframe *)buf;
411 printf(" QoS [TID %u%s]", qwh->i_qos[0] & IEEE80211_QOS_TID,
412 qwh->i_qos[0] & IEEE80211_QOS_ACKPOLICY ? " ACM" : "");
413 }
414 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
415 int off;
416
417 off = ieee80211_anyhdrspace(ic, wh);
418 printf(" WEP [IV %.02x %.02x %.02x",
419 buf[off+0], buf[off+1], buf[off+2]);
420 if (buf[off+IEEE80211_WEP_IVLEN] & IEEE80211_WEP_EXTIV)
421 printf(" %.02x %.02x %.02x",
422 buf[off+4], buf[off+5], buf[off+6]);
423 printf(" KID %u]", buf[off+IEEE80211_WEP_IVLEN] >> 6);
424 }
425 if (rate >= 0)
426 printf(" %dM", rate / 2);
427 if (rssi >= 0)
428 printf(" +%d", rssi);
429 printf("\n");
430 if (len > 0) {
431 for (i = 0; i < len; i++) {
432 if ((i & 1) == 0)
433 printf(" ");
434 printf("%02x", buf[i]);
435 }
436 printf("\n");
437 }
438 }
439
440 static __inline int
441 findrix(const struct ieee80211_rateset *rs, int r)
442 {
443 int i;
444
445 for (i = 0; i < rs->rs_nrates; i++)
446 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == r)
447 return i;
448 return -1;
449 }
450
451 int
452 ieee80211_fix_rate(struct ieee80211_node *ni,
453 struct ieee80211_rateset *nrs, int flags)
454 {
455 #define RV(v) ((v) & IEEE80211_RATE_VAL)
456 struct ieee80211vap *vap = ni->ni_vap;
457 struct ieee80211com *ic = ni->ni_ic;
458 int i, j, rix, error;
459 int okrate, badrate, fixedrate, ucastrate;
460 const struct ieee80211_rateset *srs;
461 uint8_t r;
462
463 error = 0;
464 okrate = badrate = 0;
465 ucastrate = vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)].ucastrate;
466 if (ucastrate != IEEE80211_FIXED_RATE_NONE) {
467 /*
468 * Workaround awkwardness with fixed rate. We are called
469 * to check both the legacy rate set and the HT rate set
470 * but we must apply any legacy fixed rate check only to the
471 * legacy rate set and vice versa. We cannot tell what type
472 * of rate set we've been given (legacy or HT) but we can
473 * distinguish the fixed rate type (MCS have 0x80 set).
474 * So to deal with this the caller communicates whether to
475 * check MCS or legacy rate using the flags and we use the
476 * type of any fixed rate to avoid applying an MCS to a
477 * legacy rate and vice versa.
478 */
479 if (ucastrate & 0x80) {
480 if (flags & IEEE80211_F_DOFRATE)
481 flags &= ~IEEE80211_F_DOFRATE;
482 } else if ((ucastrate & 0x80) == 0) {
483 if (flags & IEEE80211_F_DOFMCS)
484 flags &= ~IEEE80211_F_DOFMCS;
485 }
486 /* NB: required to make MCS match below work */
487 ucastrate &= IEEE80211_RATE_VAL;
488 }
489 fixedrate = IEEE80211_FIXED_RATE_NONE;
490 /*
491 * XXX we are called to process both MCS and legacy rates;
492 * we must use the appropriate basic rate set or chaos will
493 * ensue; for now callers that want MCS must supply
494 * IEEE80211_F_DOBRS; at some point we'll need to split this
495 * function so there are two variants, one for MCS and one
496 * for legacy rates.
497 */
498 if (flags & IEEE80211_F_DOBRS)
499 srs = (const struct ieee80211_rateset *)
500 ieee80211_get_suphtrates(ic, ni->ni_chan);
501 else
502 srs = ieee80211_get_suprates(ic, ni->ni_chan);
503 for (i = 0; i < nrs->rs_nrates; ) {
504 if (flags & IEEE80211_F_DOSORT) {
505 /*
506 * Sort rates.
507 */
508 for (j = i + 1; j < nrs->rs_nrates; j++) {
509 if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) {
510 r = nrs->rs_rates[i];
511 nrs->rs_rates[i] = nrs->rs_rates[j];
512 nrs->rs_rates[j] = r;
513 }
514 }
515 }
516 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL;
517 badrate = r;
518 /*
519 * Check for fixed rate.
520 */
521 if (r == ucastrate)
522 fixedrate = r;
523 /*
524 * Check against supported rates.
525 */
526 rix = findrix(srs, r);
527 if (flags & IEEE80211_F_DONEGO) {
528 if (rix < 0) {
529 /*
530 * A rate in the node's rate set is not
531 * supported. If this is a basic rate and we
532 * are operating as a STA then this is an error.
533 * Otherwise we just discard/ignore the rate.
534 */
535 if ((flags & IEEE80211_F_JOIN) &&
536 (nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
537 error++;
538 } else if ((flags & IEEE80211_F_JOIN) == 0) {
539 /*
540 * Overwrite with the supported rate
541 * value so any basic rate bit is set.
542 */
543 nrs->rs_rates[i] = srs->rs_rates[rix];
544 }
545 }
546 if ((flags & IEEE80211_F_DODEL) && rix < 0) {
547 /*
548 * Delete unacceptable rates.
549 */
550 nrs->rs_nrates--;
551 for (j = i; j < nrs->rs_nrates; j++)
552 nrs->rs_rates[j] = nrs->rs_rates[j + 1];
553 nrs->rs_rates[j] = 0;
554 continue;
555 }
556 if (rix >= 0)
557 okrate = nrs->rs_rates[i];
558 i++;
559 }
560 if (okrate == 0 || error != 0 ||
561 ((flags & (IEEE80211_F_DOFRATE|IEEE80211_F_DOFMCS)) &&
562 fixedrate != ucastrate)) {
563 IEEE80211_NOTE(vap, IEEE80211_MSG_XRATE | IEEE80211_MSG_11N, ni,
564 "%s: flags 0x%x okrate %d error %d fixedrate 0x%x "
565 "ucastrate %x\n", __func__, fixedrate, ucastrate, flags);
566 return badrate | IEEE80211_RATE_BASIC;
567 } else
568 return RV(okrate);
569 #undef RV
570 }
571
572 /*
573 * Reset 11g-related state.
574 */
575 void
576 ieee80211_reset_erp(struct ieee80211com *ic)
577 {
578 ic->ic_flags &= ~IEEE80211_F_USEPROT;
579 ic->ic_nonerpsta = 0;
580 ic->ic_longslotsta = 0;
581 /*
582 * Short slot time is enabled only when operating in 11g
583 * and not in an IBSS. We must also honor whether or not
584 * the driver is capable of doing it.
585 */
586 ieee80211_set_shortslottime(ic,
587 IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
588 IEEE80211_IS_CHAN_HT(ic->ic_curchan) ||
589 (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) &&
590 ic->ic_opmode == IEEE80211_M_HOSTAP &&
591 (ic->ic_caps & IEEE80211_C_SHSLOT)));
592 /*
593 * Set short preamble and ERP barker-preamble flags.
594 */
595 if (IEEE80211_IS_CHAN_A(ic->ic_curchan) ||
596 (ic->ic_caps & IEEE80211_C_SHPREAMBLE)) {
597 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
598 ic->ic_flags &= ~IEEE80211_F_USEBARKER;
599 } else {
600 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
601 ic->ic_flags |= IEEE80211_F_USEBARKER;
602 }
603 }
604
605 /*
606 * Set the short slot time state and notify the driver.
607 */
608 void
609 ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff)
610 {
611 if (onoff)
612 ic->ic_flags |= IEEE80211_F_SHSLOT;
613 else
614 ic->ic_flags &= ~IEEE80211_F_SHSLOT;
615 /* notify driver */
616 if (ic->ic_updateslot != NULL)
617 ic->ic_updateslot(ic->ic_ifp);
618 }
619
620 /*
621 * Check if the specified rate set supports ERP.
622 * NB: the rate set is assumed to be sorted.
623 */
624 int
625 ieee80211_iserp_rateset(const struct ieee80211_rateset *rs)
626 {
627 #define N(a) (sizeof(a) / sizeof(a[0]))
628 static const int rates[] = { 2, 4, 11, 22, 12, 24, 48 };
629 int i, j;
630
631 if (rs->rs_nrates < N(rates))
632 return 0;
633 for (i = 0; i < N(rates); i++) {
634 for (j = 0; j < rs->rs_nrates; j++) {
635 int r = rs->rs_rates[j] & IEEE80211_RATE_VAL;
636 if (rates[i] == r)
637 goto next;
638 if (r > rates[i])
639 return 0;
640 }
641 return 0;
642 next:
643 ;
644 }
645 return 1;
646 #undef N
647 }
648
649 /*
650 * Mark the basic rates for the rate table based on the
651 * operating mode. For real 11g we mark all the 11b rates
652 * and 6, 12, and 24 OFDM. For 11b compatibility we mark only
653 * 11b rates. There's also a pseudo 11a-mode used to mark only
654 * the basic OFDM rates.
655 */
656 static void
657 setbasicrates(struct ieee80211_rateset *rs,
658 enum ieee80211_phymode mode, int add)
659 {
660 static const struct ieee80211_rateset basic[IEEE80211_MODE_MAX] = {
661 { .rs_nrates = 0 }, /* IEEE80211_MODE_AUTO */
662 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */
663 { 2, { 2, 4 } }, /* IEEE80211_MODE_11B */
664 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11G (mixed b/g) */
665 { .rs_nrates = 0 }, /* IEEE80211_MODE_FH */
666 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_TURBO_A */
667 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_TURBO_G (mixed b/g) */
668 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_STURBO_A */
669 { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11NA */
670 { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11NG (mixed b/g) */
671 };
672 int i, j;
673
674 for (i = 0; i < rs->rs_nrates; i++) {
675 if (!add)
676 rs->rs_rates[i] &= IEEE80211_RATE_VAL;
677 for (j = 0; j < basic[mode].rs_nrates; j++)
678 if (basic[mode].rs_rates[j] == rs->rs_rates[i]) {
679 rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
680 break;
681 }
682 }
683 }
684
685 /*
686 * Set the basic rates in a rate set.
687 */
688 void
689 ieee80211_setbasicrates(struct ieee80211_rateset *rs,
690 enum ieee80211_phymode mode)
691 {
692 setbasicrates(rs, mode, 0);
693 }
694
695 /*
696 * Add basic rates to a rate set.
697 */
698 void
699 ieee80211_addbasicrates(struct ieee80211_rateset *rs,
700 enum ieee80211_phymode mode)
701 {
702 setbasicrates(rs, mode, 1);
703 }
704
705 /*
706 * WME protocol support.
707 *
708 * The default 11a/b/g/n parameters come from the WiFi Alliance WMM
709 * System Interopability Test Plan (v1.4, Appendix F) and the 802.11n
710 * Draft 2.0 Test Plan (Appendix D).
711 *
712 * Static/Dynamic Turbo mode settings come from Atheros.
713 */
714 typedef struct phyParamType {
715 uint8_t aifsn;
716 uint8_t logcwmin;
717 uint8_t logcwmax;
718 uint16_t txopLimit;
719 uint8_t acm;
720 } paramType;
721
722 static const struct phyParamType phyParamForAC_BE[IEEE80211_MODE_MAX] = {
723 { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_AUTO */
724 { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11A */
725 { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11B */
726 { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11G */
727 { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_FH */
728 { 2, 3, 5, 0, 0 }, /* IEEE80211_MODE_TURBO_A */
729 { 2, 3, 5, 0, 0 }, /* IEEE80211_MODE_TURBO_G */
730 { 2, 3, 5, 0, 0 }, /* IEEE80211_MODE_STURBO_A */
731 { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11NA */
732 { 3, 4, 6, 0, 0 }, /* IEEE80211_MODE_11NG */
733 };
734 static const struct phyParamType phyParamForAC_BK[IEEE80211_MODE_MAX] = {
735 { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_AUTO */
736 { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11A */
737 { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11B */
738 { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11G */
739 { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_FH */
740 { 7, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_A */
741 { 7, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_G */
742 { 7, 3, 10, 0, 0 }, /* IEEE80211_MODE_STURBO_A */
743 { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NA */
744 { 7, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NG */
745 };
746 static const struct phyParamType phyParamForAC_VI[IEEE80211_MODE_MAX] = {
747 { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_AUTO */
748 { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11A */
749 { 1, 3, 4, 188, 0 }, /* IEEE80211_MODE_11B */
750 { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11G */
751 { 1, 3, 4, 188, 0 }, /* IEEE80211_MODE_FH */
752 { 1, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_A */
753 { 1, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_G */
754 { 1, 2, 3, 94, 0 }, /* IEEE80211_MODE_STURBO_A */
755 { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NA */
756 { 1, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NG */
757 };
758 static const struct phyParamType phyParamForAC_VO[IEEE80211_MODE_MAX] = {
759 { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_AUTO */
760 { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11A */
761 { 1, 2, 3, 102, 0 }, /* IEEE80211_MODE_11B */
762 { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11G */
763 { 1, 2, 3, 102, 0 }, /* IEEE80211_MODE_FH */
764 { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_A */
765 { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_G */
766 { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_STURBO_A */
767 { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NA */
768 { 1, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NG */
769 };
770
771 static const struct phyParamType bssPhyParamForAC_BE[IEEE80211_MODE_MAX] = {
772 { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_AUTO */
773 { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11A */
774 { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11B */
775 { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11G */
776 { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_FH */
777 { 2, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_A */
778 { 2, 3, 10, 0, 0 }, /* IEEE80211_MODE_TURBO_G */
779 { 2, 3, 10, 0, 0 }, /* IEEE80211_MODE_STURBO_A */
780 { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NA */
781 { 3, 4, 10, 0, 0 }, /* IEEE80211_MODE_11NG */
782 };
783 static const struct phyParamType bssPhyParamForAC_VI[IEEE80211_MODE_MAX] = {
784 { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_AUTO */
785 { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11A */
786 { 2, 3, 4, 188, 0 }, /* IEEE80211_MODE_11B */
787 { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11G */
788 { 2, 3, 4, 188, 0 }, /* IEEE80211_MODE_FH */
789 { 2, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_A */
790 { 2, 2, 3, 94, 0 }, /* IEEE80211_MODE_TURBO_G */
791 { 2, 2, 3, 94, 0 }, /* IEEE80211_MODE_STURBO_A */
792 { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NA */
793 { 2, 3, 4, 94, 0 }, /* IEEE80211_MODE_11NG */
794 };
795 static const struct phyParamType bssPhyParamForAC_VO[IEEE80211_MODE_MAX] = {
796 { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_AUTO */
797 { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11A */
798 { 2, 2, 3, 102, 0 }, /* IEEE80211_MODE_11B */
799 { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11G */
800 { 2, 2, 3, 102, 0 }, /* IEEE80211_MODE_FH */
801 { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_A */
802 { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_TURBO_G */
803 { 1, 2, 2, 47, 0 }, /* IEEE80211_MODE_STURBO_A */
804 { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NA */
805 { 2, 2, 3, 47, 0 }, /* IEEE80211_MODE_11NG */
806 };
807
808 static void
809 ieee80211_wme_initparams_locked(struct ieee80211vap *vap)
810 {
811 struct ieee80211com *ic = vap->iv_ic;
812 struct ieee80211_wme_state *wme = &ic->ic_wme;
813 const paramType *pPhyParam, *pBssPhyParam;
814 struct wmeParams *wmep;
815 enum ieee80211_phymode mode;
816 int i;
817
818 IEEE80211_LOCK_ASSERT(ic);
819
820 if ((ic->ic_caps & IEEE80211_C_WME) == 0)
821 return;
822
823 /*
824 * Select mode; we can be called early in which case we
825 * always use auto mode. We know we'll be called when
826 * entering the RUN state with bsschan setup properly
827 * so state will eventually get set correctly
828 */
829 if (ic->ic_bsschan != IEEE80211_CHAN_ANYC)
830 mode = ieee80211_chan2mode(ic->ic_bsschan);
831 else
832 mode = IEEE80211_MODE_AUTO;
833 for (i = 0; i < WME_NUM_AC; i++) {
834 switch (i) {
835 case WME_AC_BK:
836 pPhyParam = &phyParamForAC_BK[mode];
837 pBssPhyParam = &phyParamForAC_BK[mode];
838 break;
839 case WME_AC_VI:
840 pPhyParam = &phyParamForAC_VI[mode];
841 pBssPhyParam = &bssPhyParamForAC_VI[mode];
842 break;
843 case WME_AC_VO:
844 pPhyParam = &phyParamForAC_VO[mode];
845 pBssPhyParam = &bssPhyParamForAC_VO[mode];
846 break;
847 case WME_AC_BE:
848 default:
849 pPhyParam = &phyParamForAC_BE[mode];
850 pBssPhyParam = &bssPhyParamForAC_BE[mode];
851 break;
852 }
853
854 wmep = &wme->wme_wmeChanParams.cap_wmeParams[i];
855 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
856 wmep->wmep_acm = pPhyParam->acm;
857 wmep->wmep_aifsn = pPhyParam->aifsn;
858 wmep->wmep_logcwmin = pPhyParam->logcwmin;
859 wmep->wmep_logcwmax = pPhyParam->logcwmax;
860 wmep->wmep_txopLimit = pPhyParam->txopLimit;
861 } else {
862 wmep->wmep_acm = pBssPhyParam->acm;
863 wmep->wmep_aifsn = pBssPhyParam->aifsn;
864 wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
865 wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
866 wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
867
868 }
869 IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,
870 "%s: %s chan [acm %u aifsn %u log2(cwmin) %u "
871 "log2(cwmax) %u txpoLimit %u]\n", __func__
872 , ieee80211_wme_acnames[i]
873 , wmep->wmep_acm
874 , wmep->wmep_aifsn
875 , wmep->wmep_logcwmin
876 , wmep->wmep_logcwmax
877 , wmep->wmep_txopLimit
878 );
879
880 wmep = &wme->wme_wmeBssChanParams.cap_wmeParams[i];
881 wmep->wmep_acm = pBssPhyParam->acm;
882 wmep->wmep_aifsn = pBssPhyParam->aifsn;
883 wmep->wmep_logcwmin = pBssPhyParam->logcwmin;
884 wmep->wmep_logcwmax = pBssPhyParam->logcwmax;
885 wmep->wmep_txopLimit = pBssPhyParam->txopLimit;
886 IEEE80211_DPRINTF(vap, IEEE80211_MSG_WME,
887 "%s: %s bss [acm %u aifsn %u log2(cwmin) %u "
888 "log2(cwmax) %u txpoLimit %u]\n", __func__
889 , ieee80211_wme_acnames[i]
890 , wmep->wmep_acm
891 , wmep->wmep_aifsn
892 , wmep->wmep_logcwmin
893 , wmep->wmep_logcwmax
894 , wmep->wmep_txopLimit
895 );
896 }
897 /* NB: check ic_bss to avoid NULL deref on initial attach */
898 if (vap->iv_bss != NULL) {
899 /*
900 * Calculate agressive mode switching threshold based
901 * on beacon interval. This doesn't need locking since
902 * we're only called before entering the RUN state at
903 * which point we start sending beacon frames.
904 */
905 wme->wme_hipri_switch_thresh =
906 (HIGH_PRI_SWITCH_THRESH * vap->iv_bss->ni_intval) / 100;
907 ieee80211_wme_updateparams(vap);
908 }
909 }
910
911 void
912 |