From 1a9f01e8edd63aa8a3a43ff0b563012dc0fe547d Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 14 Jul 2018 13:58:51 -0400 Subject: [PATCH] iprowifi2100: Sync with FreeBSD 11.1. Untested, but mostly just changes to adapt to the new net80211 stack. --- .../kernel/drivers/network/wlan/Jamfile | 2 +- .../drivers/network/wlan/iprowifi2100/Jamfile | 14 +- .../wlan/iprowifi2100/dev/ipw/if_ipw.c | 370 ++++++++---------- .../wlan/iprowifi2100/dev/ipw/if_ipwreg.h | 2 +- .../wlan/iprowifi2100/dev/ipw/if_ipwvar.h | 10 +- .../drivers/network/wlan/iprowifi2100/glue.c | 7 +- 6 files changed, 176 insertions(+), 229 deletions(-) diff --git a/src/add-ons/kernel/drivers/network/wlan/Jamfile b/src/add-ons/kernel/drivers/network/wlan/Jamfile index 6ad47c1024..0a1233a7b4 100644 --- a/src/add-ons/kernel/drivers/network/wlan/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/Jamfile @@ -1,7 +1,6 @@ SubDir HAIKU_TOP src add-ons kernel drivers network wlan ; # FreeBSD 9.2 drivers -SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan marvell88w8335 ; # FreeBSD 9.3 drivers @@ -13,6 +12,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network wlan wavelanwifi ; # FreeBSD 11.1 drivers SubInclude HAIKU_TOP src add-ons kernel drivers network wlan aironetwifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan atheroswifi ; +SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi3945 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi4965 ; diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/Jamfile b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/Jamfile index 6970487047..2b862ba8d3 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/Jamfile @@ -1,14 +1,14 @@ SubDir HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ; -UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ] : true ; -UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_wlan ] : true ; UsePrivateHeaders net system ; UsePrivateKernelHeaders ; -SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] - -Wno-format - -Wno-unused +SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] + -Wno-format + -Wno-unused -Wno-uninitialized ; UseHeaders [ FDirName $(SUBDIR) ] : true ; @@ -19,8 +19,8 @@ KernelAddon iprowifi2100 : if_ipw.c glue.c : - libfreebsd_wlan.a - libfreebsd_network.a + libfreebsd11_wlan.a + libfreebsd11_network.a ; # Note: Due to licensing restrictions, we can only distribute the archive. diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c index 4ffba3d826..bb137de5d9 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipw.c @@ -1,5 +1,3 @@ -/* $FreeBSD$ */ - /*- * Copyright (c) 2004-2006 * Damien Bergamini . All rights reserved. @@ -30,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: releng/11.1/sys/dev/ipw/if_ipw.c 300239 2016-05-19 22:19:35Z avos $"); /*- * Intel(R) PRO/Wireless 2100 MiniPCI driver @@ -62,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -117,6 +116,7 @@ static void ipw_release(struct ipw_softc *); static void ipw_media_status(struct ifnet *, struct ifmediareq *); static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int); static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t); +static uint16_t ipw_read_chanmask(struct ipw_softc *); static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *); static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); static void ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *, @@ -128,14 +128,14 @@ static void ipw_intr(void *); static void ipw_dma_map_addr(void *, bus_dma_segment_t *, int, int); static const char * ipw_cmdname(int); static int ipw_cmd(struct ipw_softc *, uint32_t, void *, uint32_t); -static int ipw_tx_start(struct ifnet *, struct mbuf *, +static int ipw_tx_start(struct ipw_softc *, struct mbuf *, struct ieee80211_node *); static int ipw_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void ipw_start(struct ifnet *); -static void ipw_start_locked(struct ifnet *); +static int ipw_transmit(struct ieee80211com *, struct mbuf *); +static void ipw_start(struct ipw_softc *); static void ipw_watchdog(void *); -static int ipw_ioctl(struct ifnet *, u_long, caddr_t); +static void ipw_parent(struct ieee80211com *); static void ipw_stop_master(struct ipw_softc *); static int ipw_enable(struct ipw_softc *); static int ipw_disable(struct ipw_softc *); @@ -165,6 +165,8 @@ static void ipw_write_mem_1(struct ipw_softc *, bus_size_t, static int ipw_scan(struct ipw_softc *); static void ipw_scan_start(struct ieee80211com *); static void ipw_scan_end(struct ieee80211com *); +static void ipw_getradiocaps(struct ieee80211com *, int, int *, + struct ieee80211_channel[]); static void ipw_set_channel(struct ieee80211com *); static void ipw_scan_curchan(struct ieee80211_scan_state *, unsigned long maxdwell); @@ -186,7 +188,7 @@ static device_method_t ipw_methods[] = { DEVMETHOD(device_suspend, ipw_suspend), DEVMETHOD(device_resume, ipw_resume), - { 0, 0 } + DEVMETHOD_END }; static driver_t ipw_driver = { @@ -197,7 +199,7 @@ static driver_t ipw_driver = { static devclass_t ipw_devclass; -DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, 0, 0); +DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, NULL, NULL); MODULE_VERSION(ipw, 1); @@ -210,48 +212,36 @@ ipw_probe(device_t dev) if (pci_get_vendor(dev) == ident->vendor && pci_get_device(dev) == ident->device) { device_set_desc(dev, ident->name); - return 0; + return (BUS_PROBE_DEFAULT); } } return ENXIO; } /* Base Address Register */ -#define IPW_PCI_BAR0 0x10 - static int ipw_attach(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ifnet *ifp; - struct ieee80211com *ic; - struct ieee80211_channel *c; + struct ieee80211com *ic = &sc->sc_ic; uint16_t val; int error, i; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); - + mbufq_init(&sc->sc_snd, ifqmaxlen); TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); - if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { - device_printf(dev, "chip is in D%d power mode " - "-- setting to D0\n", pci_get_powerstate(dev)); - pci_set_powerstate(dev, PCI_POWERSTATE_D0); - } - pci_write_config(dev, 0x41, 0, 1); /* enable bus-mastering */ pci_enable_busmaster(dev); - sc->mem_rid = IPW_PCI_BAR0; - sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, - RF_ACTIVE); + i = PCIR_BAR(0); + sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &i, RF_ACTIVE); if (sc->mem == NULL) { device_printf(dev, "could not allocate memory resource\n"); goto fail; @@ -260,8 +250,8 @@ ipw_attach(device_t dev) sc->sc_st = rman_get_bustag(sc->mem); sc->sc_sh = rman_get_bushandle(sc->mem); - sc->irq_rid = 0; - sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, + i = 0; + sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i, RF_ACTIVE | RF_SHAREABLE); if (sc->irq == NULL) { device_printf(dev, "could not allocate interrupt resource\n"); @@ -278,24 +268,8 @@ ipw_attach(device_t dev) goto fail2; } - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - goto fail3; - } - ic = ifp->if_l2com; - - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = ipw_init; - ifp->if_ioctl = ipw_ioctl; - ifp->if_start = ipw_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - 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; @@ -311,42 +285,35 @@ ipw_attach(device_t dev) /* read MAC address from EEPROM */ val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 0); - macaddr[0] = val >> 8; - macaddr[1] = val & 0xff; + ic->ic_macaddr[0] = val >> 8; + ic->ic_macaddr[1] = val & 0xff; val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 1); - macaddr[2] = val >> 8; - macaddr[3] = val & 0xff; + ic->ic_macaddr[2] = val >> 8; + ic->ic_macaddr[3] = val & 0xff; val = ipw_read_prom_word(sc, IPW_EEPROM_MAC + 2); - macaddr[4] = val >> 8; - macaddr[5] = val & 0xff; + ic->ic_macaddr[4] = val >> 8; + ic->ic_macaddr[5] = val & 0xff; - /* set supported .11b channels (read from EEPROM) */ - if ((val = ipw_read_prom_word(sc, IPW_EEPROM_CHANNEL_LIST)) == 0) - val = 0x7ff; /* default to channels 1-11 */ - val <<= 1; - for (i = 1; i < 16; i++) { - if (val & (1 << i)) { - c = &ic->ic_channels[ic->ic_nchans++]; - c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); - c->ic_flags = IEEE80211_CHAN_B; - c->ic_ieee = i; - } - } + sc->chanmask = ipw_read_chanmask(sc); + ipw_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, + ic->ic_channels); /* check support for radio transmitter switch in EEPROM */ if (!(ipw_read_prom_word(sc, IPW_EEPROM_RADIO) & 8)) sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH; - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_scan_start = ipw_scan_start; ic->ic_scan_end = ipw_scan_end; + ic->ic_getradiocaps = ipw_getradiocaps; ic->ic_set_channel = ipw_set_channel; ic->ic_scan_curchan = ipw_scan_curchan; ic->ic_scan_mindwell = ipw_scan_mindwell; ic->ic_raw_xmit = ipw_raw_xmit; - ic->ic_vap_create = ipw_vap_create; ic->ic_vap_delete = ipw_vap_delete; + ic->ic_transmit = ipw_transmit; + ic->ic_parent = ipw_parent; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -374,21 +341,20 @@ ipw_attach(device_t dev) NULL, ipw_intr, sc, &sc->sc_ih); if (error != 0) { device_printf(dev, "could not set up interrupt\n"); - goto fail4; + goto fail3; } if (bootverbose) ieee80211_announce(ic); return 0; -fail4: - if_free(ifp); fail3: ipw_release(sc); fail2: - bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); + bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq), sc->irq); fail1: - bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); + bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem), + sc->mem); fail: mtx_destroy(&sc->sc_mtx); return ENXIO; @@ -398,8 +364,9 @@ static int ipw_detach(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + + bus_teardown_intr(dev, sc->irq, sc->sc_ih); ieee80211_draintask(ic, &sc->sc_init_task); ipw_stop(sc); @@ -407,15 +374,14 @@ ipw_detach(device_t dev) ieee80211_ifdetach(ic); callout_drain(&sc->sc_wdtimer); + mbufq_drain(&sc->sc_snd); ipw_release(sc); - bus_teardown_intr(dev, sc->irq, sc->sc_ih); - bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); + bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq), sc->irq); - bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); - - if_free(ifp); + bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->mem), + sc->mem); if (sc->sc_firmware != NULL) { firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); @@ -433,8 +399,7 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; struct ipw_vap *ivp; struct ieee80211vap *vap; const struct firmware *fp; @@ -492,19 +457,17 @@ ipw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, return NULL; } - ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (ivp == NULL) - return NULL; + ivp = malloc(sizeof(struct ipw_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &ivp->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 */ ivp->newstate = vap->iv_newstate; vap->iv_newstate = ipw_newstate; /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status, + mac); ic->ic_opmode = opmode; return vap; } @@ -758,11 +721,8 @@ ipw_release(struct ipw_softc *sc) } if (sc->tbd_dmat != NULL) { - if (sc->stbd_list != NULL) { - bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map); - bus_dmamem_free(sc->tbd_dmat, sc->tbd_list, - sc->tbd_map); - } + bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map); + bus_dmamem_free(sc->tbd_dmat, sc->tbd_list, sc->tbd_map); bus_dma_tag_destroy(sc->tbd_dmat); } @@ -835,7 +795,7 @@ static int ipw_suspend(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ieee80211_suspend_all(ic); return 0; @@ -845,7 +805,7 @@ static int ipw_resume(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; pci_write_config(dev, 0x41, 0, 1); @@ -874,7 +834,7 @@ ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr) { struct ieee80211vap *vap = ifp->if_softc; struct ieee80211com *ic = vap->iv_ic; - struct ipw_softc *sc = ic->ic_ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; /* read current transmission rate from adapter */ vap->iv_bss->ni_txrate = ipw_cvtrate( @@ -887,8 +847,7 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct ipw_vap *ivp = IPW_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; enum ieee80211_state ostate; DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, @@ -1001,6 +960,19 @@ ipw_read_prom_word(struct ipw_softc *sc, uint8_t addr) return le16toh(val); } +static uint16_t +ipw_read_chanmask(struct ipw_softc *sc) +{ + uint16_t val; + + /* set supported .11b channels (read from EEPROM) */ + if ((val = ipw_read_prom_word(sc, IPW_EEPROM_CHANNEL_LIST)) == 0) + val = 0x7ff; /* default to channels 1-11 */ + val <<= 1; + + return (val); +} + static void ipw_rx_cmd_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) { @@ -1023,8 +995,7 @@ static void ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) { #define IEEESTATE(vap) ieee80211_state_name[vap->iv_state] - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t state; @@ -1126,8 +1097,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) static void ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; ic->ic_curchan = chan; ieee80211_radiotap_chan_change(ic); @@ -1140,8 +1110,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) static void ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *c; struct ieee80211_frame *wh; uint8_t subtype; @@ -1186,8 +1155,7 @@ static void ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct mbuf *mnew, *m; struct ieee80211_node *ni; bus_addr_t physaddr; @@ -1209,7 +1177,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -1230,7 +1198,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); return; } @@ -1241,9 +1209,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, m = sbuf->m; sbuf->m = mnew; sbd->bd->physaddr = htole32(physaddr); - - /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = le32toh(status->len); rssi = status->rssi + IPW_RSSI_TO_DBM; @@ -1372,7 +1337,6 @@ ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd) static void ipw_tx_intr(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct ipw_soft_bd *sbd; uint32_t r, i; @@ -1383,10 +1347,6 @@ ipw_tx_intr(struct ipw_softc *sc) for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD) { sbd = &sc->stbd_list[i]; - - if (sbd->type == IPW_SBD_TYPE_DATA) - ifp->if_opackets++; - ipw_release_sbd(sc, sbd); sc->txfree++; } @@ -1394,15 +1354,13 @@ ipw_tx_intr(struct ipw_softc *sc) /* remember what the firmware has processed */ sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ipw_start_locked(ifp); + ipw_start(sc); } static void ipw_fatal_error_intr(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "firmware error\n"); @@ -1470,7 +1428,6 @@ ipw_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) static const char * ipw_cmdname(int cmd) { -#define N(a) (sizeof(a) / sizeof(a[0])) static const struct { int cmd; const char *name; @@ -1507,12 +1464,11 @@ ipw_cmdname(int cmd) static char buf[12]; int i; - for (i = 0; i < N(cmds); i++) + for (i = 0; i < nitems(cmds); i++) if (cmds[i].cmd == cmd) return cmds[i].name; snprintf(buf, sizeof(buf), "%u", cmd); return buf; -#undef N } /* @@ -1566,14 +1522,9 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len) 0, 0, len); /* Print the data buffer in the higher debug level */ if (ipw_debug >= 9 && len > 0) { -#ifdef __HAIKU__ int i; printf(" data: 0x"); for (i = 1; i <= len; i++) -#else - printf(" data: 0x"); - for (int i = 1; i <= len; i++) -#endif printf("%1D", (u_char *)data + len - i, ""); } printf("\n"); @@ -1597,10 +1548,9 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len) } static int -ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) +ipw_tx_start(struct ipw_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_frame *wh; struct ipw_soft_bd *sbd; @@ -1614,7 +1564,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); @@ -1638,7 +1588,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) shdr->hdr.type = htole32(IPW_HDR_TYPE_SEND); shdr->hdr.subtype = 0; - shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_WEP) ? 1 : 0; + shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) ? 1 : 0; shdr->hdr.encrypt = 0; shdr->hdr.keyidx = 0; shdr->hdr.keysz = 0; @@ -1754,38 +1704,42 @@ ipw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; } -static void -ipw_start(struct ifnet *ifp) +static int +ipw_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; + int error; IPW_LOCK(sc); - ipw_start_locked(ifp); + if ((sc->flags & IPW_FLAG_RUNNING) == 0) { + IPW_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + IPW_UNLOCK(sc); + return (error); + } + ipw_start(sc); IPW_UNLOCK(sc); + return (0); } static void -ipw_start_locked(struct ifnet *ifp) +ipw_start(struct ipw_softc *sc) { - struct ipw_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; IPW_LOCK_ASSERT(sc); - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->txfree < 1 + IPW_MAX_NSEG) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } + while (sc->txfree < 1 + IPW_MAX_NSEG && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - if (ipw_tx_start(ifp, m, ni) != 0) { + if (ipw_tx_start(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - ifp->if_oerrors++; break; } /* start watchdog timer */ @@ -1797,15 +1751,14 @@ static void ipw_watchdog(void *arg) { struct ipw_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IPW_LOCK_ASSERT(sc); if (sc->sc_tx_timer > 0) { if (--sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); - ifp->if_oerrors++; + device_printf(sc->sc_dev, "device timeout\n"); + counter_u64_add(ic->ic_oerrors, 1); taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task); } } @@ -1821,45 +1774,27 @@ ipw_watchdog(void *arg) } } } - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->flags & IPW_FLAG_RUNNING) callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); } -static int -ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +ipw_parent(struct ieee80211com *ic) { - struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct ipw_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - IPW_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - ipw_init_locked(sc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ipw_stop_locked(sc); + IPW_LOCK(sc); + if (ic->ic_nrunning > 0) { + if (!(sc->flags & IPW_FLAG_RUNNING)) { + ipw_init_locked(sc); + startall = 1; } - IPW_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + } else if (sc->flags & IPW_FLAG_RUNNING) + ipw_stop_locked(sc); + IPW_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -2075,8 +2010,7 @@ ipw_load_firmware(struct ipw_softc *sc, const char *fw, int size) static int ipw_setwepkeys(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ipw_wep_key wepkey; struct ieee80211_key *wk; @@ -2219,8 +2153,7 @@ done: static int ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t data; int error; @@ -2235,8 +2168,7 @@ ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan) static void ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap) { - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; struct ieee80211_node *ni = vap->iv_bss; struct ipw_security security; uint32_t data; @@ -2327,9 +2259,8 @@ done: static void ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap) { - struct ifnet *ifp = vap->iv_ic->ic_ifp; struct ieee80211_node *ni = vap->iv_bss; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); @@ -2363,22 +2294,20 @@ static void ipw_init(void *priv) { struct ipw_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; IPW_LOCK(sc); ipw_init_locked(sc); IPW_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->flags & IPW_FLAG_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } static void ipw_init_locked(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); const struct firmware *fp; const struct ipw_firmware_hdr *hdr; @@ -2462,22 +2391,19 @@ ipw_init_locked(struct ipw_softc *sc) } callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - - sc->flags &=~ IPW_FLAG_INIT_LOCKED; + sc->flags |= IPW_FLAG_RUNNING; + sc->flags &= ~IPW_FLAG_INIT_LOCKED; return; fail: ipw_stop_locked(sc); - sc->flags &=~ IPW_FLAG_INIT_LOCKED; + sc->flags &= ~IPW_FLAG_INIT_LOCKED; } static int ipw_config(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ipw_configuration config; uint32_t data; int error; @@ -2522,7 +2448,7 @@ ipw_config(struct ipw_softc *sc) IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE); if (ic->ic_opmode == IEEE80211_M_IBSS) config.flags |= htole32(IPW_CFG_IBSS_AUTO_START); - if (ifp->if_flags & IFF_PROMISC) + if (ic->ic_promisc > 0) config.flags |= htole32(IPW_CFG_PROMISCUOUS); config.bss_chan = htole32(0x3fff); /* channels 1-14 */ config.ibss_chan = htole32(0x7ff); /* channels 1-11 */ @@ -2580,7 +2506,6 @@ ipw_stop(void *priv) static void ipw_stop_locked(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; int i; IPW_LOCK_ASSERT(sc); @@ -2597,7 +2522,7 @@ ipw_stop_locked(struct ipw_softc *sc) ipw_release_sbd(sc, &sc->stbd_list[i]); sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->flags &= ~IPW_FLAG_RUNNING; } static int @@ -2695,19 +2620,37 @@ ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, const uint8_t *datap, static void ipw_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); ipw_scan(sc); IPW_UNLOCK(sc); } +static void +ipw_getradiocaps(struct ieee80211com *ic, + int maxchans, int *nchans, struct ieee80211_channel chans[]) +{ + struct ipw_softc *sc = ic->ic_softc; + uint8_t bands[IEEE80211_MODE_BYTES]; + int i; + + memset(bands, 0, sizeof(bands)); + setbit(bands, IEEE80211_MODE_11B); + + for (i = 1; i < 16; i++) { + if (sc->chanmask & (1 << i)) { + ieee80211_add_channel(chans, maxchans, nchans, + i, 0, 0, 0, bands); + } + } + +} + static void ipw_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); if (ic->ic_opmode == IEEE80211_M_MONITOR) { @@ -2733,8 +2676,7 @@ ipw_scan_mindwell(struct ieee80211_scan_state *ss) static void ipw_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct ipw_softc *sc = ifp->if_softc; + struct ipw_softc *sc = ic->ic_softc; IPW_LOCK(sc); sc->flags &= ~IPW_FLAG_SCANNING; diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwreg.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwreg.h index b300e13492..bb95c06816 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwreg.h +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwreg.h @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ipw/if_ipwreg.h 172567 2007-10-12 05:23:00Z thompsa $ */ /*- * Copyright (c) 2004-2006 diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h index ea4f218018..518b0db889 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/dev/ipw/if_ipwvar.h @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ipw/if_ipwvar.h 300239 2016-05-19 22:19:35Z avos $ */ /*- * Copyright (c) 2004-2006 @@ -87,7 +87,8 @@ struct ipw_vap { #define IPW_VAP(vap) ((struct ipw_vap *)(vap)) struct ipw_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; device_t sc_dev; struct mtx sc_mtx; @@ -104,9 +105,8 @@ struct ipw_softc { #define IPW_FLAG_BUSY 0x0040 #define IPW_FLAG_ASSOCIATING 0x0080 #define IPW_FLAG_ASSOCIATED 0x0100 +#define IPW_FLAG_RUNNING 0x0200 - int irq_rid; - int mem_rid; struct resource *irq; struct resource *mem; bus_space_tag_t sc_st; @@ -157,6 +157,8 @@ struct ipw_softc { uint32_t rxcur; int txfree; + uint16_t chanmask; + struct ipw_rx_radiotap_header sc_rxtap; struct ipw_tx_radiotap_header sc_txtap; diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/glue.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/glue.c index dbfc268e81..1d26d7be64 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/glue.c +++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi2100/glue.c @@ -23,8 +23,11 @@ NO_HAIKU_FBSD_MII_DRIVER(); NO_HAIKU_REENABLE_INTERRUPTS(); HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_SWI_TASKQUEUE | FBSD_WLAN); HAIKU_FIRMWARE_VERSION(130); -HAIKU_FIRMWARE_NAME_MAP(3) = {{"ipw_bss", "ipw2100-1.3.fw"}, - {"ipw_ibss", "ipw2100-1.3-i.fw"}, {"ipw_monitor", "ipw2100-1.3-p.fw"}}; +HAIKU_FIRMWARE_NAME_MAP(3) = { + {"ipw_bss", "ipw2100-1.3.fw"}, + {"ipw_ibss", "ipw2100-1.3-i.fw"}, + {"ipw_monitor", "ipw2100-1.3-p.fw"} +}; int