From owner-p4-projects@FreeBSD.ORG Sun Mar 30 04:48:06 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8F44C1065678; Sun, 30 Mar 2008 04:48:06 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4E2DE1065673 for ; Sun, 30 Mar 2008 04:48:06 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 421258FC28 for ; Sun, 30 Mar 2008 04:48:06 +0000 (UTC) (envelope-from thompsa@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m2U4m59m032228 for ; Sun, 30 Mar 2008 04:48:05 GMT (envelope-from thompsa@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m2U4m5BX032226 for perforce@freebsd.org; Sun, 30 Mar 2008 04:48:05 GMT (envelope-from thompsa@freebsd.org) Date: Sun, 30 Mar 2008 04:48:05 GMT Message-Id: <200803300448.m2U4m5BX032226@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to thompsa@freebsd.org using -f From: Andrew Thompson To: Perforce Change Reviews Cc: Subject: PERFORCE change 138963 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Mar 2008 04:48:07 -0000 http://perforce.freebsd.org/chv.cgi?CH=138963 Change 138963 by thompsa@thompsa_burger on 2008/03/30 04:48:01 Checkpoint the mechanical vap changes. It compiles but is untested and still needs work. Affected files ... .. //depot/projects/vap/sys/dev/if_ndis/if_ndis.c#8 edit .. //depot/projects/vap/sys/dev/if_ndis/if_ndisvar.h#7 edit Differences ... ==== //depot/projects/vap/sys/dev/if_ndis/if_ndis.c#8 (text+ko) ==== @@ -133,6 +133,11 @@ 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 void ndis_start (struct ifnet *); @@ -140,9 +145,7 @@ 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 +154,8 @@ 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 +167,11 @@ 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 +522,11 @@ 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 +595,6 @@ 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 +670,17 @@ } } + 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); @@ -710,7 +714,6 @@ ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_DS; - ic->ic_opmode = IEEE80211_M_STA; ic->ic_caps = IEEE80211_C_IBSS; setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); len = 0; @@ -840,7 +843,7 @@ } #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 @@ -890,21 +893,16 @@ 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_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 +926,45 @@ 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 @@ -1422,10 +1459,14 @@ 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 = &sc->ic; + vap = TAILQ_FIRST(&ic->ic_vaps); block = dobj->do_devext; KeAcquireSpinLock(&sc->ndis_rxlock, &irql); @@ -1434,8 +1475,10 @@ 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); @@ -1604,11 +1647,13 @@ { struct ndis_softc *sc; struct ieee80211com *ic; + struct ieee80211vap *vap; ndis_checkforhang_handler hangfunc; uint8_t rval; sc = xsc; ic = &sc->ic; + vap = TAILQ_FIRST(&ic->ic_vaps); NDIS_LOCK(sc); if (!NDIS_INITIALIZED(sc)) { @@ -1635,7 +1680,7 @@ 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); @@ -1645,7 +1690,7 @@ 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); } @@ -1854,7 +1899,7 @@ * 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; /* @@ -1912,23 +1957,14 @@ 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 @@ -2070,18 +2106,17 @@ */ 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 @@ -2090,7 +2125,7 @@ * 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) { @@ -2153,18 +2188,20 @@ 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; + vap = TAILQ_FIRST(&ic->ic_vaps); + ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) { DPRINTF(("%s: NDIS not initialized\n", __func__)); @@ -2180,7 +2217,7 @@ /* 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; @@ -2193,13 +2230,13 @@ /* 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 */ @@ -2234,11 +2271,11 @@ /* 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")); @@ -2246,12 +2283,12 @@ &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 @@ -2259,21 +2296,21 @@ * 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)); @@ -2294,7 +2331,7 @@ 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; @@ -2303,20 +2340,23 @@ 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; @@ -2328,7 +2368,7 @@ break; default: device_printf(sc->ndis_dev, "unknown mode: %d\n", - ic->ic_curmode); + vap->iv_curmode); } if (arg) { @@ -2368,7 +2408,7 @@ 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 = @@ -2400,8 +2440,8 @@ */ 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); @@ -2435,67 +2475,12 @@ 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; @@ -2560,6 +2545,8 @@ 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; @@ -2567,7 +2554,9 @@ struct ifnet *ifp; ic = &sc->ic; + vap = TAILQ_FIRST(&ic->ic_vaps); ifp = sc->ifp; + ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) return; @@ -2578,12 +2567,12 @@ /* 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); @@ -2592,29 +2581,29 @@ 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); @@ -2637,7 +2626,7 @@ 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); @@ -2656,27 +2645,27 @@ 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; } } @@ -2747,14 +2736,7 @@ 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, &sc->ifmedia, command); break; case SIOCSIFCAP: @@ -2765,22 +2747,6 @@ 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; @@ -2881,17 +2847,8 @@ 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 + if (!sc->ndis_80211) error = ether_ioctl(ifp, command, data); - sc->ndis_skip = 0; break; } @@ -2900,55 +2857,16 @@ 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); @@ -2956,7 +2874,7 @@ 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); @@ -2974,16 +2892,18 @@ */ 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: @@ -3008,17 +2928,17 @@ 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; @@ -3053,54 +2973,6 @@ 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; @@ -3149,8 +3021,6 @@ int i; ic = &sc->ic; - if (sc->ndis_80211) - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); ifp = sc->ifp; untimeout(ndis_tick, sc, sc->ndis_stat_ch); @@ -3194,24 +3064,26 @@ } 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) @@ -3233,13 +3105,16 @@ { struct ndis_softc *sc = arg; struct ieee80211com *ic = (void *)&sc->ic; + struct ieee80211vap *vap; struct ieee80211_scan_state *ss = ic->ic_scan; ndis_80211_ssid ssid; int error, len; + 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; } @@ -3260,7 +3135,7 @@ NULL, &len); if (error) { DPRINTF(("%s: scan command failed\n", __func__)); - ieee80211_cancel_scan(ic); + ieee80211_cancel_scan(vap); return; } @@ -3270,13 +3145,14 @@ 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 ieee80211vap *vap; ndis_80211_bssid_list_ex *bl; ndis_wlan_bssid_ex *wb; struct ieee80211_scanparams sp; @@ -3288,6 +3164,7 @@ >>> TRUNCATED FOR MAIL (1000 lines) <<<