summaryrefslogtreecommitdiffstats
path: root/sys/dev/if_ndis/if_ndis.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/if_ndis/if_ndis.c')
-rw-r--r--sys/dev/if_ndis/if_ndis.c549
1 files changed, 221 insertions, 328 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index c44ed53..896ddb3 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -133,16 +133,21 @@ static funcptr ndis_starttask_wrap;
static funcptr ndis_resettask_wrap;
static funcptr ndis_inputtask_wrap;
+static struct ieee80211vap *ndis_vap_create(struct ieee80211com *,
+ const char name[IFNAMSIZ], int unit, int opmode,
+ int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
+ const uint8_t mac[IEEE80211_ADDR_LEN]);
+static void ndis_vap_delete (struct ieee80211vap *);
static void ndis_tick (void *);
static void ndis_ticktask (device_object *, void *);
+static int ndis_raw_xmit (struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_bpf_params *);
static void ndis_start (struct ifnet *);
static void ndis_starttask (device_object *, void *);
static void ndis_resettask (device_object *, void *);
static void ndis_inputtask (device_object *, void *);
static int ndis_ioctl (struct ifnet *, u_long, caddr_t);
-static int ndis_80211_ioctl_get (struct ifnet *, u_long, caddr_t);
-static int ndis_80211_ioctl_set (struct ifnet *, u_long, caddr_t);
-static int ndis_newstate (struct ieee80211com *, enum ieee80211_state,
+static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state,
int);
static int ndis_nettype_chan (uint32_t);
static int ndis_nettype_mode (uint32_t);
@@ -151,8 +156,8 @@ static void ndis_scan_results (struct ndis_softc *);
static void ndis_scan_start (struct ieee80211com *);
static void ndis_scan_end (struct ieee80211com *);
static void ndis_set_channel (struct ieee80211com *);
-static void ndis_scan_curchan (struct ieee80211com *, unsigned long);
-static void ndis_scan_mindwell (struct ieee80211com *);
+static void ndis_scan_curchan (struct ieee80211_scan_state *, unsigned long);
+static void ndis_scan_mindwell (struct ieee80211_scan_state *);
static void ndis_init (void *);
static void ndis_stop (struct ndis_softc *);
static void ndis_watchdog (struct ifnet *);
@@ -164,12 +169,11 @@ static int ndis_set_offload (struct ndis_softc *);
static void ndis_getstate_80211 (struct ndis_softc *);
static void ndis_setstate_80211 (struct ndis_softc *);
static int ndis_set_cipher (struct ndis_softc *, int);
-static int ndis_set_wpa (struct ndis_softc *);
-static int ndis_add_key (struct ieee80211com *,
+static int ndis_set_wpa (struct ndis_softc *, void *, int);
+static int ndis_add_key (struct ieee80211vap *,
const struct ieee80211_key *, const u_int8_t []);
-static int ndis_del_key (struct ieee80211com *,
+static int ndis_del_key (struct ieee80211vap *,
const struct ieee80211_key *);
-static void ndis_media_status (struct ifnet *, struct ifmediareq *);
static void ndis_setmulti (struct ndis_softc *);
static void ndis_map_sclist (void *, bus_dma_segment_t *,
@@ -520,16 +524,11 @@ ndis_attach(dev)
driver_object *pdrv;
device_object *pdo;
struct ifnet *ifp = NULL;
- int error = 0, len, mode, bands = 0;
+ int error = 0, len, mode;
+ uint8_t bands = 0;
int i;
sc = device_get_softc(dev);
- ifp = sc->ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- error = ENOSPC;
- goto fail;
- }
- ifp->if_softc = sc;
KeInitializeSpinLock(&sc->ndis_spinlock);
KeInitializeSpinLock(&sc->ndis_rxlock);
@@ -598,10 +597,6 @@ ndis_attach(dev)
sc->ndis_inputitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj);
KeInitializeDpc(&sc->ndis_rxdpc, ndis_rxeof_xfr_wrap, sc->ndis_block);
- /* make sure drv flags are all cleared before initing the NIC. */
-
- ifp->if_drv_flags = 0;
-
/* Call driver's init routine. */
if (ndis_init_nic(sc)) {
device_printf (dev, "init handler failed\n");
@@ -677,6 +672,17 @@ ndis_attach(dev)
}
}
+ if (sc->ndis_80211)
+ ifp = if_alloc(IFT_IEEE80211);
+ else
+ ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL) {
+ error = ENOSPC;
+ goto fail;
+ }
+ sc->ifp = ifp;
+ ifp->if_softc = sc;
+
/* Check for task offload support. */
ndis_probe_offload(sc);
@@ -696,7 +702,7 @@ ndis_attach(dev)
/* Do media setup */
if (sc->ndis_80211) {
- struct ieee80211com *ic = (void *)&sc->ic;
+ struct ieee80211com *ic = ifp->if_l2com;
ndis_80211_rates_ex rates;
struct ndis_80211_nettype_list *ntl;
uint32_t arg;
@@ -709,8 +715,8 @@ ndis_attach(dev)
TASK_INIT(&sc->ndis_scantask, 0, ndis_scan, sc);
ic->ic_ifp = ifp;
- ic->ic_phytype = IEEE80211_T_DS;
ic->ic_opmode = IEEE80211_M_STA;
+ ic->ic_phytype = IEEE80211_T_DS;
ic->ic_caps = IEEE80211_C_IBSS;
setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO);
len = 0;
@@ -840,7 +846,7 @@ nonettypes:
}
#undef SETRATE
#undef INCRATE
- ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1);
+ ieee80211_init_channels(ic, NULL, &bands);
/*
* To test for WPA support, we need to see if we can
@@ -869,20 +875,22 @@ nonettypes:
arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
if (r == 0) {
- ic->ic_caps |= IEEE80211_C_WEP|IEEE80211_C_TKIP|
- IEEE80211_C_AES_CCM;
+ ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
+ | IEEE80211_CRYPTO_TKIP
+ | IEEE80211_CRYPTO_AES_CCM;
goto got_crypto;
}
arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
if (r == 0) {
- ic->ic_caps |= IEEE80211_C_WEP|IEEE80211_C_TKIP;
+ ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP
+ | IEEE80211_CRYPTO_TKIP;
goto got_crypto;
}
arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i);
if (r == 0)
- ic->ic_caps |= IEEE80211_C_WEP;
+ ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP;
got_crypto:
i = sizeof(arg);
r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i);
@@ -890,21 +898,17 @@ got_crypto:
ic->ic_caps |= IEEE80211_C_PMGT;
bcopy(eaddr, &ic->ic_myaddr, sizeof(eaddr));
ieee80211_ifattach(ic);
- ieee80211_media_init(ic, ieee80211_media_change,
- ndis_media_status);
+ ic->ic_raw_xmit = ndis_raw_xmit;
ic->ic_scan_start = ndis_scan_start;
ic->ic_scan_end = ndis_scan_end;
ic->ic_set_channel = ndis_set_channel;
ic->ic_scan_curchan = ndis_scan_curchan;
ic->ic_scan_mindwell = ndis_scan_mindwell;
ic->ic_bsschan = IEEE80211_CHAN_ANYC;
- ic->ic_bss->ni_chan = ic->ic_bsschan;
- /* override state transition machine */
- sc->ndis_newstate = ic->ic_newstate;
- ic->ic_newstate = ndis_newstate;
- /* install key handing routines */
- ic->ic_crypto.cs_key_set = ndis_add_key;
- ic->ic_crypto.cs_key_delete = ndis_del_key;
+ //ic->ic_bss->ni_chan = ic->ic_bsschan;
+ ic->ic_vap_create = ndis_vap_create;
+ ic->ic_vap_delete = ndis_vap_delete;
+
} else {
ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd,
ndis_ifmedia_sts);
@@ -928,6 +932,45 @@ fail:
return(error);
}
+static struct ieee80211vap *
+ndis_vap_create(struct ieee80211com *ic,
+ const char name[IFNAMSIZ], int unit, int opmode, int flags,
+ const uint8_t bssid[IEEE80211_ADDR_LEN],
+ const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+ struct ndis_vap *nvp;
+ struct ieee80211vap *vap;
+
+ if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
+ return NULL;
+ nvp = (struct ndis_vap *) malloc(sizeof(struct ndis_vap),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (nvp == NULL)
+ return NULL;
+ vap = &nvp->vap;
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ /* override with driver methods */
+ nvp->newstate = vap->iv_newstate;
+ vap->iv_newstate = ndis_newstate;
+
+ /* complete setup */
+ ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ic->ic_opmode = opmode;
+ /* install key handing routines */
+ vap->iv_key_set = ndis_add_key;
+ vap->iv_key_delete = ndis_del_key;
+ return vap;
+}
+
+static void
+ndis_vap_delete(struct ieee80211vap *vap)
+{
+ struct ndis_vap *nvp = NDIS_VAP(vap);
+
+ ieee80211_vap_detach(vap);
+ free(nvp, M_80211_VAP);
+}
+
/*
* Shutdown hardware and free up resources. This can be called any
* time after the mutex has been initialized. It is called in both
@@ -952,7 +995,7 @@ ndis_detach(dev)
NDIS_UNLOCK(sc);
ndis_stop(sc);
if (sc->ndis_80211)
- ieee80211_ifdetach(&sc->ic);
+ ieee80211_ifdetach(ifp->if_l2com);
else
ether_ifdetach(ifp);
} else
@@ -1422,10 +1465,14 @@ ndis_inputtask(dobj, arg)
struct ifnet *ifp;
struct ndis_softc *sc;
struct mbuf *m;
+ struct ieee80211com *ic;
+ struct ieee80211vap *vap;
uint8_t irql;
ifp = arg;
sc = ifp->if_softc;
+ ic = ifp->if_l2com;
+ vap = TAILQ_FIRST(&ic->ic_vaps);
block = dobj->do_devext;
KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
@@ -1434,8 +1481,10 @@ ndis_inputtask(dobj, arg)
if (m == NULL)
break;
KeReleaseSpinLock(&sc->ndis_rxlock, irql);
- ifp->if_ipackets++;
- (*ifp->if_input)(ifp, m);
+ if (sc->ndis_80211)
+ vap->iv_deliver_data(vap, vap->iv_bss, m);
+ else
+ (*ifp->if_input)(ifp, m);
KeAcquireSpinLock(&sc->ndis_rxlock, &irql);
}
KeReleaseSpinLock(&sc->ndis_rxlock, irql);
@@ -1600,11 +1649,13 @@ ndis_ticktask(d, xsc)
{
struct ndis_softc *sc;
struct ieee80211com *ic;
+ struct ieee80211vap *vap;
ndis_checkforhang_handler hangfunc;
uint8_t rval;
sc = xsc;
- ic = &sc->ic;
+ ic = sc->ifp->if_l2com;
+ vap = TAILQ_FIRST(&ic->ic_vaps);
NDIS_LOCK(sc);
if (!NDIS_INITIALIZED(sc)) {
@@ -1631,7 +1682,7 @@ ndis_ticktask(d, xsc)
NDIS_UNLOCK(sc);
if (sc->ndis_80211) {
ndis_getstate_80211(sc);
- ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+ ieee80211_new_state(vap, IEEE80211_S_RUN, -1);
}
NDIS_LOCK(sc);
if_link_state_change(sc->ifp, LINK_STATE_UP);
@@ -1641,7 +1692,7 @@ ndis_ticktask(d, xsc)
sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
sc->ndis_link = 0;
if (sc->ndis_80211)
- ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
+ ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
if_link_state_change(sc->ifp, LINK_STATE_DOWN);
}
@@ -1677,6 +1728,16 @@ ndis_map_sclist(arg, segs, nseg, mapsize, error)
return;
}
+static int
+ndis_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_bpf_params *params)
+{
+ /* no support; just discard */
+ m_freem(m);
+ ieee80211_free_node(ni);
+ return 0;
+}
+
static void
ndis_starttask(d, arg)
device_object *d;
@@ -1791,7 +1852,8 @@ ndis_start(ifp)
* to him.
*/
- BPF_MTAP(ifp, m);
+ if (!sc->ndis_80211) /* XXX handle 80211 */
+ BPF_MTAP(ifp, m);
/*
* The array that p0 points to must appear contiguous,
@@ -1840,8 +1902,8 @@ ndis_init(xsc)
void *xsc;
{
struct ndis_softc *sc = xsc;
- struct ieee80211com *ic = (void *)&sc->ic;
struct ifnet *ifp = sc->ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
int i, len, error;
/*
@@ -1850,7 +1912,7 @@ ndis_init(xsc)
* fixing the upper layer modules so they don't
* call ifp->if_init() quite as often.
*/
- if (sc->ndis_link && sc->ndis_skip)
+ if (sc->ndis_link)
return;
/*
@@ -1908,23 +1970,14 @@ ndis_init(xsc)
if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN);
- if (ic->ic_opmode != IEEE80211_M_MONITOR) {
- /*
- * NB: When restarting the adapter clock the state
- * machine regardless of the roaming mode; otherwise
- * we need to notify user apps so they can manually
- * get us going again.
- */
- if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
- ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
- } else
- ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
-
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
NDIS_UNLOCK(sc);
+ /* XXX force handling */
+ ieee80211_start_all(ic); /* start all vap's */
+
/*
* Some drivers don't set this value. The NDIS spec says
* the default checkforhang timeout is "approximately 2
@@ -2017,24 +2070,24 @@ ndis_set_cipher(sc, cipher)
int rval = 0, len;
uint32_t arg, save;
- ic = &sc->ic;
+ ic = sc->ifp->if_l2com;
len = sizeof(arg);
if (cipher == WPA_CSE_WEP40 || WPA_CSE_WEP104) {
- if (!(ic->ic_caps & IEEE80211_C_WEP))
+ if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP))
return(ENOTSUP);
arg = NDIS_80211_WEPSTAT_ENC1ENABLED;
}
if (cipher == WPA_CSE_TKIP) {
- if (!(ic->ic_caps & IEEE80211_C_TKIP))
+ if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP))
return(ENOTSUP);
arg = NDIS_80211_WEPSTAT_ENC2ENABLED;
}
if (cipher == WPA_CSE_CCMP) {
- if (!(ic->ic_caps & IEEE80211_C_AES_CCM))
+ if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_AES_CCM))
return(ENOTSUP);
arg = NDIS_80211_WEPSTAT_ENC3ENABLED;
}
@@ -2067,18 +2120,17 @@ ndis_set_cipher(sc, cipher)
*/
static int
-ndis_set_wpa(sc)
+ndis_set_wpa(sc, ie, ielen)
struct ndis_softc *sc;
+ void *ie;
+ int ielen;
{
- struct ieee80211com *ic;
struct ieee80211_ie_wpa *w;
struct ndis_ie *n;
char *pos;
uint32_t arg;
int i;
- ic = &sc->ic;
-
/*
* Apparently, the only way for us to know what ciphers
* and key management/authentication mode to use is for
@@ -2087,7 +2139,7 @@ ndis_set_wpa(sc)
* supplied by the WPA supplicant.
*/
- w = (struct ieee80211_ie_wpa *)ic->ic_opt_ie;
+ w = (struct ieee80211_ie_wpa *)ie;
/* Check for the right kind of IE. */
if (w->wpa_id != IEEE80211_ELEMID_VENDOR) {
@@ -2150,18 +2202,20 @@ ndis_setstate_80211(sc)
struct ndis_softc *sc;
{
struct ieee80211com *ic;
+ struct ieee80211vap *vap;
struct ieee80211_node *ni;
ndis_80211_ssid ssid;
ndis_80211_macaddr bssid;
ndis_80211_config config;
ndis_80211_wep wep;
- int i, rval = 0, len;
+ int i, rval = 0, len, error;
uint32_t arg;
struct ifnet *ifp;
- ic = &sc->ic;
ifp = sc->ifp;
- ni = ic->ic_bss;
+ ic = ifp->if_l2com;
+ vap = TAILQ_FIRST(&ic->ic_vaps);
+ ni = vap->iv_bss;
if (!NDIS_INITIALIZED(sc)) {
DPRINTF(("%s: NDIS not initialized\n", __func__));
@@ -2177,7 +2231,7 @@ ndis_setstate_80211(sc)
/* Set network infrastructure mode. */
len = sizeof(arg);
- if (ic->ic_opmode == IEEE80211_M_IBSS)
+ if (vap->iv_opmode == IEEE80211_M_IBSS)
arg = NDIS_80211_NET_INFRA_IBSS;
else
arg = NDIS_80211_NET_INFRA_BSS;
@@ -2190,13 +2244,13 @@ ndis_setstate_80211(sc)
/* Set RTS threshold */
len = sizeof(arg);
- arg = ic->ic_rtsthreshold;
+ arg = vap->iv_rtsthreshold;
ndis_set_info(sc, OID_802_11_RTS_THRESHOLD, &arg, &len);
/* Set fragmentation threshold */
len = sizeof(arg);
- arg = ic->ic_fragthreshold;
+ arg = vap->iv_fragthreshold;
ndis_set_info(sc, OID_802_11_FRAGMENTATION_THRESHOLD, &arg, &len);
/* Set power management */
@@ -2231,11 +2285,11 @@ ndis_setstate_80211(sc)
/* Set WEP */
- if (ic->ic_flags & IEEE80211_F_PRIVACY &&
- !(ic->ic_flags & IEEE80211_F_WPA)) {
+ if (vap->iv_flags & IEEE80211_F_PRIVACY &&
+ !(vap->iv_flags & IEEE80211_F_WPA)) {
int keys_set = 0;
- if (ic->ic_bss->ni_authmode == IEEE80211_AUTH_SHARED) {
+ if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
len = sizeof(arg);
arg = NDIS_80211_AUTHMODE_SHARED;
DPRINTF(("Setting shared auth\n"));
@@ -2243,12 +2297,12 @@ ndis_setstate_80211(sc)
&arg, &len);
}
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
- if (ic->ic_nw_keys[i].wk_keylen) {
- if (ic->ic_nw_keys[i].wk_cipher->ic_cipher !=
+ if (vap->iv_nw_keys[i].wk_keylen) {
+ if (vap->iv_nw_keys[i].wk_cipher->ic_cipher !=
IEEE80211_CIPHER_WEP)
continue;
bzero((char *)&wep, sizeof(wep));
- wep.nw_keylen = ic->ic_nw_keys[i].wk_keylen;
+ wep.nw_keylen = vap->iv_nw_keys[i].wk_keylen;
/*
* 5, 13 and 16 are the only valid
@@ -2256,21 +2310,21 @@ ndis_setstate_80211(sc)
* in between will be zero padded out to
* the next highest boundary.
*/
- if (ic->ic_nw_keys[i].wk_keylen < 5)
+ if (vap->iv_nw_keys[i].wk_keylen < 5)
wep.nw_keylen = 5;
- else if (ic->ic_nw_keys[i].wk_keylen > 5 &&
- ic->ic_nw_keys[i].wk_keylen < 13)
+ else if (vap->iv_nw_keys[i].wk_keylen > 5 &&
+ vap->iv_nw_keys[i].wk_keylen < 13)
wep.nw_keylen = 13;
- else if (ic->ic_nw_keys[i].wk_keylen > 13 &&
- ic->ic_nw_keys[i].wk_keylen < 16)
+ else if (vap->iv_nw_keys[i].wk_keylen > 13 &&
+ vap->iv_nw_keys[i].wk_keylen < 16)
wep.nw_keylen = 16;
wep.nw_keyidx = i;
wep.nw_length = (sizeof(uint32_t) * 3)
+ wep.nw_keylen;
- if (i == ic->ic_def_txkey)
+ if (i == vap->iv_def_txkey)
wep.nw_keyidx |= NDIS_80211_WEPKEY_TX;
- bcopy(ic->ic_nw_keys[i].wk_key,
+ bcopy(vap->iv_nw_keys[i].wk_key,
wep.nw_keydata, wep.nw_length);
len = sizeof(wep);
DPRINTF(("Setting WEP key %d\n", i));
@@ -2291,7 +2345,7 @@ ndis_setstate_80211(sc)
if (rval)
device_printf(sc->ndis_dev,
"enable WEP failed: %d\n", rval);
- if (ic->ic_flags & IEEE80211_F_DROPUNENC)
+ if (vap->iv_flags & IEEE80211_F_DROPUNENC)
arg = NDIS_80211_PRIVFILT_8021XWEP;
else
arg = NDIS_80211_PRIVFILT_ACCEPTALL;
@@ -2300,20 +2354,23 @@ ndis_setstate_80211(sc)
ndis_set_info(sc,
OID_802_11_PRIVACY_FILTER, &arg, &len);
}
- }
+ }
/* Set up WPA. */
- if (ic->ic_flags & IEEE80211_F_WPA1 && ic->ic_opt_ie_len &&
- ic->ic_caps & IEEE80211_C_WPA)
- if (ndis_set_wpa(sc))
+ if ((vap->iv_flags & IEEE80211_F_WPA) &&
+ vap->iv_appie_assocreq != NULL) {
+ struct ieee80211_appie *ie = vap->iv_appie_assocreq;
+ error = ndis_set_wpa(sc, ie->ie_data, ie->ie_len);
+ if (error != 0)
device_printf(sc->ndis_dev, "WPA setup failed\n");
+ }
#ifdef notyet
/* Set network type. */
arg = 0;
- switch (ic->ic_curmode) {
+ switch (vap->iv_curmode) {
case IEEE80211_MODE_11A:
arg = NDIS_80211_NETTYPE_11OFDM5;
break;
@@ -2325,7 +2382,7 @@ ndis_setstate_80211(sc)
break;
default:
device_printf(sc->ndis_dev, "unknown mode: %d\n",
- ic->ic_curmode);
+ vap->iv_curmode);
}
if (arg) {
@@ -2365,7 +2422,7 @@ ndis_setstate_80211(sc)
if (chan != ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0)) {
config.nc_dsconfig =
ic->ic_bsschan->ic_freq * 1000;
- ic->ic_bss->ni_chan = ic->ic_bsschan;
+ ni->ni_chan = ic->ic_bsschan;
len = sizeof(config);
config.nc_length = len;
config.nc_fhconfig.ncf_length =
@@ -2397,8 +2454,8 @@ ndis_setstate_80211(sc)
*/
len = IEEE80211_ADDR_LEN;
- if (ic->ic_flags & IEEE80211_F_DESBSSID &&
- ic->ic_opmode != IEEE80211_M_IBSS)
+ if (vap->iv_flags & IEEE80211_F_DESBSSID &&
+ vap->iv_opmode != IEEE80211_M_IBSS)
bcopy(ni->ni_bssid, bssid, len);
else
bcopy(ifp->if_broadcastaddr, bssid, len);
@@ -2432,67 +2489,12 @@ ndis_setstate_80211(sc)
if (rval)
device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval);
- if (ic->ic_state == IEEE80211_S_AUTH)
- ieee80211_new_state(ic, IEEE80211_S_ASSOC, 0);
+ if (vap->iv_state == IEEE80211_S_AUTH)
+ ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0);
return;
}
-static void
-ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr)
-{
- struct ieee80211com *ic = &((struct ndis_softc *)ifp->if_softc)->ic;
- struct ieee80211_node *ni = NULL;
-
- imr->ifm_status = IFM_AVALID;
- imr->ifm_active = IFM_IEEE80211;
- if (ic->ic_state == IEEE80211_S_RUN)
- imr->ifm_status |= IFM_ACTIVE;
- imr->ifm_active |= IFM_AUTO;
- switch (ic->ic_opmode) {
- case IEEE80211_M_STA:
- ni = ic->ic_bss;
- /* calculate rate subtype */
- imr->ifm_active |= ieee80211_rate2media(ic,
- ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode);
- break;
- case IEEE80211_M_IBSS:
- ni = ic->ic_bss;
- /* calculate rate subtype */
- imr->ifm_active |= ieee80211_rate2media(ic,
- ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode);
- imr->ifm_active |= IFM_IEEE80211_ADHOC;
- break;
- case IEEE80211_M_AHDEMO:
- /* should not come here */
- break;
- case IEEE80211_M_HOSTAP:
- imr->ifm_active |= IFM_IEEE80211_HOSTAP;
- break;
- case IEEE80211_M_MONITOR:
- imr->ifm_active |= IFM_IEEE80211_MONITOR;
- break;
- case IEEE80211_M_WDS:
- printf("WARNING: WDS operation mode not supported by NDIS\n");
- break;
- }
- switch (ic->ic_curmode) {
- case IEEE80211_MODE_11A:
- imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A);
- break;
- case IEEE80211_MODE_11B:
- imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11B);
- break;
- case IEEE80211_MODE_11G:
- imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11G);
- break;
- case IEEE80211_MODE_TURBO_A:
- imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A)
- | IFM_IEEE80211_TURBO;
- break;
- }
-}
-
static int
ndis_get_assoc(sc, assoc)
struct ndis_softc *sc;
@@ -2557,14 +2559,18 @@ ndis_getstate_80211(sc)
struct ndis_softc *sc;
{
struct ieee80211com *ic;
+ struct ieee80211vap *vap;
+ struct ieee80211_node *ni;
ndis_wlan_bssid_ex *bs;
int rval, len, i = 0;
int chanflag;
uint32_t arg;
struct ifnet *ifp;
- ic = &sc->ic;
ifp = sc->ifp;
+ ic = ifp->if_l2com;
+ vap = TAILQ_FIRST(&ic->ic_vaps);
+ ni = vap->iv_bss;
if (!NDIS_INITIALIZED(sc))
return;
@@ -2575,12 +2581,12 @@ ndis_getstate_80211(sc)
/* We're associated, retrieve info on the current bssid. */
ic->ic_curmode = ndis_nettype_mode(bs->nwbx_nettype);
chanflag = ndis_nettype_chan(bs->nwbx_nettype);
- IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid, bs->nwbx_macaddr);
+ IEEE80211_ADDR_COPY(ni->ni_bssid, bs->nwbx_macaddr);
/* Get SSID from current association info. */
- bcopy(bs->nwbx_ssid.ns_ssid, ic->ic_bss->ni_essid,
+ bcopy(bs->nwbx_ssid.ns_ssid, ni->ni_essid,
bs->nwbx_ssid.ns_ssidlen);
- ic->ic_bss->ni_esslen = bs->nwbx_ssid.ns_ssidlen;
+ ni->ni_esslen = bs->nwbx_ssid.ns_ssidlen;
len = sizeof(arg);
rval = ndis_get_info(sc, OID_GEN_LINK_SPEED, &arg, &len);
@@ -2589,29 +2595,29 @@ ndis_getstate_80211(sc)
rval);
if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) {
- ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B];
- for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) {
- if ((ic->ic_bss->ni_rates.rs_rates[i] &
+ ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B];
+ for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
+ if ((ni->ni_rates.rs_rates[i] &
IEEE80211_RATE_VAL) == arg / 5000)
break;
}
}
- if (i == ic->ic_bss->ni_rates.rs_nrates &&
+ if (i == ni->ni_rates.rs_nrates &&
isset(ic->ic_modecaps, IEEE80211_MODE_11G)) {
- ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11G];
- for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) {
- if ((ic->ic_bss->ni_rates.rs_rates[i] &
+ ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11G];
+ for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
+ if ((ni->ni_rates.rs_rates[i] &
IEEE80211_RATE_VAL) == arg / 5000)
break;
}
}
- if (i == ic->ic_bss->ni_rates.rs_nrates)
+ if (i == ni->ni_rates.rs_nrates)
device_printf(sc->ndis_dev, "no matching rate for: %d\n",
arg / 5000);
else
- ic->ic_bss->ni_txrate = i;
+ ni->ni_txrate = i;
if (ic->ic_caps & IEEE80211_C_PMGT) {
len = sizeof(arg);
@@ -2634,7 +2640,7 @@ ndis_getstate_80211(sc)
bs->nwbx_config.nc_dsconfig / 1000, chanflag);
if (ic->ic_curchan == NULL)
ic->ic_curchan = &ic->ic_channels[0];
- ic->ic_bss->ni_chan = ic->ic_curchan;
+ ni->ni_chan = ic->ic_curchan;
ic->ic_bsschan = ic->ic_curchan;
free(bs, M_TEMP);
@@ -2653,27 +2659,27 @@ ndis_getstate_80211(sc)
ic->ic_flags &= ~IEEE80211_F_WPA;
switch(arg) {
case NDIS_80211_AUTHMODE_OPEN:
- ic->ic_bss->ni_authmode = IEEE80211_AUTH_OPEN;
+ ni->ni_authmode = IEEE80211_AUTH_OPEN;
break;
case NDIS_80211_AUTHMODE_SHARED:
- ic->ic_bss->ni_authmode = IEEE80211_AUTH_SHARED;
+ ni->ni_authmode = IEEE80211_AUTH_SHARED;
break;
case NDIS_80211_AUTHMODE_AUTO:
- ic->ic_bss->ni_authmode = IEEE80211_AUTH_AUTO;
+ ni->ni_authmode = IEEE80211_AUTH_AUTO;
break;
case NDIS_80211_AUTHMODE_WPA:
case NDIS_80211_AUTHMODE_WPAPSK:
case NDIS_80211_AUTHMODE_WPANONE:
- ic->ic_bss->ni_authmode = IEEE80211_AUTH_WPA;
+ ni->ni_authmode = IEEE80211_AUTH_WPA;
ic->ic_flags |= IEEE80211_F_WPA1;
break;
case NDIS_80211_AUTHMODE_WPA2:
case NDIS_80211_AUTHMODE_WPA2PSK:
- ic->ic_bss->ni_authmode = IEEE80211_AUTH_WPA;
+ ni->ni_authmode = IEEE80211_AUTH_WPA;
ic->ic_flags |= IEEE80211_F_WPA2;
break;
default:
- ic->ic_bss->ni_authmode = IEEE80211_AUTH_NONE;
+ ni->ni_authmode = IEEE80211_AUTH_NONE;
break;
}
}
@@ -2699,6 +2705,7 @@ ndis_ioctl(ifp, command, data)
caddr_t data;
{
struct ndis_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ifreq *ifr = (struct ifreq *) data;
struct ndis_oid_data oid;
struct ndis_evt evt;
@@ -2744,14 +2751,9 @@ ndis_ioctl(ifp, command, data)
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
- if (sc->ndis_80211) {
- error = ieee80211_ioctl(&sc->ic, command, data);
- if (error == ENETRESET) {
- ndis_setstate_80211(sc);
- /*ndis_init(sc);*/
- error = 0;
- }
- } else
+ if (sc->ndis_80211)
+ error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command);
+ else
error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
break;
case SIOCSIFCAP:
@@ -2762,22 +2764,6 @@ ndis_ioctl(ifp, command, data)
ifp->if_hwassist = 0;
ndis_set_offload(sc);
break;
- case SIOCG80211:
- if (!NDIS_INITIALIZED(sc))
- goto do_80211;
- if (sc->ndis_80211)
- error = ndis_80211_ioctl_get(ifp, command, data);
- else
- error = ENOTTY;
- break;
- case SIOCS80211:
- if (!NDIS_INITIALIZED(sc))
- goto do_80211;
- if (sc->ndis_80211)
- error = ndis_80211_ioctl_set(ifp, command, data);
- else
- error = ENOTTY;
- break;
case SIOCGDRVSPEC:
if ((error = priv_check(curthread, PRIV_DRIVER)))
break;
@@ -2878,17 +2864,7 @@ ndis_ioctl(ifp, command, data)
NDIS_UNLOCK(sc);
break;
default:
-do_80211:
- sc->ndis_skip = 1;
- if (sc->ndis_80211) {
- error = ieee80211_ioctl(&sc->ic, command, data);
- if (error == ENETRESET) {
- ndis_setstate_80211(sc);
- error = 0;
- }
- } else
- error = ether_ioctl(ifp, command, data);
- sc->ndis_skip = 0;
+ error = ether_ioctl(ifp, command, data);
break;
}
@@ -2897,55 +2873,16 @@ do_80211:
return(error);
}
-static int
-ndis_80211_ioctl_get(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct ndis_softc *sc;
- struct ieee80211req *ireq;
- int error, len;
- uint16_t nodename_u[IEEE80211_NWID_LEN + 1];
- unicode_string us;
- ansi_string as;
-
- sc = ifp->if_softc;
- ireq = (struct ieee80211req *) data;
-
- switch (ireq->i_type) {
- case IEEE80211_IOC_MLME:
- error = 0;
- break;
- case IEEE80211_IOC_STATIONNAME:
- error = ndis_get_info(sc, OID_GEN_MACHINE_NAME,
- &nodename_u, &len);
- if (error)
- break;
- us.us_len = us.us_maxlen = len;
- us.us_buf = nodename_u;
- if (RtlUnicodeStringToAnsiString(&as, &us, TRUE)) {
- error = ENOMEM;
- break;
- }
- ireq->i_len = as.as_len;
- error = copyout(as.as_buf, ireq->i_data, ireq->i_len);
- RtlFreeAnsiString(&as);
- break;
- default:
- error = ieee80211_ioctl(&sc->ic, command, data);
- break;
- }
- return(error);
-}
-
int
-ndis_del_key(ic, key)
- struct ieee80211com *ic;
+ndis_del_key(vap, key)
+ struct ieee80211vap *vap;
const struct ieee80211_key *key;
{
struct ndis_softc *sc;
ndis_80211_key rkey;
int len, error = 0;
- sc = ic->ic_ifp->if_softc;
+ sc = vap->iv_ic->ic_ifp->if_softc;
bzero((char *)&rkey, sizeof(rkey));
len = sizeof(rkey);
@@ -2953,7 +2890,7 @@ ndis_del_key(ic, key)
rkey.nk_len = len;
rkey.nk_keyidx = key->wk_keyix;
- bcopy(ic->ic_ifp->if_broadcastaddr,
+ bcopy(vap->iv_ifp->if_broadcastaddr,
rkey.nk_bssid, IEEE80211_ADDR_LEN);
error = ndis_set_info(sc, OID_802_11_REMOVE_KEY, &rkey, &len);
@@ -2971,16 +2908,18 @@ ndis_del_key(ic, key)
*/
static int
-ndis_add_key(ic, key, mac)
- struct ieee80211com *ic;
+ndis_add_key(vap, key, mac)
+ struct ieee80211vap *vap;
const struct ieee80211_key *key;
const uint8_t mac[IEEE80211_ADDR_LEN];
{
struct ndis_softc *sc;
+ struct ifnet *ifp;
ndis_80211_key rkey;
int len, error = 0;
- sc = ic->ic_ifp->if_softc;
+ ifp = vap->iv_ic->ic_ifp;
+ sc = ifp->if_softc;
switch (key->wk_cipher->ic_cipher) {
case IEEE80211_CIPHER_TKIP:
@@ -3005,17 +2944,17 @@ ndis_add_key(ic, key, mac)
rkey.nk_keyidx |= 1 << 31;
if (key->wk_flags & IEEE80211_KEY_GROUP) {
- bcopy(ic->ic_ifp->if_broadcastaddr,
+ bcopy(ifp->if_broadcastaddr,
rkey.nk_bssid, IEEE80211_ADDR_LEN);
} else {
- bcopy(ic->ic_bss->ni_bssid,
+ bcopy(vap->iv_bss->ni_bssid,
rkey.nk_bssid, IEEE80211_ADDR_LEN);
/* pairwise key */
rkey.nk_keyidx |= 1 << 30;
}
/* need to set bit 29 based on keyrsc */
- rkey.nk_keyrsc = key->wk_keyrsc;
+ rkey.nk_keyrsc = key->wk_keyrsc[0]; /* XXX need tid */
if (rkey.nk_keyrsc)
rkey.nk_keyidx |= 1 << 29;
@@ -3050,54 +2989,6 @@ ndis_add_key(ic, key, mac)
return (1);
}
-static int
-ndis_80211_ioctl_set(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct ndis_softc *sc;
- struct ieee80211req *ireq;
- int error = EINVAL, len;
- ansi_string as;
- unicode_string us;
-
- sc = ifp->if_softc;
- ireq = (struct ieee80211req *) data;
-
- switch (ireq->i_type) {
- case IEEE80211_IOC_COUNTERMEASURES:
- case IEEE80211_IOC_DROPUNENCRYPTED:
- error = 0;
- break;
- case IEEE80211_IOC_STATIONNAME:
- error = priv_check(curthread, PRIV_NET80211_MANAGE);
- if (error)
- break;
- if (ireq->i_val != 0 ||
- ireq->i_len > IEEE80211_NWID_LEN) {
- error = EINVAL;
- break;
- }
- as.as_len = as.as_maxlen = ireq->i_len;
- as.as_buf = ireq->i_data;
- if (RtlAnsiStringToUnicodeString(&us, &as, TRUE)) {
- error = ENOMEM;
- break;
- }
- len = us.us_len;
- error = ndis_set_info(sc, OID_GEN_MACHINE_NAME,
- us.us_buf, &len);
- RtlFreeUnicodeString(&us);
- break;
- default:
- error = ieee80211_ioctl(&sc->ic, command, data);
- if (error == ENETRESET) {
- ndis_setstate_80211(sc);
- error = 0;
- }
- }
-
- return(error);
-}
-
static void
ndis_resettask(d, arg)
device_object *d;
@@ -3142,13 +3033,8 @@ ndis_stop(sc)
struct ndis_softc *sc;
{
struct ifnet *ifp;
- struct ieee80211com *ic;
int i;
- ic = &sc->ic;
- if (sc->ndis_80211)
- ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
-
ifp = sc->ifp;
callout_drain(&sc->ndis_stat_callout);
@@ -3191,24 +3077,26 @@ ndis_shutdown(dev)
}
static int
-ndis_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
+ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
+ struct ndis_vap *nvp = NDIS_VAP(vap);
+ struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = ic->ic_ifp;
struct ndis_softc *sc = ifp->if_softc;
- enum ieee80211_state ostate;
+ enum ieee80211_state ostate;
DPRINTF(("%s: %s -> %s\n", __func__,
- ieee80211_state_name[ic->ic_state],
+ ieee80211_state_name[vap->iv_state],
ieee80211_state_name[nstate]));
- ostate = ic->ic_state;
- ic->ic_state = nstate;
+ ostate = vap->iv_state;
+ vap->iv_state = nstate;
switch (nstate) {
/* pass on to net80211 */
case IEEE80211_S_INIT:
case IEEE80211_S_SCAN:
- return (sc->ndis_newstate(ic, nstate, arg));
+ return nvp->newstate(vap, nstate, arg);
case IEEE80211_S_ASSOC:
if (ostate != IEEE80211_S_AUTH)
@@ -3229,14 +3117,19 @@ static void
ndis_scan(void *arg, int npending)
{
struct ndis_softc *sc = arg;
- struct ieee80211com *ic = (void *)&sc->ic;
- struct ieee80211_scan_state *ss = ic->ic_scan;
+ struct ieee80211com *ic;
+ struct ieee80211vap *vap;
+ struct ieee80211_scan_state *ss;
ndis_80211_ssid ssid;
int error, len;
+ ic = sc->ifp->if_l2com;
+ ss = ic->ic_scan;
+ vap = TAILQ_FIRST(&ic->ic_vaps);
+
if (!NDIS_INITIALIZED(sc)) {
DPRINTF(("%s: scan aborted\n", __func__));
- ieee80211_cancel_scan(ic);
+ ieee80211_cancel_scan(vap);
return;
}
@@ -3257,7 +3150,7 @@ ndis_scan(void *arg, int npending)
NULL, &len);
if (error) {
DPRINTF(("%s: scan command failed\n", __func__));
- ieee80211_cancel_scan(ic);
+ ieee80211_cancel_scan(vap);
return;
}
@@ -3267,13 +3160,14 @@ ndis_scan(void *arg, int npending)
return;
ndis_scan_results(sc);
- ieee80211_scan_done(ic);
+ ieee80211_scan_done(vap);
}
static void
ndis_scan_results(struct ndis_softc *sc)
{
- struct ieee80211com *ic = (void *)&sc->ic;
+ struct ieee80211com *ic;
+ struct ieee80211vap *vap;
ndis_80211_bssid_list_ex *bl;
ndis_wlan_bssid_ex *wb;
struct ieee80211_scanparams sp;
@@ -3285,6 +3179,8 @@ ndis_scan_results(struct ndis_softc *sc)
uint8_t rates[2+IEEE80211_RATE_MAXSIZE];
uint8_t *frm, *efrm;
+ ic = sc->ifp->if_l2com;
+ vap = TAILQ_FIRST(&ic->ic_vaps);
noise = -96;
len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16);
@@ -3344,10 +3240,7 @@ ndis_scan_results(struct ndis_softc *sc)
chanflag = ndis_nettype_chan(wb->nwbx_nettype);
freq = wb->nwbx_config.nc_dsconfig / 1000;
- sp.bchan = ieee80211_mhz2ieee(freq, chanflag);
- sp.curchan = ieee80211_find_channel(ic, freq, chanflag);
- if (sp.curchan == NULL)
- sp.curchan = &ic->ic_channels[0];
+ sp.chan = sp.bchan = ieee80211_mhz2ieee(freq, chanflag);
/* Process extended info from AP */
if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) {
@@ -3378,7 +3271,7 @@ done:
DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n",
ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag,
rssi));
- ieee80211_add_scan(ic, &sp, &wh, 0, rssi, noise, rstamp);
+ ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise, rstamp);
wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len);
}
free(bl, M_DEVBUF);
@@ -3400,13 +3293,13 @@ ndis_set_channel(struct ieee80211com *ic)
}
static void
-ndis_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell)
+ndis_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
{
/* ignore */
}
static void
-ndis_scan_mindwell(struct ieee80211com *ic)
+ndis_scan_mindwell(struct ieee80211_scan_state *ss)
{
/* NB: don't try to abort scan; wait for firmware to finish */
}
OpenPOWER on IntegriCloud