Add support for SIOC[SG]80211BSSID, SIOC[SG]80211CHANNEL.

Change the name of structure ieee80211_bss to ieee80211_node, which is
used for management of stations in hostap mode, and peers in ibss mode.
Split off ic_opmode, ic_phytype from ic_flags.
Preparation to merge 'wi' driver into 80211subr.c.
This commit is contained in:
onoe 2002-09-27 05:36:04 +00:00
parent 23ab1acf02
commit 30d884d47c
3 changed files with 831 additions and 726 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: awi.c,v 1.46 2002/09/03 14:54:00 onoe Exp $ */
/* $NetBSD: awi.c,v 1.47 2002/09/27 05:36:06 onoe Exp $ */
/*-
* Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc.
@ -85,7 +85,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.46 2002/09/03 14:54:00 onoe Exp $");
__KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.47 2002/09/27 05:36:06 onoe Exp $");
#include "opt_inet.h"
#include "bpfilter.h"
@ -235,17 +235,18 @@ awi_attach(struct awi_softc *sc)
memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH)
ic->ic_flags = IEEE80211_F_FH;
ic->ic_phytype = IEEE80211_T_FH;
else
ic->ic_flags = IEEE80211_F_DS;
ic->ic_flags |=
ic->ic_phytype = IEEE80211_T_DS;
ic->ic_flags =
IEEE80211_F_HASWEP | IEEE80211_F_HASIBSS | IEEE80211_F_HASHAP;
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_state = IEEE80211_S_INIT;
ic->ic_newstate = awi_newstate;
ic->ic_chancheck = awi_chan_check;
nrate = sc->sc_mib_phy.aSuprt_Data_Rates[1];
memcpy(ic->ic_sup_rates, sc->sc_mib_phy.aSuprt_Data_Rates + 2, nrate);
memcpy(ic->ic_myaddr, sc->sc_mib_addr.aMAC_Address, IEEE80211_ADDR_LEN);
IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_mib_addr.aMAC_Address);
printf("%s: IEEE802.11 %s %dMbps (firmware %s)\n",
sc->sc_dev.dv_xname,
@ -276,7 +277,7 @@ awi_attach(struct awi_softc *sc)
ADD(IFM_AUTO, IFM_IEEE80211_HOSTAP);
for (i = 0; i < nrate; i++) {
mword = ieee80211_rate2media(ic->ic_sup_rates[i],
(ic->ic_flags & (IEEE80211_F_FH | IEEE80211_F_DS)));
ic->ic_phytype);
if (mword == 0)
continue;
ADD(mword, 0);
@ -468,7 +469,7 @@ awi_init(struct ifnet *ifp)
{
struct awi_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_bss *bs = &ic->ic_bss;
struct ieee80211_node *ni = &ic->ic_bss;
int i, error;
DPRINTF(("awi_init: enabled=%d\n", sc->sc_enabled));
@ -486,9 +487,9 @@ awi_init(struct ifnet *ifp)
ic->ic_state = IEEE80211_S_INIT;
sc->sc_mib_local.Network_Mode =
(ic->ic_flags & IEEE80211_F_ADHOC) ? 0 : 1;
(ic->ic_opmode == IEEE80211_M_ADHOC) ? 0 : 1;
sc->sc_mib_local.Acting_as_AP =
(ic->ic_flags & IEEE80211_F_HOSTAP) ? 1 : 0;
(ic->ic_opmode == IEEE80211_M_HOSTAP) ? 1 : 0;
memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
sc->sc_mib_mac.aDesired_ESS_ID[1] = ic->ic_des_esslen;
@ -533,42 +534,42 @@ awi_init(struct ifnet *ifp)
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
if (((ic->ic_flags & IEEE80211_F_ADHOC) && sc->sc_no_bssid) ||
(ic->ic_flags & IEEE80211_F_HOSTAP)) {
bs->bs_chan = ic->ic_ibss_chan;
bs->bs_intval = ic->ic_lintval;
bs->bs_rssi = 0;
bs->bs_rstamp = 0;
memset(bs->bs_tstamp, 0, sizeof(bs->bs_tstamp));
bs->bs_nrate = 0;
if ((ic->ic_opmode == IEEE80211_M_ADHOC && sc->sc_no_bssid) ||
ic->ic_opmode == IEEE80211_M_HOSTAP) {
ni->ni_chan = ic->ic_ibss_chan;
ni->ni_intval = ic->ic_lintval;
ni->ni_rssi = 0;
ni->ni_rstamp = 0;
memset(ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
ni->ni_nrate = 0;
for (i = 0; i < IEEE80211_RATE_SIZE; i++) {
if (ic->ic_sup_rates[i])
bs->bs_rates[bs->bs_nrate++] =
ni->ni_rates[ni->ni_nrate++] =
ic->ic_sup_rates[i];
}
memcpy(bs->bs_macaddr, ic->ic_myaddr, IEEE80211_ADDR_LEN);
if (ic->ic_flags & IEEE80211_F_HOSTAP) {
memcpy(bs->bs_bssid, ic->ic_myaddr, IEEE80211_ADDR_LEN);
bs->bs_esslen = ic->ic_des_esslen;
memcpy(bs->bs_essid, ic->ic_des_essid, bs->bs_esslen);
bs->bs_capinfo = IEEE80211_CAPINFO_ESS;
if (ic->ic_flags & IEEE80211_F_FH) {
bs->bs_fhdwell = 200; /* XXX */
bs->bs_fhindex = 1;
IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr);
ni->ni_esslen = ic->ic_des_esslen;
memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
ni->ni_capinfo = IEEE80211_CAPINFO_ESS;
if (ic->ic_phytype == IEEE80211_T_FH) {
ni->ni_fhdwell = 200; /* XXX */
ni->ni_fhindex = 1;
}
} else {
bs->bs_capinfo = IEEE80211_CAPINFO_IBSS;
memset(bs->bs_bssid, 0, IEEE80211_ADDR_LEN);
bs->bs_esslen = 0;
ni->ni_capinfo = IEEE80211_CAPINFO_IBSS;
memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN);
ni->ni_esslen = 0;
}
if (ic->ic_flags & IEEE80211_F_WEPON)
bs->bs_capinfo |= IEEE80211_CAPINFO_PRIVACY;
ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
ic->ic_flags |= IEEE80211_F_SIBSS;
ic->ic_state = IEEE80211_S_SCAN; /*XXX*/
sc->sc_substate = AWI_ST_NONE;
ieee80211_new_state(&ic->ic_if, IEEE80211_S_RUN, -1);
} else {
bs->bs_chan = sc->sc_cur_chan;
ni->ni_chan = sc->sc_cur_chan;
ieee80211_new_state(&ic->ic_if, IEEE80211_S_SCAN, -1);
}
return 0;
@ -619,6 +620,7 @@ awi_start(struct ifnet *ifp)
{
struct awi_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct mbuf *m, *m0;
int len, dowep;
u_int32_t txd, frame, ntxd;
@ -675,6 +677,19 @@ awi_start(struct ifnet *ifp)
ifp->if_oerrors++;
continue;
}
wh = mtod(m0, struct ieee80211_frame *);
if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
ic->ic_opmode != IEEE80211_M_STA &&
sc->sc_no_bssid == 0 &&
sc->sc_adhoc_ap == 0 &&
(ifp->if_flags & IFF_LINK0) == 0 &&
(wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
IEEE80211_FC0_TYPE_DATA &&
ieee80211_find_node(ic, wh->i_addr1) == NULL) {
m_freem(m0);
ifp->if_oerrors++;
continue;
}
}
#if NBPFILTER > 0
if (ic->ic_rawbpf)
@ -698,7 +713,7 @@ awi_start(struct ifnet *ifp)
if ((ifp->if_flags & IFF_DEBUG) && (ifp->if_flags & IFF_LINK2))
ieee80211_dump_pkt(m0->m_data, m0->m_len,
ic->ic_bss.bs_rates[ic->ic_bss.bs_txrate] &
ic->ic_bss.ni_rates[ic->ic_bss.ni_txrate] &
IEEE80211_RATE_VAL, -1);
for (m = m0, len = 0; m != NULL; m = m->m_next) {
@ -707,7 +722,7 @@ awi_start(struct ifnet *ifp)
len += m->m_len;
}
m_freem(m0);
rate = (ic->ic_bss.bs_rates[ic->ic_bss.bs_txrate] &
rate = (ic->ic_bss.ni_rates[ic->ic_bss.ni_txrate] &
IEEE80211_RATE_VAL) * 5;
awi_write_1(sc, ntxd + AWI_TXD_STATE, 0);
awi_write_4(sc, txd + AWI_TXD_START, frame);
@ -840,8 +855,7 @@ awi_media_change(struct ifnet *ifp)
if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) {
ic->ic_fixed_rate = -1;
} else {
rate = ieee80211_media2rate(ime->ifm_media,
(ic->ic_flags & (IEEE80211_F_FH | IEEE80211_F_DS)));
rate = ieee80211_media2rate(ime->ifm_media, ic->ic_phytype);
if (rate == 0)
return EINVAL;
for (i = 0; i < IEEE80211_RATE_SIZE; i++) {
@ -854,24 +868,31 @@ awi_media_change(struct ifnet *ifp)
}
/*
* ADHOC,-FLAG0 ADHOC|~HOSTAP, !no_bssid, !adhoc_ap IBSS
* ADHOC, FLAG0 ADHOC|~HOSTAP, no_bssid, !adhoc_ap WaveLAN adhoc
* -ADHOC, FLAG0 ADHOC|~HOSTAP, !no_bssid, adhoc_ap Melco old AP
* also LINK0
* -ADHOC,HOSTAP ~ADHOC|HOSTAP, !no_bssid, !adhoc_ap HostAP
* -ADHOC,-FLAG0 ~ADHOC|~HOSTAP, !no_bssid, !adhoc_ap Infra
* combination of mediaopt
*
* hostap adhoc flag0 opmode no_bssid adhoc_ap comment
* + - - HOSTAP 0 0 HostAP
* - + - ADHOC 0 0 IBSS
* - + + ADHOC 1 0 WaveLAN adhoc
* - - + ADHOC 0 1 Melco old Sta
* also LINK0
* - - - STA 0 0 Infra Station
*/
if (ime->ifm_media & IFM_IEEE80211_ADHOC) {
if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0 ||
(ic->ic_flags & IEEE80211_F_IBSSON) == 0 ||
(ic->ic_flags & IEEE80211_F_HOSTAP) ||
sc->sc_adhoc_ap) {
ic->ic_flags |= IEEE80211_F_ADHOC | IEEE80211_F_IBSSON;
ic->ic_flags &= ~IEEE80211_F_HOSTAP;
if (ime->ifm_media & IFM_IEEE80211_HOSTAP) {
if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
ic->ic_opmode = IEEE80211_M_HOSTAP;
sc->sc_no_bssid = 0;
sc->sc_adhoc_ap = 0;
error = ENETRESET;
}
if (sc->sc_mib_phy.IEEE_PHY_Type != AWI_PHY_TYPE_FH &&
} else if (ime->ifm_media & IFM_IEEE80211_ADHOC) {
if (ic->ic_opmode != IEEE80211_M_ADHOC ||
sc->sc_adhoc_ap != 0) {
ic->ic_opmode = IEEE80211_M_ADHOC;
sc->sc_adhoc_ap = 0;
error = ENETRESET;
}
if (ic->ic_phytype == IEEE80211_T_DS &&
(ime->ifm_media & IFM_FLAG0)) {
if (sc->sc_no_bssid == 0) {
sc->sc_no_bssid = 1;
@ -884,36 +905,16 @@ awi_media_change(struct ifnet *ifp)
}
}
} else if (ime->ifm_media & IFM_FLAG0) {
if ((ic->ic_flags & IEEE80211_F_ADHOC) == 0 ||
(ic->ic_flags & IEEE80211_F_IBSSON) ||
(ic->ic_flags & IEEE80211_F_HOSTAP) ||
sc->sc_no_bssid || !sc->sc_adhoc_ap) {
ic->ic_flags |= IEEE80211_F_ADHOC;
ic->ic_flags &=
~(IEEE80211_F_IBSSON | IEEE80211_F_HOSTAP);
sc->sc_no_bssid = 0;
if (ic->ic_opmode != IEEE80211_M_ADHOC ||
sc->sc_adhoc_ap == 0) {
ic->ic_opmode = IEEE80211_M_ADHOC;
sc->sc_adhoc_ap = 1;
error = ENETRESET;
}
} else if (ime->ifm_media & IFM_IEEE80211_HOSTAP) {
if ((ic->ic_flags & IEEE80211_F_ADHOC) ||
(ic->ic_flags & IEEE80211_F_IBSSON) ||
(ic->ic_flags & IEEE80211_F_HOSTAP) == 0 ||
sc->sc_no_bssid || sc->sc_adhoc_ap) {
ic->ic_flags |= IEEE80211_F_HOSTAP;
ic->ic_flags &=
~(IEEE80211_F_ADHOC | IEEE80211_F_IBSSON);
sc->sc_no_bssid = 0;
sc->sc_adhoc_ap = 0;
error = ENETRESET;
}
} else {
if ((ic->ic_flags & IEEE80211_F_ADHOC) ||
(ic->ic_flags & IEEE80211_F_IBSSON) ||
(ic->ic_flags & IEEE80211_F_HOSTAP) ||
sc->sc_no_bssid || sc->sc_adhoc_ap) {
ic->ic_flags &= ~(IEEE80211_F_ADHOC |
IEEE80211_F_IBSSON | IEEE80211_F_HOSTAP);
if (ic->ic_opmode != IEEE80211_M_STA) {
ic->ic_opmode = IEEE80211_M_STA;
sc->sc_no_bssid = 0;
sc->sc_adhoc_ap = 0;
error = ENETRESET;
@ -940,7 +941,7 @@ awi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
imr->ifm_status |= IFM_ACTIVE;
imr->ifm_active = IFM_IEEE80211;
if (ic->ic_state == IEEE80211_S_RUN)
rate = ic->ic_bss.bs_rates[ic->ic_bss.bs_txrate] &
rate = ic->ic_bss.ni_rates[ic->ic_bss.ni_txrate] &
IEEE80211_RATE_VAL;
else {
if (ic->ic_fixed_rate == -1)
@ -949,11 +950,11 @@ awi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
rate = ic->ic_sup_rates[ic->ic_fixed_rate] &
IEEE80211_RATE_VAL;
}
imr->ifm_active |= ieee80211_rate2media(rate,
(ic->ic_flags & (IEEE80211_F_FH | IEEE80211_F_DS)));
if (ic->ic_flags & IEEE80211_F_HOSTAP)
imr->ifm_active |= IFM_IEEE80211_HOSTAP;
else if (ic->ic_flags & IEEE80211_F_ADHOC) {
imr->ifm_active |= ieee80211_rate2media(rate, ic->ic_phytype);
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
break;
case IEEE80211_M_ADHOC:
if (sc->sc_adhoc_ap)
imr->ifm_active |= IFM_FLAG0;
else {
@ -961,6 +962,10 @@ awi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
if (sc->sc_no_bssid)
imr->ifm_active |= IFM_FLAG0;
}
break;
case IEEE80211_M_HOSTAP:
imr->ifm_active |= IFM_IEEE80211_HOSTAP;
break;
}
}
@ -975,7 +980,7 @@ awi_mode_init(struct awi_softc *sc)
/* reinitialize muticast filter */
n = 0;
sc->sc_mib_local.Accept_All_Multicast_Dis = 0;
if ((sc->sc_ic.ic_flags & IEEE80211_F_HOSTAP) == 0 &&
if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP &&
(ifp->if_flags & IFF_PROMISC)) {
sc->sc_mib_mac.aPromiscuous_Enable = 1;
goto set_mib;
@ -984,16 +989,16 @@ awi_mode_init(struct awi_softc *sc)
ETHER_FIRST_MULTI(step, &sc->sc_ic.ic_ec, enm);
while (enm != NULL) {
if (n == AWI_GROUP_ADDR_SIZE ||
memcmp(enm->enm_addrlo, enm->enm_addrhi, IEEE80211_ADDR_LEN)
!= 0)
!IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi))
goto set_mib;
memcpy(sc->sc_mib_addr.aGroup_Addresses[n], enm->enm_addrlo,
IEEE80211_ADDR_LEN);
IEEE80211_ADDR_COPY(sc->sc_mib_addr.aGroup_Addresses[n],
enm->enm_addrlo);
n++;
ETHER_NEXT_MULTI(step, enm);
}
for (; n < AWI_GROUP_ADDR_SIZE; n++)
memset(sc->sc_mib_addr.aGroup_Addresses[n], 0, IEEE80211_ADDR_LEN);
memset(sc->sc_mib_addr.aGroup_Addresses[n], 0,
IEEE80211_ADDR_LEN);
sc->sc_mib_local.Accept_All_Multicast_Dis = 1;
set_mib:
@ -1386,7 +1391,7 @@ awi_chan_check(void *arg, u_char *chanreq)
cs->cs_region;
memcpy(sc->sc_ic.ic_chan_avail, chanlist,
sizeof(sc->sc_ic.ic_chan_avail));
sc->sc_ic.ic_bss.bs_chan = cs->cs_def;
sc->sc_ic.ic_bss.ni_chan = cs->cs_def;
sc->sc_cur_chan = cs->cs_def;
return 0;
}
@ -1692,7 +1697,7 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
{
struct awi_softc *sc = arg;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_bss *bs = &ic->ic_bss;
struct ieee80211_node *ni;
struct ifnet *ifp = &ic->ic_if;
int error;
u_int8_t newmode;
@ -1715,7 +1720,7 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
awi_drvstate(sc, AWI_DRV_RESET);
break;
case IEEE80211_S_SCAN:
if (ic->ic_flags & IEEE80211_F_ADHOC)
if (ic->ic_opmode == IEEE80211_M_ADHOC)
awi_drvstate(sc, AWI_DRV_ADHSC);
else
awi_drvstate(sc, AWI_DRV_INFSY);
@ -1727,7 +1732,7 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
awi_drvstate(sc, AWI_DRV_INFAUTH);
break;
case IEEE80211_S_RUN:
if (ic->ic_flags & IEEE80211_F_ADHOC)
if (ic->ic_opmode == IEEE80211_M_ADHOC)
awi_drvstate(sc, AWI_DRV_ADHSY);
else
awi_drvstate(sc, AWI_DRV_INFASSOC);
@ -1757,12 +1762,13 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
printf("%s: no recent beacons from %s;"
" rescanning\n",
ifp->if_xname,
ether_sprintf(ic->ic_bss.bs_bssid));
ether_sprintf(ic->ic_bss.ni_bssid));
/* FALLTHRU */
case IEEE80211_S_AUTH:
case IEEE80211_S_ASSOC:
/* timeout restart scan */
ieee80211_free_scan(ifp);
while ((ni = TAILQ_FIRST(&ic->ic_node)) != NULL)
ieee80211_free_node(ic, ni);
/* FALLTHRU */
case IEEE80211_S_INIT:
ic->ic_flags |= IEEE80211_F_ASCAN;
@ -1790,22 +1796,23 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
break;
}
sc->sc_cmd_inprog = AWI_CMD_SCAN;
ni = &ic->ic_bss;
awi_write_2(sc, AWI_CA_SCAN_DURATION,
(ic->ic_flags & IEEE80211_F_ASCAN) ?
AWI_ASCAN_DURATION : AWI_PSCAN_DURATION);
if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
awi_write_1(sc, AWI_CA_SCAN_SET,
IEEE80211_FH_CHANSET(bs->bs_chan));
IEEE80211_FH_CHANSET(ni->ni_chan));
awi_write_1(sc, AWI_CA_SCAN_PATTERN,
IEEE80211_FH_CHANPAT(bs->bs_chan));
IEEE80211_FH_CHANPAT(ni->ni_chan));
awi_write_1(sc, AWI_CA_SCAN_IDX, 1);
} else {
awi_write_1(sc, AWI_CA_SCAN_SET, bs->bs_chan);
awi_write_1(sc, AWI_CA_SCAN_SET, ni->ni_chan);
awi_write_1(sc, AWI_CA_SCAN_PATTERN, 0);
awi_write_1(sc, AWI_CA_SCAN_IDX, 0);
}
awi_write_1(sc, AWI_CA_SCAN_SUSP, 0);
sc->sc_cur_chan = bs->bs_chan;
sc->sc_cur_chan = ni->ni_chan;
if ((error = awi_cmd(sc, AWI_CMD_SCAN, AWI_NOWAIT))
!= 0)
break;
@ -1837,20 +1844,21 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
sc->sc_nstate = nstate; /* next state in transition */
sc->sc_substate = AWI_ST_SUB_INIT;
}
ni = &ic->ic_bss;
switch (sc->sc_substate) {
case AWI_ST_SUB_INIT:
sc->sc_substate = AWI_ST_SUB_SETSS;
memcpy(&sc->sc_mib_mgt.aCurrent_BSS_ID, bs->bs_bssid,
IEEE80211_ADDR_LEN);
IEEE80211_ADDR_COPY(&sc->sc_mib_mgt.aCurrent_BSS_ID,
ni->ni_bssid);
memset(&sc->sc_mib_mgt.aCurrent_ESS_ID, 0,
AWI_ESS_ID_SIZE);
sc->sc_mib_mgt.aCurrent_ESS_ID[0] =
IEEE80211_ELEMID_SSID;
sc->sc_mib_mgt.aCurrent_ESS_ID[1] = bs->bs_esslen;
sc->sc_mib_mgt.aCurrent_ESS_ID[1] = ni->ni_esslen;
memcpy(&sc->sc_mib_mgt.aCurrent_ESS_ID[2],
bs->bs_essid, bs->bs_esslen);
ni->ni_essid, ni->ni_esslen);
LE_WRITE_2(&sc->sc_mib_mgt.aBeacon_Period,
bs->bs_intval);
ni->ni_intval);
if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT,
AWI_NOWAIT)) != 0)
break;
@ -1864,15 +1872,15 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
sc->sc_cmd_inprog = AWI_CMD_SYNC;
if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
awi_write_1(sc, AWI_CA_SYNC_SET,
IEEE80211_FH_CHANSET(bs->bs_chan));
IEEE80211_FH_CHANSET(ni->ni_chan));
awi_write_1(sc, AWI_CA_SYNC_PATTERN,
IEEE80211_FH_CHANPAT(bs->bs_chan));
IEEE80211_FH_CHANPAT(ni->ni_chan));
awi_write_1(sc, AWI_CA_SYNC_IDX,
bs->bs_fhindex);
ni->ni_fhindex);
awi_write_2(sc, AWI_CA_SYNC_DWELL,
bs->bs_fhdwell);
ni->ni_fhdwell);
} else {
awi_write_1(sc, AWI_CA_SYNC_SET, bs->bs_chan);
awi_write_1(sc, AWI_CA_SYNC_SET, ni->ni_chan);
awi_write_1(sc, AWI_CA_SYNC_PATTERN, 0);
awi_write_1(sc, AWI_CA_SYNC_IDX, 0);
awi_write_2(sc, AWI_CA_SYNC_DWELL, 0);
@ -1884,9 +1892,9 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
awi_write_1(sc, AWI_CA_SYNC_STARTBSS, 0);
awi_write_2(sc, AWI_CA_SYNC_MBZ, 0);
awi_write_bytes(sc, AWI_CA_SYNC_TIMESTAMP,
bs->bs_tstamp, 8);
awi_write_4(sc, AWI_CA_SYNC_REFTIME, bs->bs_rstamp);
sc->sc_cur_chan = bs->bs_chan;
ni->ni_tstamp, 8);
awi_write_4(sc, AWI_CA_SYNC_REFTIME, ni->ni_rstamp);
sc->sc_cur_chan = ni->ni_chan;
if ((error = awi_cmd(sc, AWI_CMD_SYNC, AWI_NOWAIT))
!= 0)
break;
@ -1897,9 +1905,8 @@ awi_newstate(void *arg, enum ieee80211_state nstate)
if ((error = awi_mib(sc, AWI_CMD_GET_MIB,
AWI_MIB_MGT, AWI_WAIT)) != 0)
break;
memcpy(bs->bs_bssid,
&sc->sc_mib_mgt.aCurrent_BSS_ID,
IEEE80211_ADDR_LEN);
IEEE80211_ADDR_COPY(ni->ni_bssid,
&sc->sc_mib_mgt.aCurrent_BSS_ID);
} else {
if (nstate == IEEE80211_S_RUN) {
sc->sc_rx_timer = 10;
@ -1927,7 +1934,7 @@ static struct mbuf *
awi_ether_encap(struct awi_softc *sc, struct mbuf *m)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_bss *bs = &ic->ic_bss;
struct ieee80211_node *ni = &ic->ic_bss;
struct ether_header *eh;
struct ieee80211_frame *wh;
@ -1944,22 +1951,21 @@ awi_ether_encap(struct awi_softc *sc, struct mbuf *m)
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
*(u_int16_t *)wh->i_dur = 0;
*(u_int16_t *)wh->i_seq =
htole16(bs->bs_txseq << IEEE80211_SEQ_SEQ_SHIFT);
bs->bs_txseq++;
if (ic->ic_flags & IEEE80211_F_ADHOC) {
htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
ni->ni_txseq++;
if (ic->ic_opmode == IEEE80211_M_ADHOC) {
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
if (sc->sc_adhoc_ap)
memcpy(wh->i_addr1, bs->bs_macaddr, IEEE80211_ADDR_LEN);
IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
else
memcpy(wh->i_addr1, eh->ether_dhost,
IEEE80211_ADDR_LEN);
memcpy(wh->i_addr2, eh->ether_shost, IEEE80211_ADDR_LEN);
memcpy(wh->i_addr3, bs->bs_bssid, IEEE80211_ADDR_LEN);
IEEE80211_ADDR_COPY(wh->i_addr1, eh->ether_dhost);
IEEE80211_ADDR_COPY(wh->i_addr2, eh->ether_shost);
IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
} else {
wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
memcpy(wh->i_addr1, bs->bs_bssid, IEEE80211_ADDR_LEN);
memcpy(wh->i_addr2, eh->ether_shost, IEEE80211_ADDR_LEN);
memcpy(wh->i_addr3, eh->ether_dhost, IEEE80211_ADDR_LEN);
IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid);
IEEE80211_ADDR_COPY(wh->i_addr2, eh->ether_shost);
IEEE80211_ADDR_COPY(wh->i_addr3, eh->ether_dhost);
}
return m;
}
@ -1982,8 +1988,8 @@ awi_ether_modcap(struct awi_softc *sc, struct mbuf *m)
return m;
memcpy(&eh, mtod(m, caddr_t) + sizeof(wh), sizeof(eh));
m_adj(m, sizeof(eh) - sizeof(*llc));
if (ic->ic_flags & IEEE80211_F_ADHOC)
memcpy(wh.i_addr2, eh.ether_shost, IEEE80211_ADDR_LEN);
if (ic->ic_opmode == IEEE80211_M_ADHOC)
IEEE80211_ADDR_COPY(wh.i_addr2, eh.ether_shost);
memcpy(mtod(m, caddr_t), &wh, sizeof(wh));
llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh));
llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ieee80211.h,v 1.19 2002/09/22 01:56:08 thorpej Exp $ */
/* $NetBSD: if_ieee80211.h,v 1.20 2002/09/27 05:36:04 onoe Exp $ */
/*-
* Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@ -361,6 +361,18 @@ struct ieee80211_bssid {
#define IEEE80211_RATE_SIZE 12
#define IEEE80211_KEYBUF_SIZE 16
enum ieee80211_phytype {
IEEE80211_T_DS,
IEEE80211_T_FH,
IEEE80211_T_OFDM
};
enum ieee80211_opmode {
IEEE80211_M_STA = 1, /* infrastructure station */
IEEE80211_M_ADHOC = 0, /* IBSS (adhoc) station */
IEEE80211_M_HOSTAP = 6 /* Software Access Point */
};
enum ieee80211_state {
IEEE80211_S_INIT, /* default state */
IEEE80211_S_SCAN, /* scanning */
@ -372,40 +384,40 @@ enum ieee80211_state {
/*
* Node specific information.
*/
struct ieee80211_bss {
TAILQ_ENTRY(ieee80211_bss) bs_list;
struct ieee80211_node {
TAILQ_ENTRY(ieee80211_node) ni_list;
/* hardware */
u_int8_t bs_rssi;
u_int32_t bs_rstamp;
u_int8_t ni_rssi;
u_int32_t ni_rstamp;
/* header */
u_int8_t bs_macaddr[IEEE80211_ADDR_LEN];
u_int8_t bs_bssid[IEEE80211_ADDR_LEN];
u_int8_t ni_macaddr[IEEE80211_ADDR_LEN];
u_int8_t ni_bssid[IEEE80211_ADDR_LEN];
/* beacon, probe response */
u_int8_t bs_tstamp[8];
u_int16_t bs_intval;
u_int16_t bs_capinfo;
u_int8_t bs_esslen;
u_int8_t bs_essid[IEEE80211_NWID_LEN];
int bs_nrate;
u_int8_t bs_rates[IEEE80211_RATE_SIZE];
u_int8_t bs_chan;
u_int16_t bs_fhdwell; /* FH only */
u_int8_t bs_fhindex; /* FH only */
u_int8_t ni_tstamp[8];
u_int16_t ni_intval;
u_int16_t ni_capinfo;
u_int8_t ni_esslen;
u_int8_t ni_essid[IEEE80211_NWID_LEN];
int ni_nrate;
u_int8_t ni_rates[IEEE80211_RATE_SIZE];
u_int8_t ni_chan;
u_int16_t ni_fhdwell; /* FH only */
u_int8_t ni_fhindex; /* FH only */
/* others */
u_int16_t bs_associd; /* assoc response */
u_int16_t bs_txseq; /* seq to be transmitted */
u_int16_t bs_rxseq; /* seq previous received */
int bs_fails; /* failure count to associate */
int bs_inact; /* inactivity mark count */
int bs_txrate; /* index to bs_rates[] */
void *bs_private; /* driver private */
u_int16_t ni_associd; /* assoc response */
u_int16_t ni_txseq; /* seq to be transmitted */
u_int16_t ni_rxseq; /* seq previous received */
int ni_fails; /* failure count to associate */
int ni_inact; /* inactivity mark count */
int ni_txrate; /* index to ni_rates[] */
void *ni_private; /* driver private */
};
/* bs_chan encoding for FH phy */
/* ni_chan encoding for FH phy */
#define IEEE80211_FH_CHANMOD 80
#define IEEE80211_FH_CHAN(set,pat) (((set)-1)*IEEE80211_FH_CHANMOD+(pat))
#define IEEE80211_FH_CHANSET(chan) ((chan)/IEEE80211_FH_CHANMOD+1)
@ -421,7 +433,7 @@ struct ieee80211com {
void (*ic_recv_mgmt[16])(struct ieee80211com *,
struct mbuf *, int, u_int32_t);
int (*ic_send_mgmt[16])(struct ieee80211com *,
struct ieee80211_bss *, int, int);
struct ieee80211_node *, int, int);
int (*ic_newstate)(void *, enum ieee80211_state);
int (*ic_chancheck)(void *, u_char *);
u_int8_t ic_myaddr[IEEE80211_ADDR_LEN];
@ -430,19 +442,23 @@ struct ieee80211com {
u_char ic_chan_active[roundup(IEEE80211_CHAN_MAX, NBBY)];
struct ifqueue ic_mgtq;
int ic_flags;
enum ieee80211_phytype ic_phytype;
enum ieee80211_opmode ic_opmode;
enum ieee80211_state ic_state;
caddr_t ic_rawbpf; /* packet filter structure */
struct ieee80211_bss ic_bss; /* information for this node */
int ic_bss_privlen; /* size for bs_private */
struct ieee80211_node ic_bss; /* information for this node */
int ic_bss_privlen; /* size for ni_private */
u_int8_t ic_ibss_chan;
int ic_fixed_rate; /* index to ic_sup_rates[] */
TAILQ_HEAD(, ieee80211_bss) ic_scan; /* information of all nodes */
TAILQ_HEAD(, ieee80211_node) ic_node; /* information of all nodes */
u_int16_t ic_lintval; /* listen interval */
int ic_mgt_timer; /* mgmt timeout */
int ic_scan_timer; /* scant wait */
int ic_inact_timer; /* inactivity timer wait */
int ic_des_esslen;
u_int8_t ic_des_essid[IEEE80211_NWID_LEN];
int ic_des_chan; /* desired channel */
u_int8_t ic_des_bssid[IEEE80211_ADDR_LEN];
struct ieee80211_wepkey ic_nw_keys[IEEE80211_WEP_NKID];
int ic_wep_txkey; /* default tx key index */
void *ic_wep_ctx;
@ -450,28 +466,29 @@ struct ieee80211com {
#define ic_if ic_ec.ec_if
#define ic_softc ic_ec.ec_if.if_softc
#define IEEE80211_SEND_MGMT(ic,bs,type,arg) do { \
#define IEEE80211_SEND_MGMT(ic,ni,type,arg) do { \
if ((ic)->ic_send_mgmt[(type)>>IEEE80211_FC0_SUBTYPE_SHIFT] != NULL) \
(*(ic)->ic_send_mgmt[(type)>>IEEE80211_FC0_SUBTYPE_SHIFT]) \
(ic,bs,type,arg); \
(ic,ni,type,arg); \
} while (0)
#define IEEE80211_ADDR_EQ(a1,a2) (memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0)
#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN)
#define IEEE80211_IS_MULTICAST(a) ETHER_IS_MULTICAST(a)
/* ic_flags */
#define IEEE80211_F_ASCAN 0x00000001 /* STATUS: active scan */
#define IEEE80211_F_SIBSS 0x00000002 /* STATUS: start IBSS */
#define IEEE80211_F_WEPON 0x00000100 /* CONF: WEP enabled */
#define IEEE80211_F_IBSSON 0x00000200 /* CONF: IBSS creation enable */
#define IEEE80211_F_PMGTON 0x00000400 /* CONF: Power mgmt enable */
#define IEEE80211_F_ADHOC 0x00000800 /* CONF: adhoc mode */
#define IEEE80211_F_SCANAP 0x00001000 /* CONF: scan AP mode */
#define IEEE80211_F_HOSTAP 0x00002000 /* CONF: AP mode */
#define IEEE80211_F_DESBSSID 0x00000800 /* CONF: des_bssid is set */
#define IEEE80211_F_SCANAP 0x00001000 /* CONF: Scanning AP */
#define IEEE80211_F_HASWEP 0x00010000 /* CAPABILITY: WEP available */
#define IEEE80211_F_HASIBSS 0x00020000 /* CAPABILITY: IBSS available */
#define IEEE80211_F_HASPMGT 0x00040000 /* CAPABILITY: Power mgmt */
#define IEEE80211_F_HASHAP 0x00080000 /* CAPABILITY: HOSTAP avail */
#define IEEE80211_F_FH 0x01000000 /* PHY: FH */
#define IEEE80211_F_DS 0x02000000 /* PHY: DS */
#define IEEE80211_F_OFDM 0x04000000 /* PHY: OFDM */
/* flags for ieee80211_fix_rate() */
#define IEEE80211_F_DOSORT 0x00000001 /* sort rate list */
@ -482,7 +499,7 @@ struct ieee80211com {
void ieee80211_ifattach(struct ifnet *);
void ieee80211_ifdetach(struct ifnet *);
void ieee80211_input(struct ifnet *, struct mbuf *, int, u_int32_t);
int ieee80211_mgmt_output(struct ifnet *, struct ieee80211_bss *,
int ieee80211_mgmt_output(struct ifnet *, struct ieee80211_node *,
struct mbuf *, int);
struct mbuf *ieee80211_encap(struct ifnet *, struct mbuf *);
struct mbuf *ieee80211_decap(struct ifnet *, struct mbuf *);
@ -492,13 +509,14 @@ void ieee80211_dump_pkt(u_int8_t *, int, int, int);
void ieee80211_watchdog(struct ifnet *);
void ieee80211_next_scan(struct ifnet *);
void ieee80211_end_scan(struct ifnet *);
struct ieee80211_bss *ieee80211_alloc_bss(struct ieee80211com *, int);
void ieee80211_free_scan(struct ifnet *);
int ieee80211_fix_rate(struct ieee80211com *, struct ieee80211_bss *, int);
struct ieee80211_node *ieee80211_alloc_node(struct ieee80211com *, int);
struct ieee80211_node *ieee80211_find_node(struct ieee80211com *, u_int8_t *);
void ieee80211_free_node(struct ieee80211com *, struct ieee80211_node *);
int ieee80211_fix_rate(struct ieee80211com *, struct ieee80211_node *, int);
int ieee80211_new_state(struct ifnet *, enum ieee80211_state, int);
struct mbuf *ieee80211_wep_crypt(struct ifnet *, struct mbuf *, int);
int ieee80211_rate2media(int, int);
int ieee80211_media2rate(int, int);
int ieee80211_rate2media(int, enum ieee80211_phytype);
int ieee80211_media2rate(int, enum ieee80211_phytype);
int ieee80211_cfgget(struct ifnet *, u_long, caddr_t);
int ieee80211_cfgset(struct ifnet *, u_long, caddr_t);

File diff suppressed because it is too large Load Diff