From 34f8ce05f1263db419645217d46e62d7fc3b6181 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Imre=20Vad=C3=A1sz?= Date: Fri, 20 May 2016 22:56:01 +0200 Subject: [PATCH] wlan - Sync dev/netif/ndis from FreeBSD * Sync dev/netif/ndis from FreeBSD, fbsd git dd885b9a0a0e, May 11 2016. * not tested yet (no luck with if_ndis on any of my hardware so far) --- sys/dev/netif/Makefile | 4 +- sys/dev/netif/ndis/if_ndis.c | 1216 ++++++++++++++++++++--------------- sys/dev/netif/ndis/if_ndis_pccard.c | 102 ++- sys/dev/netif/ndis/if_ndis_pci.c | 60 +- sys/dev/netif/ndis/if_ndis_u4b.c | 31 +- sys/dev/netif/ndis/if_ndisvar.h | 46 +- 6 files changed, 867 insertions(+), 592 deletions(-) diff --git a/sys/dev/netif/Makefile b/sys/dev/netif/Makefile index 94e1ab54db..05ee6c0a77 100644 --- a/sys/dev/netif/Makefile +++ b/sys/dev/netif/Makefile @@ -5,8 +5,8 @@ SUBDIR= age alc ale bce bfe bge \ re rl sbsh sf sis sk sln ste stge ti tl tx txp \ vge vr vx wb xe xl ig_hal emx ae igb ix bnx -#SUBDIR+= wpi ndis -SUBDIR+= ath bwn iwm iwi iwn ral wi +#SUBDIR+= wpi +SUBDIR+= ath bwn iwm iwi iwn ndis ral wi # Empty for concurrent build # diff --git a/sys/dev/netif/ndis/if_ndis.c b/sys/dev/netif/ndis/if_ndis.c index 88cf741eb8..033dff72b7 100644 --- a/sys/dev/netif/ndis/if_ndis.c +++ b/sys/dev/netif/ndis/if_ndis.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/if_ndis/if_ndis.c,v 1.181 2012/11/17 01:51:54 svnexp Exp $ + * $FreeBSD: head/sys/dev/if_ndis/if_ndis.c 298955 2016-05-03 03:41:25Z pfg $ * * WPA support originally contributed by Arvind Srinivasan * then hacked upon mercilessly by me. @@ -49,8 +49,10 @@ #include #include #include +#include #include +#include #include #include #include @@ -61,19 +63,36 @@ #include #include +#if !defined(__DragonFly__) +#include +#include +#endif #include #include -#include +#if defined(__DragonFly__) #include #include #include +#else +#include +#include +#include +#endif +#if defined(__DragonFly__) #include #include #include #include +#else +#include +#include +#include +#include +#endif +#if defined(__DragonFly__) #include #include #include @@ -82,6 +101,16 @@ #include #include #include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif #define NDIS_DEBUG #ifdef NDIS_DEBUG @@ -157,14 +186,13 @@ 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_update_mcast (struct ieee80211com *ic); -static void ndis_update_promisc (struct ieee80211com *ic); -static void ndis_start (struct ifnet *, struct ifaltq_subque *); +static void ndis_update_mcast (struct ieee80211com *); +static void ndis_update_promisc (struct ieee80211com *); +static void ndis_start (struct ifnet *ifp, struct ifaltq_subque *ifsq); 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, struct ucred *); -static int ndis_ioctl_80211 (struct ifnet *, u_long, caddr_t, struct ucred *); static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state, int); static int ndis_nettype_chan (uint32_t); @@ -192,13 +220,18 @@ static void ndis_media_status (struct ifnet *, struct ifmediareq *); static int ndis_set_cipher (struct ndis_softc *, int); 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 []); + const struct ieee80211_key *); static int ndis_del_key (struct ieee80211vap *, const struct ieee80211_key *); - static void ndis_setmulti (struct ndis_softc *); static void ndis_map_sclist (void *, bus_dma_segment_t *, int, bus_size_t, int); +static int ndis_ifattach(struct ndis_softc *); + +static int ndis_80211attach(struct ndis_softc *); +static int ndis_80211ioctl(struct ieee80211com *, u_long , void *); +static int ndis_80211transmit(struct ieee80211com *, struct mbuf *); +static void ndis_80211parent(struct ieee80211com *); static int ndisdrv_loaded = 0; @@ -303,7 +336,7 @@ ndis_setmulti(struct ndis_softc *sc) len = sizeof(mclistsz); ndis_get_info(sc, OID_802_3_MAXIMUM_LIST_SIZE, &mclistsz, &len); - mclist = kmalloc(ETHER_ADDR_LEN * mclistsz, M_TEMP, M_NOWAIT|M_ZERO); + mclist = kmalloc(ETHER_ADDR_LEN * mclistsz, M_TEMP, M_INTWAIT|M_ZERO); if (mclist == NULL) { sc->ndis_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; @@ -379,7 +412,7 @@ ndis_set_offload(struct ndis_softc *sc) len = sizeof(ndis_task_offload_hdr) + sizeof(ndis_task_offload) + sizeof(ndis_task_tcpip_csum); - ntoh = kmalloc(len, M_TEMP, M_NOWAIT|M_ZERO); + ntoh = kmalloc(len, M_TEMP, M_INTWAIT|M_ZERO); if (ntoh == NULL) return (ENOMEM); @@ -431,7 +464,7 @@ ndis_probe_offload(struct ndis_softc *sc) if (error != ENOSPC) return (error); - ntoh = kmalloc(len, M_TEMP, M_NOWAIT|M_ZERO); + ntoh = kmalloc(len, M_TEMP, M_INTWAIT|M_ZERO); if (ntoh == NULL) return (ENOMEM); @@ -536,25 +569,32 @@ ndis_nettype_mode(uint32_t type) int ndis_attach(device_t dev) { - u_char eaddr[ETHER_ADDR_LEN]; struct ndis_softc *sc; driver_object *pdrv; device_object *pdo; - struct ifnet *ifp = NULL; - int error = 0, len, mode; - uint8_t bands = 0; + int error = 0, len; int i; sc = device_get_softc(dev); +#if defined(__DragonFly__) lockinit(&sc->ndis_lock, "network driver", 0, LK_CANRECURSE); +#else + mtx_init(&sc->ndis_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF); +#endif KeInitializeSpinLock(&sc->ndis_rxlock); KeInitializeSpinLock(&sc->ndisusb_tasklock); KeInitializeSpinLock(&sc->ndisusb_xferdonelock); InitializeListHead(&sc->ndis_shlist); InitializeListHead(&sc->ndisusb_tasklist); InitializeListHead(&sc->ndisusb_xferdonelist); +#if defined(__DragonFly__) callout_init_mp(&sc->ndis_stat_callout); +#else + callout_init(&sc->ndis_stat_callout, 1); +#endif + mbufq_init(&sc->ndis_rxqueue, INT_MAX); /* XXXGL: sane maximum */ if (sc->ndis_iftype == PCMCIABus) { error = ndis_alloc_amem(sc); @@ -631,15 +671,8 @@ ndis_attach(device_t dev) } /* - * Get station address from the driver. - */ - len = sizeof(eaddr); - ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &eaddr, &len); - - /* * Figure out how big to make the TX buffer pool. */ - len = sizeof(sc->ndis_maxpkts); if (ndis_get_info(sc, OID_GEN_MAXIMUM_SEND_PACKETS, &sc->ndis_maxpkts, &len)) { @@ -661,7 +694,7 @@ ndis_attach(device_t dev) sc->ndis_maxpkts = 10; sc->ndis_txarray = kmalloc(sizeof(ndis_packet *) * - sc->ndis_maxpkts, M_DEVBUF, M_WAITOK|M_ZERO); + sc->ndis_maxpkts, M_DEVBUF, M_INTWAIT|M_ZERO); /* Allocate a pool of ndis_packets for TX encapsulation. */ @@ -692,100 +725,94 @@ ndis_attach(device_t dev) */ for (i = 0; i < sc->ndis_oidcnt; i++) if (sc->ndis_oids[i] == OID_802_11_CONFIGURATION) { - sc->ndis_80211++; + sc->ndis_80211 = 1; break; } if (sc->ndis_80211) - ifp = if_alloc(IFT_IEEE80211); + error = ndis_80211attach(sc); else - ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - error = ENOSPC; - goto fail; + error = ndis_ifattach(sc); + +fail: + if (error) { + ndis_detach(dev); + return (error); } - sc->ifp = ifp; - ifp->if_softc = sc; - /* Check for task offload support. */ - ndis_probe_offload(sc); + if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0) + return (error); - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; -#if 0 - if (sc->ndis_iftype == PNPBus) - ifp->if_flags |= IFF_NEEDSGIANT; -#endif - ifp->if_ioctl = ndis_ioctl; - ifp->if_start = ndis_start; - ifp->if_init = ndis_init; - ifp->if_baudrate = 10000000; - ifq_set_maxlen(&ifp->if_snd, 50); -#ifdef notyet - ifq_set_ready(&ifp->if_snd); -#endif - ifp->if_capenable = ifp->if_capabilities; - ifp->if_hwassist = sc->ndis_hwassist; + DPRINTF(("attach done.\n")); + /* We're done talking to the NIC for now; halt it. */ + ndis_halt_nic(sc); + DPRINTF(("halting done.\n")); - /* Do media setup */ - if (sc->ndis_80211) { - struct ieee80211com *ic = ifp->if_l2com; - ndis_80211_rates_ex rates; - struct ndis_80211_nettype_list *ntl; - uint32_t arg; - int r; - - callout_init_mp(&sc->ndis_scan_callout); - - ifp->if_ioctl = ndis_ioctl_80211; - ic->ic_ifp = ifp; - ic->ic_softc = sc; - ic->ic_name = device_get_nameunit(dev); - ic->ic_opmode = IEEE80211_M_STA; - ic->ic_phytype = IEEE80211_T_DS; - ic->ic_caps = IEEE80211_C_8023ENCAP | - IEEE80211_C_STA | IEEE80211_C_IBSS; - setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); - len = 0; - r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, - NULL, &len); - if (r != ENOSPC) - goto nonettypes; - ntl = kmalloc(len, M_DEVBUF, M_NOWAIT|M_ZERO); - r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, - ntl, &len); - if (r != 0) { - kfree(ntl, M_DEVBUF); - goto nonettypes; - } + return (error); +} - for (i = 0; i < ntl->ntl_items; i++) { - mode = ndis_nettype_mode(ntl->ntl_type[i]); - if (mode) { - setbit(ic->ic_modecaps, mode); - setbit(&bands, mode); - } else - device_printf(dev, "Unknown nettype %d\n", - ntl->ntl_type[i]); - } +static int +ndis_80211attach(struct ndis_softc *sc) +{ + struct ieee80211com *ic = &sc->ndis_ic; + ndis_80211_rates_ex rates; + struct ndis_80211_nettype_list *ntl; + uint32_t arg; + int mode, i, r, len, nonettypes = 1; + uint8_t bands[IEEE80211_MODE_BYTES] = { 0 }; + +#if defined(__DragonFly__) + callout_init_mp(&sc->ndis_scan_callout); +#else + callout_init(&sc->ndis_scan_callout, 1); +#endif + + ic->ic_softc = sc; + ic->ic_ioctl = ndis_80211ioctl; + ic->ic_name = device_get_nameunit(sc->ndis_dev); + ic->ic_opmode = IEEE80211_M_STA; + ic->ic_phytype = IEEE80211_T_DS; + ic->ic_caps = IEEE80211_C_8023ENCAP | + IEEE80211_C_STA | IEEE80211_C_IBSS; + setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); + len = 0; + r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, NULL, &len); + if (r != ENOSPC) + goto nonettypes; + ntl = kmalloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + r = ndis_get_info(sc, OID_802_11_NETWORK_TYPES_SUPPORTED, ntl, &len); + if (r != 0) { kfree(ntl, M_DEVBUF); + goto nonettypes; + } + + for (i = 0; i < ntl->ntl_items; i++) { + mode = ndis_nettype_mode(ntl->ntl_type[i]); + if (mode) { + nonettypes = 0; + setbit(ic->ic_modecaps, mode); + setbit(bands, mode); + } else + device_printf(sc->ndis_dev, "Unknown nettype %d\n", + ntl->ntl_type[i]); + } + kfree(ntl, M_DEVBUF); nonettypes: - /* Default to 11b channels if the card did not supply any */ - if (bands == 0) { - setbit(ic->ic_modecaps, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11B); - } - len = sizeof(rates); - bzero((char *)&rates, len); - r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES, - (void *)rates, &len); - if (r) - device_printf(dev, "get rates failed: 0x%x\n", r); - /* - * Since the supported rates only up to 8 can be supported, - * if this is not 802.11b we're just going to be faking it - * all up to heck. - */ + /* Default to 11b channels if the card did not supply any */ + if (nonettypes) { + setbit(ic->ic_modecaps, IEEE80211_MODE_11B); + setbit(bands, IEEE80211_MODE_11B); + } + len = sizeof(rates); + bzero((char *)&rates, len); + r = ndis_get_info(sc, OID_802_11_SUPPORTED_RATES, (void *)rates, &len); + if (r != 0) + device_printf(sc->ndis_dev, "get rates failed: 0x%x\n", r); + /* + * Since the supported rates only up to 8 can be supported, + * if this is not 802.11b we're just going to be faking it + * all up to heck. + */ #define TESTSETRATE(x, y) \ do { \ @@ -805,177 +832,207 @@ nonettypes: #define INCRATE(x) \ ic->ic_sup_rates[x].rs_nrates++ - ic->ic_curmode = IEEE80211_MODE_AUTO; - if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) - ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0; - if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) - ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0; - if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) - ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0; - for (i = 0; i < len; i++) { - switch (rates[i] & IEEE80211_RATE_VAL) { - case 2: - case 4: - case 11: - case 10: - case 22: - if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) { - /* Lazy-init 802.11b. */ - setbit(ic->ic_modecaps, - IEEE80211_MODE_11B); - ic->ic_sup_rates[IEEE80211_MODE_11B]. - rs_nrates = 0; - } - SETRATE(IEEE80211_MODE_11B, rates[i]); - INCRATE(IEEE80211_MODE_11B); - break; - default: - if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { - SETRATE(IEEE80211_MODE_11A, rates[i]); - INCRATE(IEEE80211_MODE_11A); - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { - SETRATE(IEEE80211_MODE_11G, rates[i]); - INCRATE(IEEE80211_MODE_11G); - } - break; + ic->ic_curmode = IEEE80211_MODE_AUTO; + if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) + ic->ic_sup_rates[IEEE80211_MODE_11A].rs_nrates = 0; + if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) + ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = 0; + if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) + ic->ic_sup_rates[IEEE80211_MODE_11G].rs_nrates = 0; + for (i = 0; i < len; i++) { + switch (rates[i] & IEEE80211_RATE_VAL) { + case 2: + case 4: + case 11: + case 10: + case 22: + if (isclr(ic->ic_modecaps, IEEE80211_MODE_11B)) { + /* Lazy-init 802.11b. */ + setbit(ic->ic_modecaps, IEEE80211_MODE_11B); + ic->ic_sup_rates[IEEE80211_MODE_11B]. + rs_nrates = 0; } + SETRATE(IEEE80211_MODE_11B, rates[i]); + INCRATE(IEEE80211_MODE_11B); + break; + default: + if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { + SETRATE(IEEE80211_MODE_11A, rates[i]); + INCRATE(IEEE80211_MODE_11A); + } + if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { + SETRATE(IEEE80211_MODE_11G, rates[i]); + INCRATE(IEEE80211_MODE_11G); + } + break; } + } + + /* + * If the hardware supports 802.11g, it most + * likely supports 802.11b and all of the + * 802.11b and 802.11g speeds, so maybe we can + * just cheat here. Just how in the heck do + * we detect turbo modes, though? + */ + if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) { + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|2); + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|4); + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|11); + TESTSETRATE(IEEE80211_MODE_11B, IEEE80211_RATE_BASIC|22); + } + if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { + TESTSETRATE(IEEE80211_MODE_11G, 48); + TESTSETRATE(IEEE80211_MODE_11G, 72); + TESTSETRATE(IEEE80211_MODE_11G, 96); + TESTSETRATE(IEEE80211_MODE_11G, 108); + } + if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { + TESTSETRATE(IEEE80211_MODE_11A, 48); + TESTSETRATE(IEEE80211_MODE_11A, 72); + TESTSETRATE(IEEE80211_MODE_11A, 96); + TESTSETRATE(IEEE80211_MODE_11A, 108); + } - /* - * If the hardware supports 802.11g, it most - * likely supports 802.11b and all of the - * 802.11b and 802.11g speeds, so maybe we can - * just cheat here. Just how in the heck do - * we detect turbo modes, though? - */ - if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) { - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|2); - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|4); - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|11); - TESTSETRATE(IEEE80211_MODE_11B, - IEEE80211_RATE_BASIC|22); - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { - TESTSETRATE(IEEE80211_MODE_11G, 48); - TESTSETRATE(IEEE80211_MODE_11G, 72); - TESTSETRATE(IEEE80211_MODE_11G, 96); - TESTSETRATE(IEEE80211_MODE_11G, 108); - } - if (isset(ic->ic_modecaps, IEEE80211_MODE_11A)) { - TESTSETRATE(IEEE80211_MODE_11A, 48); - TESTSETRATE(IEEE80211_MODE_11A, 72); - TESTSETRATE(IEEE80211_MODE_11A, 96); - TESTSETRATE(IEEE80211_MODE_11A, 108); - } #undef SETRATE #undef INCRATE - ieee80211_init_channels(ic, NULL, &bands); +#undef TESTSETRATE - /* - * To test for WPA support, we need to see if we can - * set AUTHENTICATION_MODE to WPA and read it back - * successfully. - */ - i = sizeof(arg); - arg = NDIS_80211_AUTHMODE_WPA; - r = ndis_set_info(sc, - OID_802_11_AUTHENTICATION_MODE, &arg, &i); - if (r == 0) { - r = ndis_get_info(sc, - OID_802_11_AUTHENTICATION_MODE, &arg, &i); - if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA) - ic->ic_caps |= IEEE80211_C_WPA; - } + ieee80211_init_channels(ic, NULL, bands); - /* - * To test for supported ciphers, we set each - * available encryption type in descending order. - * If ENC3 works, then we have WEP, TKIP and AES. - * If only ENC2 works, then we have WEP and TKIP. - * If only ENC1 works, then we have just WEP. - */ - i = sizeof(arg); - arg = NDIS_80211_WEPSTAT_ENC3ENABLED; - r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); - if (r == 0) { - 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_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_cryptocaps |= IEEE80211_CRYPTO_WEP; + /* + * To test for WPA support, we need to see if we can + * set AUTHENTICATION_MODE to WPA and read it back + * successfully. + */ + i = sizeof(arg); + arg = NDIS_80211_AUTHMODE_WPA; + r = ndis_set_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i); + if (r == 0) { + r = ndis_get_info(sc, OID_802_11_AUTHENTICATION_MODE, &arg, &i); + if (r == 0 && arg == NDIS_80211_AUTHMODE_WPA) + ic->ic_caps |= IEEE80211_C_WPA; + } + + /* + * To test for supported ciphers, we set each + * available encryption type in descending order. + * If ENC3 works, then we have WEP, TKIP and AES. + * If only ENC2 works, then we have WEP and TKIP. + * If only ENC1 works, then we have just WEP. + */ + i = sizeof(arg); + arg = NDIS_80211_WEPSTAT_ENC3ENABLED; + r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); + if (r == 0) { + 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_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_cryptocaps |= IEEE80211_CRYPTO_WEP; got_crypto: - i = sizeof(arg); - r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i); - if (r == 0) - ic->ic_caps |= IEEE80211_C_PMGT; - - r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i); - if (r == 0) - ic->ic_caps |= IEEE80211_C_TXPMGT; - - /* ieee80211_ifattach() assumes that WLAN serializer is held */ - wlan_serialize_enter(); - ieee80211_ifattach(ic, eaddr); - wlan_serialize_exit(); - 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; - ic->ic_vap_create = ndis_vap_create; - ic->ic_vap_delete = ndis_vap_delete; - ic->ic_update_mcast = ndis_update_mcast; - ic->ic_update_promisc = ndis_update_promisc; - - if (bootverbose) - ieee80211_announce(ic); + i = sizeof(arg); + r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i); + if (r == 0) + ic->ic_caps |= IEEE80211_C_PMGT; - } else { - ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd, - ndis_ifmedia_sts); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); - ifmedia_add(&sc->ifmedia, - IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); - ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); - ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO); - ether_ifattach(ifp, eaddr, NULL); - } + r = ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &i); + if (r == 0) + ic->ic_caps |= IEEE80211_C_TXPMGT; -fail: - if (error) { - ndis_detach(dev); - return (error); - } + /* + * Get station address from the driver. + */ + len = sizeof(ic->ic_macaddr); + ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, &ic->ic_macaddr, &len); + + ieee80211_ifattach(ic); + 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_vap_create = ndis_vap_create; + ic->ic_vap_delete = ndis_vap_delete; + ic->ic_update_mcast = ndis_update_mcast; + ic->ic_update_promisc = ndis_update_promisc; + ic->ic_transmit = ndis_80211transmit; + ic->ic_parent = ndis_80211parent; + + if (bootverbose) + ieee80211_announce(ic); - if (sc->ndis_iftype == PNPBus && ndisusb_halt == 0) - return (error); + return (0); +} - DPRINTF(("attach done.\n")); - /* We're done talking to the NIC for now; halt it. */ - ndis_halt_nic(sc); - DPRINTF(("halting done.\n")); +static int +ndis_ifattach(struct ndis_softc *sc) +{ + struct ifnet *ifp; + u_char eaddr[ETHER_ADDR_LEN]; + int len; - return (error); + ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) + return (ENOSPC); + sc->ifp = ifp; + ifp->if_softc = sc; + + /* Check for task offload support. */ + ndis_probe_offload(sc); + + /* + * Get station address from the driver. + */ + len = sizeof(eaddr); + ndis_get_info(sc, OID_802_3_CURRENT_ADDRESS, eaddr, &len); + + if_initname(ifp, device_get_name(sc->ndis_dev), + device_get_unit(sc->ndis_dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = ndis_ioctl; + ifp->if_start = ndis_start; + ifp->if_init = ndis_init; + ifp->if_baudrate = 10000000; +#if defined(__DragonFly__) + ifq_set_maxlen(&ifp->if_snd, 50); + /* ifq_set_ready(&ifp->if_snd); */ +#else + IFQ_SET_MAXLEN(&ifp->if_snd, 50); + ifp->if_snd.ifq_drv_maxlen = 25; + IFQ_SET_READY(&ifp->if_snd); +#endif + ifp->if_capenable = ifp->if_capabilities; + ifp->if_hwassist = sc->ndis_hwassist; + + ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd, + ndis_ifmedia_sts); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL); + ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); + ifmedia_set(&sc->ifmedia, IFM_ETHER|IFM_AUTO); +#if defined(__DragonFly__) + ether_ifattach(ifp, eaddr, NULL); +#else + ether_ifattach(ifp, eaddr); +#endif + + return (0); } static struct ieee80211vap * @@ -989,18 +1046,16 @@ ndis_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - nvp = (struct ndis_vap *) kmalloc(sizeof(struct ndis_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (nvp == NULL) - return NULL; + nvp = kmalloc(sizeof(struct ndis_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &nvp->vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override with driver methods */ nvp->newstate = vap->iv_newstate; vap->iv_newstate = ndis_newstate; /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, ndis_media_status, + mac); ic->ic_opmode = opmode; /* install key handing routines */ vap->iv_key_set = ndis_add_key; @@ -1013,11 +1068,10 @@ ndis_vap_delete(struct ieee80211vap *vap) { 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; + struct ndis_softc *sc = ic->ic_softc; ndis_stop(sc); - callout_stop_sync(&sc->ndis_scan_callout); + callout_drain(&sc->ndis_scan_callout); ieee80211_vap_detach(vap); kfree(nvp, M_80211_VAP); } @@ -1032,24 +1086,27 @@ ndis_vap_delete(struct ieee80211vap *vap) int ndis_detach(device_t dev) { - struct ndis_softc *sc; struct ifnet *ifp; + struct ndis_softc *sc; driver_object *drv; sc = device_get_softc(dev); - ifp = sc->ifp; + NDIS_LOCK(sc); + if (!sc->ndis_80211) + ifp = sc->ifp; + else + ifp = NULL; if (ifp != NULL) ifp->if_flags &= ~IFF_UP; - if (device_is_attached(dev)) { + NDIS_UNLOCK(sc); ndis_stop(sc); - if (ifp != NULL) { - if (sc->ndis_80211) - ieee80211_ifdetach(ifp->if_l2com); - else - ether_ifdetach(ifp); - } - } + if (sc->ndis_80211) + ieee80211_ifdetach(&sc->ndis_ic); + else if (ifp != NULL) + ether_ifdetach(ifp); + } else + NDIS_UNLOCK(sc); if (sc->ndis_tickitem != NULL) IoFreeWorkItem(sc->ndis_tickitem); @@ -1120,14 +1177,13 @@ ndis_suspend(device_t dev) { #if 0 /* notdef */ struct ndis_softc *sc; + struct ifnet *ifp; - wlan_serialize_enter(); sc = device_get_softc(dev); + ifp = sc->ifp; if (NDIS_INITIALIZED(sc)) ndis_stop(sc); - - wlan_serialize_exit(); #endif return (0); } @@ -1136,14 +1192,14 @@ int ndis_resume(device_t dev) { struct ndis_softc *sc; + struct ifnet *ifp; - wlan_serialize_enter(); sc = device_get_softc(dev); + ifp = sc->ifp; if (NDIS_INITIALIZED(sc)) ndis_init(sc); - wlan_serialize_exit(); return (0); } @@ -1288,11 +1344,11 @@ ndis_rxeof_xfr(kdpc *dpc, ndis_handle adapter, void *sysarg1, void *sysarg2) IoFreeMdl(p->np_private.npp_head); NdisFreePacket(p); KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock); - IF_ENQUEUE(&sc->ndis_rxqueue, m); + mbufq_enqueue(&sc->ndis_rxqueue, m); KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock); IoQueueWorkItem(sc->ndis_inputitem, (io_workitem_func)ndis_inputtask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc); } if (status == NDIS_STATUS_FAILURE) @@ -1333,11 +1389,11 @@ ndis_rxeof_xfr_done(ndis_handle adapter, ndis_packet *packet, uint32_t status, m->m_len = m->m_pkthdr.len; m->m_pkthdr.rcvif = ifp; KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock); - IF_ENQUEUE(&sc->ndis_rxqueue, m); + mbufq_enqueue(&sc->ndis_rxqueue, m); KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock); IoQueueWorkItem(sc->ndis_inputitem, (io_workitem_func)ndis_inputtask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc); } /* * A frame has been uploaded: pass the resulting mbuf chain up to @@ -1347,7 +1403,7 @@ ndis_rxeof_xfr_done(ndis_handle adapter, ndis_packet *packet, uint32_t status, * out-of-band portion of the ndis_packet has special meaning. In the * most common case, the underlying NDIS driver will set this field * to NDIS_STATUS_SUCCESS, which indicates that it's ok for us to - * take posession of it. We then change the status field to + * take possession of it. We then change the status field to * NDIS_STATUS_PENDING to tell the driver that we now own the packet, * and that we will return it at some point in the future via the * return packet handler. @@ -1379,12 +1435,16 @@ ndis_rxeof(ndis_handle adapter, ndis_packet **packets, uint32_t pktcnt) * before we're completely ready to handle them. If we detect this, * we need to return them to the miniport and ignore them. */ - if (!(ifp->if_flags & IFF_RUNNING)) { + if (!sc->ndis_running) { for (i = 0; i < pktcnt; i++) { p = packets[i]; if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) { p->np_refcnt++; +#if defined(__DragonFly__) ndis_return_packet(p); +#else + (void)ndis_return_packet(NULL, p, block); +#endif } } return; @@ -1396,8 +1456,13 @@ ndis_rxeof(ndis_handle adapter, ndis_packet **packets, uint32_t pktcnt) p->np_softc = sc; if (ndis_ptom(&m0, p)) { device_printf(sc->ndis_dev, "ptom failed\n"); - if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) + if (p->np_oob.npo_status == NDIS_STATUS_SUCCESS) { +#if defined(__DragonFly__) ndis_return_packet(p); +#else + (void)ndis_return_packet(NULL, p, block); +#endif + } } else { #ifdef notdef if (p->np_oob.npo_status == NDIS_STATUS_RESOURCES) { @@ -1413,7 +1478,7 @@ ndis_rxeof(ndis_handle adapter, ndis_packet **packets, uint32_t pktcnt) p->np_refcnt++; m_freem(m0); if (m == NULL) - ifp->if_ierrors++; + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); else m0 = m; } else @@ -1426,7 +1491,7 @@ ndis_rxeof(ndis_handle adapter, ndis_packet **packets, uint32_t pktcnt) p->np_oob.npo_status = NDIS_STATUS_PENDING; m_freem(m0); if (m == NULL) { - IFNET_STAT_INC(ifp, ierrors, 1); + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); continue; } m0 = m; @@ -1453,46 +1518,49 @@ ndis_rxeof(ndis_handle adapter, ndis_packet **packets, uint32_t pktcnt) } KeAcquireSpinLockAtDpcLevel(&sc->ndis_rxlock); - IF_ENQUEUE(&sc->ndis_rxqueue, m0); + mbufq_enqueue(&sc->ndis_rxqueue, m0); KeReleaseSpinLockFromDpcLevel(&sc->ndis_rxlock); IoQueueWorkItem(sc->ndis_inputitem, (io_workitem_func)ndis_inputtask_wrap, - WORKQUEUE_CRITICAL, ifp); + WORKQUEUE_CRITICAL, sc); } } } /* * This routine is run at PASSIVE_LEVEL. We use this routine to pass - * packets into the stack in order to avoid calling ifp->if_input() + * packets into the stack in order to avoid calling (*ifp->if_input)() * with any locks held (at DISPATCH_LEVEL, we'll be holding the * 'dispatch level' per-cpu sleep lock). */ static void ndis_inputtask(device_object *dobj, void *arg) { - struct ifnet *ifp; - struct ndis_softc *sc; + ndis_miniport_block *block; + struct ndis_softc *sc = arg; 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); - while(1) { - IF_DEQUEUE(&sc->ndis_rxqueue, m); - if (m == NULL) - break; + while ((m = mbufq_dequeue(&sc->ndis_rxqueue)) != NULL) { KeReleaseSpinLock(&sc->ndis_rxlock, irql); - if ((sc->ndis_80211 != 0) && (vap != NULL)) - vap->iv_deliver_data(vap, vap->iv_bss, m); - else + if ((sc->ndis_80211 != 0)) { + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap != NULL) + vap->iv_deliver_data(vap, vap->iv_bss, m); + } else { + struct ifnet *ifp = sc->ifp; + +#if defined(__DragonFly__) ifp->if_input(ifp, m, NULL, -1); +#else + (*ifp->if_input)(ifp, m); +#endif + } KeAcquireSpinLock(&sc->ndis_rxlock, &irql); } KeReleaseSpinLock(&sc->ndis_rxlock, irql); @@ -1523,19 +1591,23 @@ ndis_txeof(ndis_handle adapter, ndis_packet *packet, ndis_status status) ndis_free_packet(packet); m_freem(m); - NDISMTX_LOCK(sc); + NDIS_LOCK(sc); sc->ndis_txarray[idx] = NULL; sc->ndis_txpending++; if (status == NDIS_STATUS_SUCCESS) - IFNET_STAT_INC(ifp, opackets, 1); + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); else - IFNET_STAT_INC(ifp, oerrors, 1); + if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); sc->ndis_tx_timer = 0; - ifq_clr_oactive(&ifp->if_snd); +#if defined(__DragonFly__) + ifq_clr_oactive(&sc->ifp->if_snd); +#else + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; +#endif - NDISMTX_UNLOCK(sc); + NDIS_UNLOCK(sc); IoQueueWorkItem(sc->ndis_startitem, (io_workitem_func)ndis_starttask_wrap, @@ -1555,9 +1627,9 @@ ndis_linksts(ndis_handle adapter, ndis_status status, void *sbuf, /* Event list is all full up, drop this one. */ - NDISMTX_LOCK(sc); + NDIS_LOCK(sc); if (sc->ndis_evt[sc->ndis_evtpidx].ne_sts) { - NDISMTX_UNLOCK(sc); + NDIS_UNLOCK(sc); return; } @@ -1565,9 +1637,9 @@ ndis_linksts(ndis_handle adapter, ndis_status status, void *sbuf, if (slen) { sc->ndis_evt[sc->ndis_evtpidx].ne_buf = kmalloc(slen, - M_TEMP, M_NOWAIT); + M_TEMP, M_INTWAIT); if (sc->ndis_evt[sc->ndis_evtpidx].ne_buf == NULL) { - NDISMTX_UNLOCK(sc); + NDIS_UNLOCK(sc); return; } bcopy((char *)sbuf, @@ -1576,7 +1648,7 @@ ndis_linksts(ndis_handle adapter, ndis_status status, void *sbuf, sc->ndis_evt[sc->ndis_evtpidx].ne_sts = status; sc->ndis_evt[sc->ndis_evtpidx].ne_len = slen; NDIS_EVTINC(sc->ndis_evtpidx); - NDISMTX_UNLOCK(sc); + NDIS_UNLOCK(sc); } static void @@ -1628,7 +1700,7 @@ ndis_tick(void *xsc) } if (sc->ndis_tx_timer && --sc->ndis_tx_timer == 0) { - IFNET_STAT_INC(sc->ifp, oerrors, 1); + if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1); device_printf(sc->ndis_dev, "watchdog timeout\n"); IoQueueWorkItem(sc->ndis_resetitem, @@ -1645,16 +1717,10 @@ ndis_tick(void *xsc) static void ndis_ticktask(device_object *d, void *xsc) { - struct ndis_softc *sc; - struct ieee80211com *ic; - struct ieee80211vap *vap; + struct ndis_softc *sc = xsc; ndis_checkforhang_handler hangfunc; uint8_t rval; - sc = xsc; - ic = sc->ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); - NDIS_LOCK(sc); if (!NDIS_INITIALIZED(sc)) { NDIS_UNLOCK(sc); @@ -1677,25 +1743,60 @@ ndis_ticktask(device_object *d, void *xsc) if (sc->ndis_link == 0 && sc->ndis_sts == NDIS_STATUS_MEDIA_CONNECT) { sc->ndis_link = 1; - NDIS_UNLOCK(sc); - if ((sc->ndis_80211 != 0) && (vap != NULL)) { - ndis_getstate_80211(sc); - ieee80211_new_state(vap, IEEE80211_S_RUN, -1); + if (sc->ndis_80211 != 0) { + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap != NULL) { + NDIS_UNLOCK(sc); + ndis_getstate_80211(sc); + ieee80211_new_state(vap, IEEE80211_S_RUN, -1); + NDIS_LOCK(sc); +#if defined(__DragonFly__) + vap->iv_ifp->if_link_state = LINK_STATE_UP; + if_link_state_change(vap->iv_ifp); +#else + if_link_state_change(vap->iv_ifp, + LINK_STATE_UP); +#endif + } + } else { +#if defined(__DragonFly__) + sc->ifp->if_link_state = LINK_STATE_UP; + if_link_state_change(sc->ifp); +#else + if_link_state_change(sc->ifp, LINK_STATE_UP); +#endif } - NDIS_LOCK(sc); - sc->ifp->if_link_state = LINK_STATE_UP; - if_link_state_change(sc->ifp); } if (sc->ndis_link == 1 && sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) { sc->ndis_link = 0; - NDIS_UNLOCK(sc); - if ((sc->ndis_80211 != 0) && (vap != NULL)) - ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); - NDIS_LOCK(sc); - sc->ifp->if_link_state = LINK_STATE_DOWN; - if_link_state_change(sc->ifp); + if (sc->ndis_80211 != 0) { + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap != NULL) { + NDIS_UNLOCK(sc); + ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); + NDIS_LOCK(sc); +#if defined(__DragonFly__) + vap->iv_ifp->if_link_state = LINK_STATE_DOWN; + if_link_state_change(vap->iv_ifp); +#else + if_link_state_change(vap->iv_ifp, + LINK_STATE_DOWN); +#endif + } + } else { +#if defined(__DragonFly__) + sc->ifp->if_link_state = LINK_STATE_DOWN; + if_link_state_change(sc->ifp); +#else + if_link_state_change(sc->ifp, LINK_STATE_DOWN); +#endif + } } NDIS_UNLOCK(sc); @@ -1752,10 +1853,13 @@ ndis_starttask(device_object *d, void *arg) ifp = arg; - lwkt_serialize_enter(ifp->if_serializer); +#if defined(__DragonFly__) if (!ifq_is_empty(&ifp->if_snd)) if_devstart(ifp); - lwkt_serialize_exit(ifp->if_serializer); +#else + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + ndis_start(ifp); +#endif } /* @@ -1779,18 +1883,14 @@ ndis_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) ndis_tcpip_csum *csum; int pcnt = 0, status; - ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq); - sc = ifp->if_softc; NDIS_LOCK(sc); - if (!sc->ndis_link) { - ifq_purge(&ifp->if_snd); - NDIS_UNLOCK(sc); - return; - } - - if (ifq_is_oactive(&ifp->if_snd)) { +#if defined(__DragonFly__) + if (!sc->ndis_link || ifq_is_oactive(&ifp->if_snd)) { +#else + if (!sc->ndis_link || ifp->if_drv_flags & IFF_DRV_OACTIVE) { +#endif NDIS_UNLOCK(sc); return; } @@ -1798,7 +1898,11 @@ ndis_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) p0 = &sc->ndis_txarray[sc->ndis_txidx]; while(sc->ndis_txpending) { +#if defined(__DragonFly__) m = ifq_dequeue(&ifp->if_snd); +#else + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); +#endif if (m == NULL) break; @@ -1809,7 +1913,11 @@ ndis_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) break; if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) { +#if defined(__DragonFly__) ifq_prepend(&ifp->if_snd, m); +#else + IFQ_DRV_PREPEND(&ifp->if_snd, m); +#endif NDIS_UNLOCK(sc); return; } @@ -1881,8 +1989,13 @@ ndis_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) return; } - if (sc->ndis_txpending == 0) + if (sc->ndis_txpending == 0) { +#if defined(__DragonFly__) ifq_set_oactive(&ifp->if_snd); +#else + ifp->if_drv_flags |= IFF_DRV_OACTIVE; +#endif + } /* * Set a timeout in case the chip goes out to lunch. @@ -1905,12 +2018,103 @@ ndis_start(struct ifnet *ifp, struct ifaltq_subque *ifsq) return; } +static int +ndis_80211transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct ndis_softc *sc = ic->ic_softc; + ndis_packet **p0 = NULL, *p = NULL; + int status; + + NDIS_LOCK(sc); + if (!sc->ndis_link || !sc->ndis_running) { + NDIS_UNLOCK(sc); + return (ENXIO); + } + + if (sc->ndis_txpending == 0) { + NDIS_UNLOCK(sc); + return (ENOBUFS); + } + + p0 = &sc->ndis_txarray[sc->ndis_txidx]; + + NdisAllocatePacket(&status, + &sc->ndis_txarray[sc->ndis_txidx], sc->ndis_txpool); + + if (status != NDIS_STATUS_SUCCESS) { + NDIS_UNLOCK(sc); + return (ENOBUFS); + } + + if (ndis_mtop(m, &sc->ndis_txarray[sc->ndis_txidx])) { + NDIS_UNLOCK(sc); + return (ENOBUFS); + } + + /* + * Save pointer to original mbuf + * so we can free it later. + */ + + p = sc->ndis_txarray[sc->ndis_txidx]; + p->np_txidx = sc->ndis_txidx; + p->np_m0 = m; + p->np_oob.npo_status = NDIS_STATUS_PENDING; + + /* + * Do scatter/gather processing, if driver requested it. + */ + if (sc->ndis_sc) { + bus_dmamap_load_mbuf(sc->ndis_ttag, + sc->ndis_tmaps[sc->ndis_txidx], m, + ndis_map_sclist, &p->np_sclist, BUS_DMA_NOWAIT); + bus_dmamap_sync(sc->ndis_ttag, + sc->ndis_tmaps[sc->ndis_txidx], + BUS_DMASYNC_PREREAD); + p->np_ext.npe_info[ndis_sclist_info] = &p->np_sclist; + } + + NDIS_INC(sc); + sc->ndis_txpending--; + + /* + * Set a timeout in case the chip goes out to lunch. + */ + sc->ndis_tx_timer = 5; + NDIS_UNLOCK(sc); + + /* + * According to NDIS documentation, if a driver exports + * a MiniportSendPackets() routine, we prefer that over + * a MiniportSend() routine (which sends just a single + * packet). + */ + if (sc->ndis_chars->nmc_sendmulti_func != NULL) + ndis_send_packets(sc, p0, 1); + else + ndis_send_packet(sc, p); + + return (0); +} + +static void +ndis_80211parent(struct ieee80211com *ic) +{ + struct ndis_softc *sc = ic->ic_softc; + + /*NDIS_LOCK(sc);*/ + if (ic->ic_nrunning > 0) { + if (!sc->ndis_running) + ndis_init(sc); + } else if (sc->ndis_running) + ndis_stop(sc); + /*NDIS_UNLOCK(sc);*/ +} + static void ndis_init(void *xsc) { struct ndis_softc *sc = xsc; - struct ifnet *ifp = sc->ifp; - struct ieee80211com *ic = ifp->if_l2com; int i, len, error; /* @@ -1936,17 +2140,21 @@ ndis_init(void *xsc) } } - /* Init our MAC address */ - /* Program the packet filter */ + sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED | + NDIS_PACKET_TYPE_BROADCAST; - sc->ndis_filter = NDIS_PACKET_TYPE_DIRECTED; + if (sc->ndis_80211) { + struct ieee80211com *ic = &sc->ndis_ic; - if (ifp->if_flags & IFF_BROADCAST) - sc->ndis_filter |= NDIS_PACKET_TYPE_BROADCAST; + if (ic->ic_promisc > 0) + sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS; + } else { + struct ifnet *ifp = sc->ifp; - if (ifp->if_flags & IFF_PROMISC) - sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS; + if (ifp->if_flags & IFF_PROMISC) + sc->ndis_filter |= NDIS_PACKET_TYPE_PROMISCUOUS; + } len = sizeof(sc->ndis_filter); @@ -1959,7 +2167,10 @@ ndis_init(void *xsc) /* * Set lookahead. */ - i = ifp->if_mtu; + if (sc->ndis_80211) + i = ETHERMTU; + else + i = sc->ifp->if_mtu; len = sizeof(i); ndis_set_info(sc, OID_GEN_CURRENT_LOOKAHEAD, &i, &len); @@ -1977,11 +2188,19 @@ ndis_init(void *xsc) sc->ndis_txpending = sc->ndis_maxpkts; sc->ndis_link = 0; - sc->ifp->if_link_state = LINK_STATE_UNKNOWN; - if_link_state_change(sc->ifp); + if (!sc->ndis_80211) { +#if defined(__DragonFly__) + sc->ifp->if_link_state = LINK_STATE_UNKNOWN; + if_link_state_change(sc->ifp); + sc->ifp->if_flags |= IFF_RUNNING; + ifq_clr_oactive(&sc->ifp->if_snd); +#else + if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN); + sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; +#endif + } - ifp->if_flags |= IFF_RUNNING; - ifq_clr_oactive(&ifp->if_snd); sc->ndis_tx_timer = 0; /* @@ -1995,11 +2214,12 @@ ndis_init(void *xsc) sc->ndis_hang_timer = sc->ndis_block->nmb_checkforhangsecs; callout_reset(&sc->ndis_stat_callout, hz, ndis_tick, sc); + sc->ndis_running = 1; NDIS_UNLOCK(sc); /* XXX force handling */ if (sc->ndis_80211) - ieee80211_start_all(ic); /* start all vap's */ + ieee80211_start_all(&sc->ndis_ic); /* start all vap's */ } /* @@ -2066,12 +2286,10 @@ ndis_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) static int ndis_set_cipher(struct ndis_softc *sc, int cipher) { - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->ndis_ic; int rval = 0, len; uint32_t arg, save; - ic = sc->ifp->if_l2com; - len = sizeof(arg); if (cipher == WPA_CSE_WEP40 || cipher == WPA_CSE_WEP104) { @@ -2197,7 +2415,7 @@ static void ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct ieee80211vap *vap = ifp->if_softc; - struct ndis_softc *sc = vap->iv_ic->ic_ifp->if_softc; + struct ndis_softc *sc = vap->iv_ic->ic_softc; uint32_t txrate; int len; @@ -2213,18 +2431,12 @@ ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr) static void ndis_setstate_80211(struct ndis_softc *sc) { - struct ieee80211com *ic; - struct ieee80211vap *vap; + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); ndis_80211_macaddr bssid; ndis_80211_config config; int rval = 0, len; uint32_t arg; - struct ifnet *ifp; - char ethstr[ETHER_ADDRSTRLEN + 1]; - - ifp = sc->ifp; - ic = ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); if (!NDIS_INITIALIZED(sc)) { DPRINTF(("%s: NDIS not initialized\n", __func__)); @@ -2259,7 +2471,7 @@ ndis_setstate_80211(struct ndis_softc *sc) /* Set TX power */ if ((ic->ic_caps & IEEE80211_C_TXPMGT) && - ic->ic_txpowlimit < NELEM(dBm2mW)) { + ic->ic_txpowlimit < nitems(dBm2mW)) { arg = dBm2mW[ic->ic_txpowlimit]; len = sizeof(arg); ndis_set_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len); @@ -2303,9 +2515,11 @@ ndis_setstate_80211(struct ndis_softc *sc) if (config.nc_fhconfig.ncf_dwelltime == 0) config.nc_fhconfig.ncf_dwelltime = 200; if (rval == 0 && ic->ic_bsschan != IEEE80211_CHAN_ANYC) { - int chan; + int chan, chanflag; chan = ieee80211_chan2ieee(ic, ic->ic_bsschan); + chanflag = config.nc_dsconfig > 2500000 ? IEEE80211_CHAN_2GHZ : + IEEE80211_CHAN_5GHZ; if (chan != ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0)) { config.nc_dsconfig = ic->ic_bsschan->ic_freq * 1000; @@ -2327,8 +2541,12 @@ ndis_setstate_80211(struct ndis_softc *sc) /* Set the BSSID to our value so the driver doesn't associate */ len = IEEE80211_ADDR_LEN; - bcopy(IF_LLADDR(ifp), bssid, len); - DPRINTF(("Setting BSSID to %s\n", kether_ntoa((uint8_t *)&bssid, ethstr))); + bcopy(vap->iv_myaddr, bssid, len); +#if defined(__DragonFly__) + DPRINTF(("Setting BSSID to %s\n", ether_sprintf(bssid))); +#else + DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":")); +#endif rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len); if (rval) device_printf(sc->ndis_dev, @@ -2338,17 +2556,12 @@ ndis_setstate_80211(struct ndis_softc *sc) static void ndis_auth_and_assoc(struct ndis_softc *sc, struct ieee80211vap *vap) { - struct ieee80211_node *ni; + struct ieee80211_node *ni = vap->iv_bss; ndis_80211_ssid ssid; ndis_80211_macaddr bssid; ndis_80211_wep wep; int i, rval = 0, len, error; uint32_t arg; - struct ifnet *ifp; - char ethstr[ETHER_ADDRSTRLEN + 1]; - - ifp = sc->ifp; - ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) { DPRINTF(("%s: NDIS not initialized\n", __func__)); @@ -2515,9 +2728,13 @@ ndis_auth_and_assoc(struct ndis_softc *sc, struct ieee80211vap *vap) vap->iv_opmode != IEEE80211_M_IBSS) bcopy(ni->ni_bssid, bssid, len); else - bcopy(ifp->if_broadcastaddr, bssid, len); + bcopy(ieee80211broadcastaddr, bssid, len); - DPRINTF(("Setting BSSID to %s\n", kether_ntoa((uint8_t *)&bssid, ethstr))); +#if defined(__DragonFly__) + DPRINTF(("Setting BSSID to %s\n", ether_sprintf(bssid))); +#else + DPRINTF(("Setting BSSID to %6D\n", (uint8_t *)&bssid, ":")); +#endif rval = ndis_set_info(sc, OID_802_11_BSSID, &bssid, &len); if (rval) device_printf(sc->ndis_dev, @@ -2555,14 +2772,14 @@ ndis_get_bssid_list(struct ndis_softc *sc, ndis_80211_bssid_list_ex **bl) int len, error; len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); - *bl = kmalloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + *bl = kmalloc(len, M_DEVBUF, M_INTWAIT | M_ZERO); if (*bl == NULL) return (ENOMEM); error = ndis_get_info(sc, OID_802_11_BSSID_LIST, *bl, &len); if (error == ENOSPC) { kfree(*bl, M_DEVBUF); - *bl = kmalloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + *bl = kmalloc(len, M_DEVBUF, M_INTWAIT | M_ZERO); if (*bl == NULL) return (ENOMEM); @@ -2580,8 +2797,7 @@ ndis_get_bssid_list(struct ndis_softc *sc, ndis_80211_bssid_list_ex **bl) static int ndis_get_assoc(struct ndis_softc *sc, ndis_wlan_bssid_ex **assoc) { - struct ifnet *ifp = sc->ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->ndis_ic; struct ieee80211vap *vap; struct ieee80211_node *ni; ndis_80211_bssid_list_ex *bl; @@ -2609,7 +2825,7 @@ ndis_get_assoc(struct ndis_softc *sc, ndis_wlan_bssid_ex **assoc) bs = (ndis_wlan_bssid_ex *)&bl->nblx_bssid[0]; for (i = 0; i < bl->nblx_items; i++) { if (bcmp(bs->nwbx_macaddr, bssid, sizeof(bssid)) == 0) { - *assoc = kmalloc(bs->nwbx_len, M_TEMP, M_NOWAIT); + *assoc = kmalloc(bs->nwbx_len, M_TEMP, M_INTWAIT); if (*assoc == NULL) { kfree(bl, M_TEMP); return (ENOMEM); @@ -2630,19 +2846,13 @@ ndis_get_assoc(struct ndis_softc *sc, ndis_wlan_bssid_ex **assoc) static void ndis_getstate_80211(struct ndis_softc *sc) { - struct ieee80211com *ic; - struct ieee80211vap *vap; - struct ieee80211_node *ni; + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211_node *ni = vap->iv_bss; ndis_wlan_bssid_ex *bs; int rval, len, i = 0; int chanflag; uint32_t arg; - struct ifnet *ifp; - - ifp = sc->ifp; - ic = ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); - ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) return; @@ -2677,7 +2887,7 @@ ndis_getstate_80211(struct ndis_softc *sc) if (ic->ic_caps & IEEE80211_C_TXPMGT) { len = sizeof(arg); ndis_get_info(sc, OID_802_11_TX_POWER_LEVEL, &arg, &len); - for (i = 0; i < NELEM(dBm2mW); i++) + for (i = 0; i < nitems(dBm2mW); i++) if (dBm2mW[i] >= arg) break; ic->ic_txpowlimit = i; @@ -2758,7 +2968,7 @@ ndis_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) switch (command) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_flags & IFF_RUNNING && + if (sc->ndis_running && ifp->if_flags & IFF_PROMISC && !(sc->ndis_if_flags & IFF_PROMISC)) { sc->ndis_filter |= @@ -2767,7 +2977,7 @@ ndis_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) error = ndis_set_info(sc, OID_GEN_CURRENT_PACKET_FILTER, &sc->ndis_filter, &i); - } else if (ifp->if_flags & IFF_RUNNING && + } else if (sc->ndis_running && !(ifp->if_flags & IFF_PROMISC) && sc->ndis_if_flags & IFF_PROMISC) { sc->ndis_filter &= @@ -2779,7 +2989,7 @@ ndis_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) } else ndis_init(sc); } else { - if (ifp->if_flags & IFF_RUNNING) + if (sc->ndis_running) ndis_stop(sc); } sc->ndis_if_flags = ifp->if_flags; @@ -2813,92 +3023,41 @@ ndis_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) } static int -ndis_ioctl_80211(struct ifnet *ifp, u_long command, caddr_t data, - struct ucred *cr) +ndis_80211ioctl(struct ieee80211com *ic, u_long cmd, void *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; - void *oidbuf; - int error = 0; + struct ndis_softc *sc = ic->ic_softc; + struct ifreq *ifr = data; + struct ndis_oid_data oid; + struct ndis_evt evt; + void *oidbuf = NULL; + int error = 0; + + if ((error = priv_check(curthread, PRIV_DRIVER)) != 0) + return (error); - switch (command) { - case SIOCSIFFLAGS: - /*NDIS_LOCK(sc);*/ - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_flags & IFF_RUNNING)) - ndis_init(sc); - } else { - if (ifp->if_flags & IFF_RUNNING) - ndis_stop(sc); - } - sc->ndis_if_flags = ifp->if_flags; - error = 0; - /*NDIS_UNLOCK(sc);*/ - break; + switch (cmd) { case SIOCGDRVSPEC: - if ((error = priv_check(curthread, PRIV_DRIVER))) - break; - error = copyin(ifr->ifr_data, &oid, sizeof(oid)); + case SIOCSDRVSPEC: + error = copyin(ifr->ifr_data, &oid, sizeof(oid)); if (error) break; - oidbuf = kmalloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO); - if (oidbuf == NULL) { - error = ENOMEM; - break; - } - error = copyin((caddr_t)ifr->ifr_data + sizeof(oid), oidbuf, oid.len); - if (error) { - kfree(oidbuf, M_TEMP); - break; - } - error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len); - if (error) { - kfree(oidbuf, M_TEMP); - break; - } - error = copyout(&oid, ifr->ifr_data, sizeof(oid)); - if (error) { - kfree(oidbuf, M_TEMP); - break; - } - error = copyout(oidbuf, (caddr_t)ifr->ifr_data + sizeof(oid), oid.len); + oidbuf = kmalloc(oid.len, M_TEMP, M_WAITOK | M_ZERO); + error = copyin((char *)ifr->ifr_data + sizeof(oid), oidbuf, oid.len); + } + + if (error) { kfree(oidbuf, M_TEMP); + return (error); + } + + switch (cmd) { + case SIOCGDRVSPEC: + error = ndis_get_info(sc, oid.oid, oidbuf, &oid.len); break; case SIOCSDRVSPEC: - if ((error = priv_check(curthread, PRIV_DRIVER))) - break; - error = copyin(ifr->ifr_data, &oid, sizeof(oid)); - if (error) - break; - oidbuf = kmalloc(oid.len, M_TEMP, M_NOWAIT|M_ZERO); - if (oidbuf == NULL) { - error = ENOMEM; - break; - } - error = copyin((caddr_t)ifr->ifr_data + sizeof(oid), oidbuf, oid.len); - if (error) { - kfree(oidbuf, M_TEMP); - break; - } error = ndis_set_info(sc, oid.oid, oidbuf, &oid.len); - if (error) { - kfree(oidbuf, M_TEMP); - break; - } - error = copyout(&oid, ifr->ifr_data, sizeof(oid)); - if (error) { - kfree(oidbuf, M_TEMP); - break; - } - error = copyout(oidbuf, (caddr_t)ifr->ifr_data + sizeof(oid), oid.len); - kfree(oidbuf, M_TEMP); break; case SIOCGPRIVATE_0: - if ((error = priv_check(curthread, PRIV_DRIVER))) - break; NDIS_LOCK(sc); if (sc->ndis_evt[sc->ndis_evtcidx].ne_sts == 0) { error = ENOENT; @@ -2937,28 +3096,32 @@ ndis_ioctl_80211(struct ifnet *ifp, u_long command, caddr_t data, NDIS_EVTINC(sc->ndis_evtcidx); NDIS_UNLOCK(sc); break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, command, data); - break; default: - error = EINVAL; + error = ENOTTY; break; } + + switch (cmd) { + case SIOCGDRVSPEC: + case SIOCSDRVSPEC: + error = copyout(&oid, ifr->ifr_data, sizeof(oid)); + if (error) + break; + error = copyout(oidbuf, (char *)ifr->ifr_data + sizeof(oid), oid.len); + } + + kfree(oidbuf, M_TEMP); + return (error); } int ndis_del_key(struct ieee80211vap *vap, const struct ieee80211_key *key) { - struct ndis_softc *sc; + struct ndis_softc *sc = vap->iv_ic->ic_softc; ndis_80211_key rkey; int len, error = 0; - sc = vap->iv_ic->ic_ifp->if_softc; - bzero((char *)&rkey, sizeof(rkey)); len = sizeof(rkey); @@ -2982,17 +3145,12 @@ ndis_del_key(struct ieee80211vap *vap, const struct ieee80211_key *key) * set after initial authentication with the AP. */ static int -ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key, - const uint8_t mac[IEEE80211_ADDR_LEN]) +ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key) { - struct ndis_softc *sc; - struct ifnet *ifp; + struct ndis_softc *sc = vap->iv_ic->ic_softc; ndis_80211_key rkey; int len, error = 0; - ifp = vap->iv_ic->ic_ifp; - sc = ifp->if_softc; - switch (key->wk_cipher->ic_cipher) { case IEEE80211_CIPHER_TKIP: @@ -3016,7 +3174,7 @@ ndis_add_key(struct ieee80211vap *vap, const struct ieee80211_key *key, rkey.nk_keyidx |= 1 << 31; if (key->wk_flags & IEEE80211_KEY_GROUP) { - bcopy(ifp->if_broadcastaddr, + bcopy(ieee80211broadcastaddr, rkey.nk_bssid, IEEE80211_ADDR_LEN); } else { bcopy(vap->iv_bss->ni_bssid, @@ -3077,17 +3235,22 @@ ndis_resettask(device_object *d, void *arg) static void ndis_stop(struct ndis_softc *sc) { - struct ifnet *ifp; int i; - ifp = sc->ifp; - callout_stop_sync(&sc->ndis_stat_callout); + callout_drain(&sc->ndis_stat_callout); NDIS_LOCK(sc); sc->ndis_tx_timer = 0; sc->ndis_link = 0; - ifp->if_flags &= ~IFF_RUNNING; - ifq_clr_oactive(&ifp->if_snd); + if (!sc->ndis_80211) { +#if defined(__DragonFly__) + sc->ifp->if_flags &= ~IFF_RUNNING; + ifq_clr_oactive(&sc->ifp->if_snd); +#else + sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); +#endif + } + sc->ndis_running = 0; NDIS_UNLOCK(sc); if (sc->ndis_iftype != PNPBus || @@ -3119,10 +3282,8 @@ ndis_shutdown(device_t dev) { struct ndis_softc *sc; - wlan_serialize_enter(); sc = device_get_softc(dev); ndis_stop(sc); - wlan_serialize_exit(); } static int @@ -3130,8 +3291,7 @@ 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; + struct ndis_softc *sc = ic->ic_softc; enum ieee80211_state ostate; DPRINTF(("%s: %s -> %s\n", __func__, @@ -3148,17 +3308,17 @@ ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) return nvp->newstate(vap, nstate, arg); case IEEE80211_S_ASSOC: if (ostate != IEEE80211_S_AUTH) { - wlan_serialize_exit(); + IEEE80211_UNLOCK(ic); ndis_auth_and_assoc(sc, vap); - wlan_serialize_enter(); + IEEE80211_LOCK(ic); } break; case IEEE80211_S_AUTH: - wlan_serialize_exit(); + IEEE80211_UNLOCK(ic); ndis_auth_and_assoc(sc, vap); if (vap->iv_state == IEEE80211_S_AUTH) /* XXX */ ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0); - wlan_serialize_enter(); + IEEE80211_LOCK(ic); break; default: break; @@ -3177,8 +3337,8 @@ ndis_scan(void *arg) static void ndis_scan_results(struct ndis_softc *sc) { - struct ieee80211com *ic; - struct ieee80211vap *vap; + struct ieee80211com *ic = &sc->ndis_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); ndis_80211_bssid_list_ex *bl; ndis_wlan_bssid_ex *wb; struct ieee80211_scanparams sp; @@ -3189,10 +3349,7 @@ ndis_scan_results(struct ndis_softc *sc) uint8_t ssid[2+IEEE80211_NWID_LEN]; uint8_t rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t *frm, *efrm; - char ethstr[ETHER_ADDRSTRLEN + 1]; - ic = sc->ifp->if_l2com; - vap = TAILQ_FIRST(&ic->ic_vaps); saved_chan = ic->ic_curchan; noise = -96; @@ -3228,7 +3385,7 @@ ndis_scan_results(struct ndis_softc *sc) wb->nwbx_supportedrates[j] & 0x7f; } rates[1] = j; - sp.ssid = &ssid[0]; + sp.ssid = (uint8_t *)&ssid[0]; memcpy(sp.ssid + 2, &wb->nwbx_ssid.ns_ssid, wb->nwbx_ssid.ns_ssidlen); sp.ssid[1] = wb->nwbx_ssid.ns_ssidlen; @@ -3255,7 +3412,7 @@ ndis_scan_results(struct ndis_softc *sc) } done: DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n", - kether_ntoa(wb->nwbx_macaddr, ethstr), freq, sp.bchan, chanflag, + ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag, rssi)); ieee80211_add_scan(vap, ic->ic_curchan, &sp, &wh, 0, rssi, noise); wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); @@ -3268,8 +3425,7 @@ done: static void ndis_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ndis_softc *sc = ifp->if_softc; + struct ndis_softc *sc = ic->ic_softc; struct ieee80211vap *vap; struct ieee80211_scan_state *ss; ndis_80211_ssid ssid; @@ -3330,7 +3486,7 @@ ndis_scan_mindwell(struct ieee80211_scan_state *ss) static void ndis_scan_end(struct ieee80211com *ic) { - struct ndis_softc *sc = ic->ic_ifp->if_softc; + struct ndis_softc *sc = ic->ic_softc; ndis_scan_results(sc); } diff --git a/sys/dev/netif/ndis/if_ndis_pccard.c b/sys/dev/netif/ndis/if_ndis_pccard.c index 3e7a9b4905..5ebab77d6f 100644 --- a/sys/dev/netif/ndis/if_ndis_pccard.c +++ b/sys/dev/netif/ndis/if_ndis_pccard.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/if_ndis/if_ndis_pccard.c,v 1.21 2012/11/17 01:51:54 svnexp Exp $ + * $FreeBSD: head/sys/dev/if_ndis/if_ndis_pccard.c 296137 2016-02-27 03:38:01Z jhibbits $ */ #include @@ -43,32 +43,59 @@ #include #include +#include #include #include +#include +#if !defined(__DragonFly__) +#include +#include +#endif #include #include -#include - +#if defined(__DragonFly__) #include #include +#else +#include +#include +#endif + +#if defined(__DragonFly__) +#include +#else +#include +#endif +#if defined(__DragonFly__) #include #include #include #include #include #include - +#else +#include +#include +#include +#include +#include +#include +#endif + +#if defined(__DragonFly__) #include +#else +#include +#endif #include "card_if.h" MODULE_DEPEND(if_ndis, pccard, 1, 1, 1); static int ndis_probe_pccard (device_t); static int ndis_attach_pccard (device_t); -static int ndis_detach_pccard (device_t); static struct resource_list *ndis_get_resource_list (device_t, device_t); static int ndis_devcompare (interface_type, @@ -86,7 +113,7 @@ static device_method_t ndis_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ndis_probe_pccard), DEVMETHOD(device_attach, ndis_attach_pccard), - DEVMETHOD(device_detach, ndis_detach_pccard), + DEVMETHOD(device_detach, ndis_detach), DEVMETHOD(device_shutdown, ndis_shutdown), DEVMETHOD(device_suspend, ndis_suspend), DEVMETHOD(device_resume, ndis_resume), @@ -118,12 +145,24 @@ ndis_devcompare(interface_type bustype, struct ndis_pccard_type *t, device_t dev) { const char *prodstr, *vendstr; +#if !defined(__DragonFly__) + int error; +#endif if (bustype != PCMCIABus) return(FALSE); +#if defined(__DragonFly__) prodstr = pccard_get_product_str(dev); vendstr = pccard_get_vendor_str(dev); +#else + error = pccard_get_product_str(dev, &prodstr); + if (error) + return(FALSE); + error = pccard_get_vendor_str(dev, &vendstr); + if (error) + return(FALSE); +#endif while(t->ndis_name != NULL) { if (strcasecmp(vendstr, t->ndis_vid) == 0 && @@ -170,21 +209,19 @@ static int ndis_attach_pccard(device_t dev) { struct ndis_softc *sc; - int error = 0, rid; + int unit, error = 0, rid; struct ndis_pccard_type *t; int devidx = 0; const char *prodstr, *vendstr; struct drvdb_ent *db; - wlan_serialize_enter(); sc = device_get_softc(dev); + unit = device_get_unit(dev); sc->ndis_dev = dev; db = windrv_match((matchfuncptr)ndis_devcompare, dev); - if (db == NULL) { - wlan_serialize_exit(); + if (db == NULL) return (ENXIO); - } sc->ndis_dobj = db->windrv_object; sc->ndis_regvals = db->windrv_regvals; resource_list_init(&sc->ndis_rl); @@ -199,9 +236,15 @@ ndis_attach_pccard(device_t dev) goto fail; } sc->ndis_rescnt++; +#if defined(__DragonFly__) resource_list_add(&sc->ndis_rl, SYS_RES_IOPORT, sc->ndis_io_rid, rman_get_start(sc->ndis_res_io), rman_get_end(sc->ndis_res_io), rman_get_size(sc->ndis_res_io), -1); +#else + resource_list_add(&sc->ndis_rl, SYS_RES_IOPORT, sc->ndis_io_rid, + rman_get_start(sc->ndis_res_io), rman_get_end(sc->ndis_res_io), + rman_get_size(sc->ndis_res_io)); +#endif rid = 0; sc->ndis_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, @@ -213,9 +256,14 @@ ndis_attach_pccard(device_t dev) goto fail; } sc->ndis_rescnt++; +#if defined(__DragonFly__) resource_list_add(&sc->ndis_rl, SYS_RES_IRQ, rid, rman_get_start(sc->ndis_irq), rman_get_start(sc->ndis_irq), 1, rman_get_cpuid(sc->ndis_irq)); +#else + resource_list_add(&sc->ndis_rl, SYS_RES_IRQ, rid, + rman_get_start(sc->ndis_irq), rman_get_start(sc->ndis_irq), 1); +#endif sc->ndis_iftype = PCMCIABus; @@ -223,8 +271,17 @@ ndis_attach_pccard(device_t dev) t = db->windrv_devlist; +#if defined(__DragonFly__) prodstr = pccard_get_product_str(dev); vendstr = pccard_get_vendor_str(dev); +#else + error = pccard_get_product_str(dev, &prodstr); + if (error) + return(error); + error = pccard_get_vendor_str(dev, &vendstr); + if (error) + return(error); +#endif while(t->ndis_name != NULL) { if (strcasecmp(vendstr, t->ndis_vid) == 0 && @@ -239,18 +296,6 @@ ndis_attach_pccard(device_t dev) error = ndis_attach(dev); fail: - wlan_serialize_exit(); - return(error); -} - -static int -ndis_detach_pccard(device_t dev) -{ - int error = 0; - - wlan_serialize_enter(); - error = ndis_detach(dev); - wlan_serialize_exit(); return(error); } @@ -276,8 +321,13 @@ ndis_alloc_amem(void *arg) sc = arg; rid = NDIS_AM_RID; +#if defined(__DragonFly__) sc->ndis_res_am = bus_alloc_resource(sc->ndis_dev, SYS_RES_MEMORY, &rid, 0UL, ~0UL, 0x1000, RF_ACTIVE); +#else + sc->ndis_res_am = bus_alloc_resource_anywhere(sc->ndis_dev, + SYS_RES_MEMORY, &rid, 0x1000, RF_ACTIVE); +#endif if (sc->ndis_res_am == NULL) { device_printf(sc->ndis_dev, @@ -285,9 +335,15 @@ ndis_alloc_amem(void *arg) return(ENXIO); } sc->ndis_rescnt++; +#if defined(__DragonFly__) resource_list_add(&sc->ndis_rl, SYS_RES_MEMORY, rid, rman_get_start(sc->ndis_res_am), rman_get_end(sc->ndis_res_am), rman_get_size(sc->ndis_res_am), -1); +#else + resource_list_add(&sc->ndis_rl, SYS_RES_MEMORY, rid, + rman_get_start(sc->ndis_res_am), rman_get_end(sc->ndis_res_am), + rman_get_size(sc->ndis_res_am)); +#endif error = CARD_SET_MEMORY_OFFSET(device_get_parent(sc->ndis_dev), sc->ndis_dev, rid, 0, NULL); diff --git a/sys/dev/netif/ndis/if_ndis_pci.c b/sys/dev/netif/ndis/if_ndis_pci.c index 45ad02415f..12bd734b8c 100644 --- a/sys/dev/netif/ndis/if_ndis_pci.c +++ b/sys/dev/netif/ndis/if_ndis_pci.c @@ -29,12 +29,13 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/if_ndis/if_ndis_pci.c,v 1.26 2010/12/19 11:14:34 tijl Exp $ + * $FreeBSD: head/sys/dev/if_ndis/if_ndis_pci.c 292411 2015-12-17 21:01:19Z glebius $ */ #include #include #include +#include #include #include #include @@ -42,31 +43,56 @@ #include #include +#include #include #include +#include +#if !defined(__DragonFly__) +#include +#include +#endif #include #include +#if defined(__DragonFly__) #include +#else +#include +#endif +#if defined(__DragonFly__) #include #include #include #include - +#else +#include +#include +#include +#include +#endif + +#if defined(__DragonFly__) #include #include #include #include #include #include +#else +#include +#include +#include +#include +#include +#include +#endif MODULE_DEPEND(if_ndis, pci, 1, 1, 1); static int ndis_probe_pci (device_t); static int ndis_attach_pci (device_t); -static int ndis_detach_pci (device_t); static struct resource_list *ndis_get_resource_list (device_t, device_t); static int ndis_devcompare (interface_type, @@ -82,7 +108,7 @@ static device_method_t ndis_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ndis_probe_pci), DEVMETHOD(device_attach, ndis_attach_pci), - DEVMETHOD(device_detach, ndis_detach_pci), + DEVMETHOD(device_detach, ndis_detach), DEVMETHOD(device_shutdown, ndis_shutdown), DEVMETHOD(device_suspend, ndis_suspend), DEVMETHOD(device_resume, ndis_resume), @@ -101,8 +127,7 @@ static driver_t ndis_driver = { static devclass_t ndis_devclass; -DRIVER_MODULE(if_ndis, pci, ndis_driver, ndis_devclass, ndisdrv_modevent, NULL); -DRIVER_MODULE(if_ndis, cardbus, ndis_driver, ndis_devclass, ndisdrv_modevent, NULL); +DRIVER_MODULE(if_ndis, pci, ndis_driver, ndis_devclass, ndisdrv_modevent, 0); static int ndis_devcompare(interface_type bustype, struct ndis_pci_type *t, device_t dev) @@ -164,7 +189,7 @@ static int ndis_attach_pci(device_t dev) { struct ndis_softc *sc; - int error = 0, rid; + int unit, error = 0, rid; struct ndis_pci_type *t; int devidx = 0, defidx = 0; struct resource_list *rl; @@ -173,16 +198,13 @@ ndis_attach_pci(device_t dev) uint16_t vid, did; uint32_t subsys; - wlan_serialize_enter(); - sc = device_get_softc(dev); + unit = device_get_unit(dev); sc->ndis_dev = dev; db = windrv_match((matchfuncptr)ndis_devcompare, dev); - if (db == NULL) { - wlan_serialize_exit(); + if (db == NULL) return (ENXIO); - } sc->ndis_dobj = db->windrv_object; sc->ndis_regvals = db->windrv_regvals; @@ -293,7 +315,7 @@ ndis_attach_pci(device_t dev) BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - MAXBSIZE, NDIS_NSEG_NEW,/* maxsize, nsegments */ + DFLTPHYS, NDIS_NSEG_NEW,/* maxsize, nsegments */ BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ BUS_DMA_ALLOCNOW, /* flags */ &sc->ndis_parent_tag); @@ -331,18 +353,6 @@ ndis_attach_pci(device_t dev) error = ndis_attach(dev); fail: - wlan_serialize_exit(); - return(error); -} - -static int -ndis_detach_pci(device_t dev) -{ - int error = 0; - - wlan_serialize_enter(); - error = ndis_detach(dev); - wlan_serialize_exit(); return(error); } diff --git a/sys/dev/netif/ndis/if_ndis_u4b.c b/sys/dev/netif/ndis/if_ndis_u4b.c index dd5cb6cbaa..3d5e4a5854 100644 --- a/sys/dev/netif/ndis/if_ndis_u4b.c +++ b/sys/dev/netif/ndis/if_ndis_u4b.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/if_ndis/if_ndis_usb.c,v 1.26 2012/11/17 01:51:54 svnexp Exp $ + * $FreeBSD: head/sys/dev/if_ndis/if_ndis_usb.c 257176 2013-10-26 17:58:36Z glebius $ */ #include @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -50,11 +51,22 @@ #include #include +#if defined(__DragonFly__) #include #include +#else +#include +#include +#include +#endif +#if defined(__DragonFly__) #include +#else +#include +#endif +#if defined(__DragonFly__) #include #include #include @@ -62,6 +74,15 @@ #include #include #include +#else +#include +#include +#include +#include +#include +#include +#include +#endif SYSCTL_NODE(_hw, OID_AUTO, ndisusb, CTLFLAG_RD, 0, "NDIS USB driver parameters"); @@ -166,7 +187,11 @@ ndisusb_attach(device_t self) db = uaa->driver_ivar; sc = (struct ndis_softc *)dummy; sc->ndis_dev = self; +#if defined(__DragonFly__) lockinit(&sc->ndisusb_lock, "NDIS USB", 0, LK_CANRECURSE); +#else + mtx_init(&sc->ndisusb_mtx, "NDIS USB", MTX_NETWORK_LOCK, MTX_DEF); +#endif sc->ndis_dobj = db->windrv_object; sc->ndis_regvals = db->windrv_regvals; sc->ndis_iftype = PNPBus; @@ -219,7 +244,11 @@ ndisusb_detach(device_t self) (void)ndis_detach(self); +#if defined(__DragonFly__) lockuninit(&sc->ndisusb_lock); +#else + mtx_destroy(&sc->ndisusb_mtx); +#endif return (0); } diff --git a/sys/dev/netif/ndis/if_ndisvar.h b/sys/dev/netif/ndis/if_ndisvar.h index 541342752e..94e4d7c835 100644 --- a/sys/dev/netif/ndis/if_ndisvar.h +++ b/sys/dev/netif/ndis/if_ndisvar.h @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/if_ndis/if_ndisvar.h,v 1.39 2009/05/02 15:14:18 thompsa Exp $ + * $FreeBSD: head/sys/dev/if_ndis/if_ndisvar.h 287197 2015-08-27 08:56:39Z glebius $ */ #define NDIS_DEFAULT_NODENAME "FreeBSD NDIS node" @@ -152,8 +152,22 @@ struct ndisusb_task { }; struct ndis_softc { - struct ifnet *ifp; - struct ifmedia ifmedia; /* media info */ + u_int ndis_80211:1, + ndis_link:1, + ndis_running:1; + union { + struct { /* Ethernet */ + struct ifnet *ifp; + struct ifmedia ifmedia; + int ndis_if_flags; + }; + struct { /* Wireless */ + struct ieee80211com ndis_ic; + struct callout ndis_scan_callout; + int (*ndis_newstate)(struct ieee80211com *, + enum ieee80211_state, int); + }; + }; u_long ndis_hwassist; uint32_t ndis_v4tx; uint32_t ndis_v4rx; @@ -173,14 +187,17 @@ struct ndis_softc { struct resource *ndis_res_cm; /* common mem (pccard) */ struct resource_list ndis_rl; int ndis_rescnt; +#if defined(__DragonFly__) struct lock ndis_lock; +#else + struct mtx ndis_mtx; +#endif uint8_t ndis_irql; device_t ndis_dev; int ndis_unit; ndis_miniport_block *ndis_block; ndis_miniport_characteristics *ndis_chars; interface_type ndis_type; - struct callout ndis_scan_callout; struct callout ndis_stat_callout; int ndis_maxpkts; ndis_oid *ndis_oids; @@ -192,13 +209,9 @@ struct ndis_softc { int ndis_sc; ndis_cfg *ndis_regvals; struct nch ndis_cfglist_head; - int ndis_80211; - int ndis_link; uint32_t ndis_sts; uint32_t ndis_filter; - int ndis_if_flags; int ndis_skip; - int ndis_devidx; interface_type ndis_iftype; driver_object *ndis_dobj; @@ -217,16 +230,18 @@ struct ndis_softc { struct ndis_evt ndis_evt[NDIS_EVENTS]; int ndis_evtpidx; int ndis_evtcidx; - struct ifqueue ndis_rxqueue; + struct mbufq ndis_rxqueue; kspin_lock ndis_rxlock; - int (*ndis_newstate)(struct ieee80211com *, - enum ieee80211_state, int); int ndis_tx_timer; int ndis_hang_timer; struct usb_device *ndisusb_dev; +#if defined(__DragonFly__) struct lock ndisusb_lock; +#else + struct mtx ndisusb_mtx; +#endif struct ndisusb_ep ndisusb_dread_ep; struct ndisusb_ep ndisusb_dwrite_ep; #define NDISUSB_GET_ENDPT(addr) \ @@ -244,6 +259,7 @@ struct ndis_softc { #define NDISUSB_STATUS_SETUP_EP 0x2 }; +#if defined(__DragonFly__) #define NDIS_LOCK(_sc) lockmgr(&(_sc)->ndis_lock, LK_EXCLUSIVE) #define NDIS_UNLOCK(_sc) lockmgr(&(_sc)->ndis_lock, LK_RELEASE) #define NDISMTX_LOCK NDIS_LOCK @@ -252,3 +268,11 @@ struct ndis_softc { #define NDISUSB_LOCK(_sc) lockmgr(&(_sc)->ndisusb_lock, LK_EXCLUSIVE) #define NDISUSB_UNLOCK(_sc) lockmgr(&(_sc)->ndisusb_lock, LK_RELEASE) #define NDISUSB_LOCK_ASSERT(_sc, t) KKASSERT(lockstatus(&(_sc)->ndisusb_lock, curthread) != 0) +#else +#define NDIS_LOCK(_sc) mtx_lock(&(_sc)->ndis_mtx) +#define NDIS_UNLOCK(_sc) mtx_unlock(&(_sc)->ndis_mtx) +#define NDIS_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndis_mtx, t) +#define NDISUSB_LOCK(_sc) mtx_lock(&(_sc)->ndisusb_mtx) +#define NDISUSB_UNLOCK(_sc) mtx_unlock(&(_sc)->ndisusb_mtx) +#define NDISUSB_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndisusb_mtx, t) +#endif -- 2.11.4.GIT