diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 4e38de011a01..a0fae81b5b2f 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -1,4 +1,4 @@ -/* $NetBSD: ieee80211.c,v 1.4 2003/09/23 16:01:21 dyoung Exp $ */ +/* $NetBSD: ieee80211.c,v 1.5 2003/10/13 04:28:35 dyoung Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting @@ -35,7 +35,7 @@ #ifdef __FreeBSD__ __FBSDID("$FreeBSD: src/sys/net80211/ieee80211.c,v 1.7 2003/08/13 22:09:44 sam Exp $"); #else -__KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.4 2003/09/23 16:01:21 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ieee80211.c,v 1.5 2003/10/13 04:28:35 dyoung Exp $"); #endif /* @@ -104,6 +104,7 @@ static const char *ieee80211_phymode_name[] = { "11a", /* IEEE80211_MODE_11A */ "11b", /* IEEE80211_MODE_11B */ "11g", /* IEEE80211_MODE_11G */ + "FH", /* IEEE80211_MODE_FH */ "turbo", /* IEEE80211_MODE_TURBO */ }; @@ -149,6 +150,8 @@ ieee80211_ifattach(struct ifnet *ifp) ic->ic_modecaps |= 1<ic_modecaps |= 1<ic_modecaps |= 1<ic_modecaps |= 1<ic_modecaps & (1<if_baudrate = IF_Mbps(maxrate); + + if (ic->ic_max_aid == 0) + ic->ic_max_aid = IEEE80211_MAX_AID; + #undef ADD } @@ -409,6 +417,9 @@ ieee80211_media_change(struct ifnet *ifp) case IFM_IEEE80211_11G: newphymode = IEEE80211_MODE_11G; break; + case IFM_IEEE80211_FH: + newphymode = IEEE80211_MODE_FH; + break; case IFM_AUTO: newphymode = IEEE80211_MODE_AUTO; break; @@ -579,16 +590,19 @@ ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr) } switch (ic->ic_curmode) { case IEEE80211_MODE_11A: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A); + imr->ifm_active |= IFM_IEEE80211_11A; break; case IEEE80211_MODE_11B: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11B); + imr->ifm_active |= IFM_IEEE80211_11B; break; case IEEE80211_MODE_11G: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11G); + imr->ifm_active |= IFM_IEEE80211_11G; + break; + case IEEE80211_MODE_FH: + imr->ifm_active |= IFM_IEEE80211_FH; break; case IEEE80211_MODE_TURBO: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A) + imr->ifm_active |= IFM_IEEE80211_11A | IFM_IEEE80211_TURBO; break; } @@ -622,6 +636,7 @@ ieee80211_set11gbasicrates(struct ieee80211_rateset *rs, enum ieee80211_phymode { 3, { 12, 24, 48 } }, /* IEEE80211_MODE_11A */ { 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_11B */ { 7, { 2, 4, 11, 22, 12, 24, 48 } },/* IEEE80211_MODE_11G */ + { 0 }, /* IEEE80211_MODE_FH */ { 0 }, /* IEEE80211_MODE_TURBO */ }; int i, j; @@ -651,6 +666,7 @@ ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode) IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */ IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */ + IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */ IEEE80211_CHAN_T, /* IEEE80211_MODE_TURBO */ }; struct ieee80211_channel *c; @@ -715,6 +731,11 @@ ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode) ic->ic_ibss_chan = &ic->ic_channels[i]; break; } + KASSERT(ic->ic_ibss_chan != NULL && + isset(ic->ic_chan_active, + ieee80211_chan2ieee(ic, ic->ic_ibss_chan)), + ("Bad IBSS channel %u\n", + ieee80211_chan2ieee(ic, ic->ic_ibss_chan))); } /* @@ -743,6 +764,8 @@ ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode) * Return the phy mode for with the specified channel so the * caller can select a rate set. This is problematic and the * work here assumes how things work elsewhere in this code. + * + * XXX never returns turbo modes -dcy */ enum ieee80211_phymode ieee80211_chan2mode(struct ieee80211com *ic, struct ieee80211_channel *chan) @@ -760,6 +783,8 @@ ieee80211_chan2mode(struct ieee80211com *ic, struct ieee80211_channel *chan) */ if (IEEE80211_IS_CHAN_5GHZ(chan)) return IEEE80211_MODE_11A; + else if (IEEE80211_IS_CHAN_FHSS(chan)) + return IEEE80211_MODE_FH; else if (chan->ic_flags & (IEEE80211_CHAN_OFDM|IEEE80211_CHAN_DYN)) return IEEE80211_MODE_11G; else @@ -778,31 +803,33 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m u_int m; /* rate + mode */ u_int r; /* if_media rate */ } rates[] = { - { 2 | IFM_MAKEMODE(IFM_IEEE80211_11B), IFM_IEEE80211_DS1 }, - { 4 | IFM_MAKEMODE(IFM_IEEE80211_11B), IFM_IEEE80211_DS2 }, - { 11 | IFM_MAKEMODE(IFM_IEEE80211_11B), IFM_IEEE80211_DS5 }, - { 22 | IFM_MAKEMODE(IFM_IEEE80211_11B), IFM_IEEE80211_DS11 }, - { 44 | IFM_MAKEMODE(IFM_IEEE80211_11B), IFM_IEEE80211_DS22 }, - { 12 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM6 }, - { 18 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM9 }, - { 24 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM12 }, - { 36 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM18 }, - { 48 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM24 }, - { 72 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM36 }, - { 96 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM48 }, - { 108 | IFM_MAKEMODE(IFM_IEEE80211_11A), IFM_IEEE80211_OFDM54 }, - { 2 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_DS1 }, - { 4 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_DS2 }, - { 11 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_DS5 }, - { 22 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_DS11 }, - { 12 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM6 }, - { 18 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM9 }, - { 24 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM12 }, - { 36 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM18 }, - { 48 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM24 }, - { 72 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM36 }, - { 96 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM48 }, - { 108 | IFM_MAKEMODE(IFM_IEEE80211_11G), IFM_IEEE80211_OFDM54 }, + { 2 | IFM_IEEE80211_FH, IFM_IEEE80211_FH1 }, + { 4 | IFM_IEEE80211_FH, IFM_IEEE80211_FH2 }, + { 2 | IFM_IEEE80211_11B, IFM_IEEE80211_DS1 }, + { 4 | IFM_IEEE80211_11B, IFM_IEEE80211_DS2 }, + { 11 | IFM_IEEE80211_11B, IFM_IEEE80211_DS5 }, + { 22 | IFM_IEEE80211_11B, IFM_IEEE80211_DS11 }, + { 44 | IFM_IEEE80211_11B, IFM_IEEE80211_DS22 }, + { 12 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM6 }, + { 18 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM9 }, + { 24 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM12 }, + { 36 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM18 }, + { 48 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM24 }, + { 72 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM36 }, + { 96 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM48 }, + { 108 | IFM_IEEE80211_11A, IFM_IEEE80211_OFDM54 }, + { 2 | IFM_IEEE80211_11G, IFM_IEEE80211_DS1 }, + { 4 | IFM_IEEE80211_11G, IFM_IEEE80211_DS2 }, + { 11 | IFM_IEEE80211_11G, IFM_IEEE80211_DS5 }, + { 22 | IFM_IEEE80211_11G, IFM_IEEE80211_DS11 }, + { 12 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM6 }, + { 18 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM9 }, + { 24 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM12 }, + { 36 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM18 }, + { 48 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM24 }, + { 72 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM36 }, + { 96 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM48 }, + { 108 | IFM_IEEE80211_11G, IFM_IEEE80211_OFDM54 }, /* NB: OFDM72 doesn't realy exist so we don't handle it */ }; u_int mask, i; @@ -811,26 +838,30 @@ ieee80211_rate2media(struct ieee80211com *ic, int rate, enum ieee80211_phymode m switch (mode) { case IEEE80211_MODE_11A: case IEEE80211_MODE_TURBO: - mask |= IFM_MAKEMODE(IFM_IEEE80211_11A); + mask |= IFM_IEEE80211_11A; break; case IEEE80211_MODE_11B: - mask |= IFM_MAKEMODE(IFM_IEEE80211_11B); + mask |= IFM_IEEE80211_11B; + break; + case IEEE80211_MODE_FH: + mask |= IFM_IEEE80211_FH; + break; + case IEEE80211_MODE_11G: + mask |= IFM_IEEE80211_11G; break; case IEEE80211_MODE_AUTO: - /* NB: ic may be NULL for some drivers */ - if (ic && ic->ic_phytype == IEEE80211_T_FH) { - /* must handle these specially */ - switch (mask) { - case 2: return IFM_IEEE80211_FH1; - case 4: return IFM_IEEE80211_FH2; - } - return IFM_AUTO; + switch (ic->ic_phytype) { + case IEEE80211_T_FH: + mask |= IFM_IEEE80211_FH; + break; + case IEEE80211_T_DS: + mask |= IFM_IEEE80211_11B; + break; + case IEEE80211_T_OFDM: + case IEEE80211_T_TURBO: + mask |= IFM_IEEE80211_11G; + break; } - /* NB: hack, 11g matches both 11b+11a rates */ - /* fall thru... */ - case IEEE80211_MODE_11G: - mask |= IFM_MAKEMODE(IFM_IEEE80211_11G); - break; } for (i = 0; i < N(rates); i++) if (rates[i].m == mask) @@ -843,29 +874,36 @@ int ieee80211_media2rate(int mword) { #define N(a) (sizeof(a) / sizeof(a[0])) - static const int ieeerates[] = { - -1, /* IFM_AUTO */ - 0, /* IFM_MANUAL */ - 0, /* IFM_NONE */ - 2, /* IFM_IEEE80211_FH1 */ - 4, /* IFM_IEEE80211_FH2 */ - 2, /* IFM_IEEE80211_DS1 */ - 4, /* IFM_IEEE80211_DS2 */ - 11, /* IFM_IEEE80211_DS5 */ - 22, /* IFM_IEEE80211_DS11 */ - 44, /* IFM_IEEE80211_DS22 */ - 12, /* IFM_IEEE80211_OFDM6 */ - 18, /* IFM_IEEE80211_OFDM9 */ - 24, /* IFM_IEEE80211_OFDM12 */ - 36, /* IFM_IEEE80211_OFDM18 */ - 48, /* IFM_IEEE80211_OFDM24 */ - 72, /* IFM_IEEE80211_OFDM36 */ - 96, /* IFM_IEEE80211_OFDM48 */ - 108, /* IFM_IEEE80211_OFDM54 */ - 144, /* IFM_IEEE80211_OFDM72 */ + int i; + static const struct { + int subtype; + int rate; + } ieeerates[] = { + { IFM_AUTO, -1 }, + { IFM_MANUAL, 0 }, + { IFM_NONE, 0 }, + { IFM_IEEE80211_FH1, 2 }, + { IFM_IEEE80211_FH2, 4 }, + { IFM_IEEE80211_DS1, 2 }, + { IFM_IEEE80211_DS2, 4 }, + { IFM_IEEE80211_DS5, 11 }, + { IFM_IEEE80211_DS11, 22 }, + { IFM_IEEE80211_DS22, 44 }, + { IFM_IEEE80211_OFDM6, 12 }, + { IFM_IEEE80211_OFDM9, 18 }, + { IFM_IEEE80211_OFDM12, 24 }, + { IFM_IEEE80211_OFDM18, 36 }, + { IFM_IEEE80211_OFDM24, 48 }, + { IFM_IEEE80211_OFDM36, 72 }, + { IFM_IEEE80211_OFDM48, 96 }, + { IFM_IEEE80211_OFDM54, 108 }, + { IFM_IEEE80211_OFDM72, 144 }, }; - return IFM_SUBTYPE(mword) < N(ieeerates) ? - ieeerates[IFM_SUBTYPE(mword)] : 0; + for (i = 0; i < N(ieeerates); i++) { + if (ieeerates[i].subtype == IFM_SUBTYPE(mword)) + return ieeerates[i].rate; + } + return 0; #undef N } diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index def3ff1ffb80..7fbc993c9eab 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -1,4 +1,4 @@ -/* $NetBSD: ieee80211.h,v 1.2 2003/09/14 01:14:54 dyoung Exp $ */ +/* $NetBSD: ieee80211.h,v 1.3 2003/10/13 04:28:35 dyoung Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting @@ -52,6 +52,9 @@ struct ieee80211_plcp_hdr { u_int16_t i_crc; } __attribute__((__packed__)); +#define IEEE80211_PLCP_SFD 0xF3A0 +#define IEEE80211_PLCP_SERVICE 0x00 + /* * generic definitions for IEEE 802.11 frames */ @@ -316,6 +319,15 @@ enum { #define IEEE80211_MAX_LEN (2300 + IEEE80211_CRC_LEN + \ (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN)) +#define IEEE80211_MAX_AID 2007 + +#define IEEE80211_AID_SET(b, w) \ + ((w)[((b) & ~0xc000) / 32] |= (1 << (((b) & ~0xc000) % 32))) +#define IEEE80211_AID_CLR(b, w) \ + ((w)[((b) & ~0xc000) / 32] &= ~(1 << (((b) & ~0xc000) % 32))) +#define IEEE80211_AID_ISSET(b, w) \ + ((w)[((b) & ~0xc000) / 32] & (1 << (((b) & ~0xc000) % 32))) + /* * RTS frame length parameters. The default is specified in * the 802.11 spec. The max may be wrong for jumbo frames.