More changes to the new 802.11 layer:

* Add Kevin Lahey's power-saving support from the old 802.11 layer

* Support for frequency-hopping PHYs

    * Add support frequency-hopping PHY mode, IFM_IEEE80211_FH
    * Add channel flags for frequency-hopping
    * Add mode<->media mappings in for FH PHY in ieee80211_media2rate
      and ieee80211_rate2media

* Stop using IFM_MAKEMODE macro since the mode constants
  (e.g., IFM_IEEE80211_11A) are pre-shifted in sys/net/if_media.h

* Add some PLCP constants.
This commit is contained in:
dyoung 2003-10-13 04:28:35 +00:00
parent 60dad7c3fe
commit 8a3890c655
2 changed files with 123 additions and 73 deletions

View File

@ -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<<IEEE80211_MODE_11B;
if (IEEE80211_IS_CHAN_PUREG(c))
ic->ic_modecaps |= 1<<IEEE80211_MODE_11G;
if (IEEE80211_IS_CHAN_FHSS(c))
ic->ic_modecaps |= 1<<IEEE80211_MODE_FH;
if (IEEE80211_IS_CHAN_T(c))
ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO;
}
@ -290,10 +293,11 @@ ieee80211_media_init(struct ifnet *ifp,
for (mode = IEEE80211_MODE_AUTO; mode < IEEE80211_MODE_MAX; mode++) {
static const u_int mopts[] = {
IFM_AUTO,
IFM_MAKEMODE(IFM_IEEE80211_11A),
IFM_MAKEMODE(IFM_IEEE80211_11B),
IFM_MAKEMODE(IFM_IEEE80211_11G),
IFM_MAKEMODE(IFM_IEEE80211_11A) | IFM_IEEE80211_TURBO,
IFM_IEEE80211_11A,
IFM_IEEE80211_11B,
IFM_IEEE80211_11G,
IFM_IEEE80211_FH,
IFM_IEEE80211_11A | IFM_IEEE80211_TURBO,
};
if ((ic->ic_modecaps & (1<<mode)) == 0)
continue;
@ -367,6 +371,10 @@ ieee80211_media_init(struct ifnet *ifp,
if (maxrate)
ifp->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
}

View File

@ -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.