X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/1adceb71a1cac29db409608150c1ef84c64da86f..78195a764d5e70464a6d4f49bc08332a2a8bb4d0:/sys/dev/netif/wl/if_wl.c diff --git a/sys/dev/netif/wl/if_wl.c b/sys/dev/netif/wl/if_wl.c index bfe45650b7..eae12e8983 100644 --- a/sys/dev/netif/wl/if_wl.c +++ b/sys/dev/netif/wl/if_wl.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/i386/isa/if_wl.c,v 1.27.2.2 2000/07/17 21:24:32 archie Exp $ */ -/* $DragonFly: src/sys/dev/netif/wl/if_wl.c,v 1.15 2004/09/15 16:54:21 joerg Exp $ */ +/* $DragonFly: src/sys/dev/netif/wl/if_wl.c,v 1.26 2005/11/28 17:13:44 dillon Exp $ */ /* * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -189,7 +189,6 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * transmit buffer available in sram space. */ -#include "use_wl.h" #include "opt_wavelan.h" #include "opt_inet.h" @@ -200,12 +199,21 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include +#include #include #include +#include +#include +#include +#include + #include #include +#include +#include #include #ifdef INET @@ -217,8 +225,7 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include -#include - +#include #include #include "if_wl_i82586.h" /* Definitions for the Intel chip */ @@ -236,7 +243,6 @@ struct wl_softc{ u_char psa[0x40]; u_char nwid[2]; /* current radio modem nwid */ short base; - short unit; int flags; int tbusy; /* flag to determine if xmit is busy */ u_short begin_fd; @@ -246,6 +252,11 @@ struct wl_softc{ short mode; u_char chan24; /* 2.4 Gz: channel number/EEPROM Area # */ u_short freq24; /* 2.4 Gz: resulting frequency */ + int rid_ioport; + int rid_irq; + struct resource *res_ioport; + struct resource *res_irq; + void *intr_handle; struct callout watchdog_ch; #ifdef WLCACHE int w_sigitems; /* number of cached entries */ @@ -255,18 +266,6 @@ struct wl_softc{ int w_wrapindex; /* next "free" cache entry */ #endif }; -static struct wl_softc wl_softc[NWL]; - -#define WLSOFTC(unit) ((struct wl_softc *)(&wl_softc[unit])) - -static int wlprobe(struct isa_device *); -static int wlattach(struct isa_device *); - -DECLARE_DUMMY_MODULE(if_wl); - -struct isa_driver wldriver = { - wlprobe, wlattach, "wl", 0 -}; /* * XXX The Wavelan appears to be prone to dropping stuff if you talk to @@ -298,50 +297,76 @@ SYSCTL_INT(_machdep, OID_AUTO, wl_xmit_watch, CTLFLAG_RW, &xmt_watch, 0, ""); static int gathersnr = 0; SYSCTL_INT(_machdep, OID_AUTO, wl_gather_snr, CTLFLAG_RW, &gathersnr, 0, ""); -static void wlstart(struct ifnet *ifp); -static void wlinit(void *xsc); -static int wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *); +static int wlprobe(device_t); +static int wlattach(device_t); +static int wldetach(device_t); +static int wl_alloc_resources(device_t); +static void wl_free_resources(device_t); +static void wlstart(struct ifnet *); +static void wlinit(void *); +static int wlioctl(struct ifnet *, u_long, caddr_t, struct ucred *); static timeout_t wlwatchdog; -static ointhand2_t wlintr; -static void wlxmt(int unt, struct mbuf *m); -static int wldiag(int unt); -static int wlconfig(int unit); -static int wlcmd(int unit, char *str); -static void wlmmcstat(int unit); -static u_short wlbldru(int unit); -static u_short wlmmcread(u_int base, u_short reg); -static void wlinitmmc(int unit); -static int wlhwrst(int unit); -static void wlrustrt(int unit); -static void wlbldcu(int unit); -static int wlack(int unit); -static int wlread(int unit, u_short fd_p); -static void getsnr(int unit); -static void wlrcv(int unit); -static int wlrequeue(int unit, u_short fd_p); -static void wlsftwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, int unit); -static void wlhdwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, int unit); -static void wltbd(int unit); -static void wlgetpsa(int base, u_char *buf); -static void wlsetpsa(int unit); -static u_short wlpsacrc(u_char *buf); -static void wldump(int unit); +static void wlintr(void *); +static void wlxmt(struct wl_softc *, struct mbuf *); +static int wldiag(struct wl_softc *); +static int wlconfig(struct wl_softc *); +static int wlcmd(struct wl_softc *, const char *); +static void wlmmcstat(struct wl_softc *); +static u_short wlbldru(struct wl_softc *); +static u_short wlmmcread(u_int, u_short); +static void wlinitmmc(struct wl_softc *); +static int wlhwrst(struct wl_softc *); +static void wlrustrt(struct wl_softc *); +static void wlbldcu(struct wl_softc *); +static int wlack(struct wl_softc *); +static int wlread(struct wl_softc *, u_short); +static void getsnr(struct wl_softc *); +static void wlrcv(struct wl_softc *); +static int wlrequeue(struct wl_softc *, u_short); +static void wlsftwsleaze(u_short *, u_char **, struct mbuf **); +static void wlhdwsleaze(u_short *, u_char **, struct mbuf **); +static void wltbd(struct wl_softc *); +static void wlgetpsa(int, u_char *); +static void wlsetpsa(struct wl_softc *); +static u_short wlpsacrc(u_char *); +static void wldump(struct wl_softc *); #ifdef WLCACHE -static void wl_cache_store(int, int, struct ether_header *, struct mbuf *); -static void wl_cache_zero(int unit); +static void wl_cache_store(struct wl_softc *, int, struct ether_header *, + struct mbuf *); +static void wl_cache_zero(struct wl_softc *); #endif #ifdef MULTICAST # if defined(__FreeBSD__) && __FreeBSD_version < 300000 -static int check_allmulti(int unit); +static int check_allmulti(struct wl_softc *); # endif #endif +static device_method_t wl_methods[] = { + DEVMETHOD(device_probe, wlprobe), + DEVMETHOD(device_attach, wlattach), + DEVMETHOD(device_detach, wldetach), + { 0, 0 } +}; + +static driver_t wl_driver = { + "wl", + wl_methods, + sizeof(struct wl_softc) +}; + +devclass_t wl_devclass; +DECLARE_DUMMY_MODULE(if_wl); +DRIVER_MODULE(wl, isa, wl_driver, wl_devclass, 0, 0); +MODULE_DEPEND(wl, isa, 1, 1, 1); + +static struct isa_pnp_id wl_ids[] = { + { 0, NULL } +}; + /* array for maping irq numbers to values for the irq parameter register */ static int irqvals[16] = { 0, 0, 0, 0x01, 0x02, 0x04, 0, 0x08, 0, 0, 0x10, 0x20, 0x40, 0, 0, 0x80 }; -/* mask of valid IRQs */ -#define WL_IRQS (IRQ3|IRQ4|IRQ5|IRQ7|IRQ10|IRQ11|IRQ12|IRQ15) /* * wlprobe: @@ -354,32 +379,36 @@ static int irqvals[16] = { * comes back properly then we assume the board is there. The config * code expects to see a successful return from the probe routine before * attach will be called. - * - * input : address device is mapped to, and unit # being checked - * output : a '1' is returned if the board exists, and a 0 otherwise - * */ static int -wlprobe(struct isa_device *id) +wlprobe(device_t dev) { - struct wl_softc *sc = &wl_softc[id->id_unit]; - short base = id->id_iobase; - char *str = "wl%d: board out of range [0..%d]\n"; + struct wl_softc *sc; + short base; + const char *str = "wl%d: board out of range [0..%d]\n"; u_char inbuf[100]; - unsigned long oldpri; - int irq; + int irq, error; + + error = ISA_PNP_PROBE(device_get_parent(dev), dev, wl_ids); + if (error == ENXIO || error == 0) + return (error); + + sc = device_get_softc(dev); + error = wl_alloc_resources(dev); + if (error) + return error; + + base = rman_get_start(sc->res_ioport); /* TBD. not true. * regular CMD() will not work, since no softc yet */ #define PCMD(base, hacr) outw((base), (hacr)) - oldpri = splimp(); PCMD(base, HACR_RESET); /* reset the board */ DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */ PCMD(base, HACR_RESET); /* reset the board */ DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */ - splx(oldpri); /* clear reset command and set PIO#1 in autoincrement mode */ PCMD(base, HACR_DEFAULT); @@ -390,33 +419,42 @@ wlprobe(struct isa_device *id) outw(PIOR1(base), 0); /* rewind */ insw(PIOP1(base), inbuf, strlen(str)/2+1); /* read result */ - if (bcmp(str, inbuf, strlen(str))) - return(0); + if (bcmp(str, inbuf, strlen(str))) { + error = ENXIO; + goto fail; + } sc->chan24 = 0; /* 2.4 Gz: config channel */ sc->freq24 = 0; /* 2.4 Gz: frequency */ /* read the PSA from the board into temporary storage */ wlgetpsa(base, inbuf); - + /* We read the IRQ value from the PSA on the board. */ for (irq = 15; irq >= 0; irq--) if (irqvals[irq] == inbuf[WLPSA_IRQNO]) break; if ((irq == 0) || (irqvals[irq] == 0)){ - printf("wl%d: PSA corrupt (invalid IRQ value)\n", id->id_unit); - id->id_irq = 0; /* no interrupt */ + device_printf(dev, "PSA corrupt (invalid IRQ value)\n"); } else { + u_long sirq, dummy; + /* * If the IRQ requested by the PSA is already claimed by another * device, the board won't work, but the user can still access the * driver to change the IRQ. */ - id->id_irq = (1<id_unit]; - short base = id->id_iobase; - int i,j; - u_char unit = id->id_unit; - struct ifnet *ifp = &sc->wl_if; + struct wl_softc *sc; + short base; + int i, j, error; + struct ifnet *ifp; + + sc = device_get_softc(dev); + + ifp = &sc->wl_if; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + + error = wl_alloc_resources(dev); + if (error) + return error; + + base = rman_get_start(sc->res_ioport); #ifdef WLDEBUG - printf("wlattach: base %x, unit %d\n", base, unit); + device_printf(dev, "%s: base %x, unit %d\n", + __func__, base, device_get_unit(dev)); #endif - id->id_ointr = wlintr; + sc->base = base; - sc->unit = unit; sc->flags = 0; sc->mode = 0; sc->hacr = HACR_RESET; callout_init(&sc->watchdog_ch); - CMD(unit); /* reset the board */ + CMD(sc); /* reset the board */ DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */ /* clear reset command and set PIO#2 in parameter access mode */ sc->hacr = (HACR_DEFAULT & ~HACR_16BITS); - CMD(unit); + CMD(sc); /* Read the PSA from the board for our later reference */ wlgetpsa(base, sc->psa); @@ -475,18 +519,16 @@ wlattach(struct isa_device *id) /* enter normal 16 bit mode operation */ sc->hacr = HACR_DEFAULT; - CMD(unit); + CMD(sc); - wlinitmmc(unit); + wlinitmmc(sc); outw(PIOR1(base), OFFSET_SCB + 8); /* address of scb_crcerrs */ outw(PIOP1(base), 0); /* clear scb_crcerrs */ outw(PIOP1(base), 0); /* clear scb_alnerrs */ outw(PIOP1(base), 0); /* clear scb_rscerrs */ outw(PIOP1(base), 0); /* clear scb_ovrnerrs */ - bzero(ifp, sizeof(ifp)); ifp->if_softc = sc; - if_initname(ifp, "wl", id->id_unit); ifp->if_mtu = WAVELAN_MTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; #ifdef WLDEBUG @@ -504,45 +546,122 @@ wlattach(struct isa_device *id) ifp->if_done ifp->if_reset */ - ether_ifattach(ifp, sc->wl_ac.ac_enaddr); + ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN); + ifq_set_ready(&ifp->if_snd); + ether_ifattach(ifp, sc->wl_ac.ac_enaddr, NULL); - bcopy(&sc->wl_addr[0], sc->wl_ac.ac_enaddr, WAVELAN_ADDR_SIZE); - if_printf(ifp, "NWID 0x%02x%02x", sc->nwid[0], sc->nwid[1]); if (sc->freq24) printf(", Freq %d MHz",sc->freq24); /* 2.4 Gz */ printf("\n"); /* 2.4 Gz */ + error = bus_setup_intr(dev, sc->res_irq, INTR_NETSAFE, + wlintr, sc, &sc->intr_handle, + ifp->if_serializer); + if (error) { + device_printf(dev, "setup irq fail!\n"); + ether_ifdetach(ifp); + wl_free_resources(dev); + return error; + } if (bootverbose) - wldump(unit); - return(1); + wldump(sc); + return 0; +} + +static int +wldetach(device_t dev) +{ + struct wl_softc *sc = device_get_softc(dev); + device_t parent = device_get_parent(dev); + struct ifnet *ifp = &sc->wl_if; + + lwkt_serialize_enter(ifp->if_serializer); + ether_ifdetach(ifp); + + /* reset the board */ + sc->hacr = HACR_RESET; + CMD(sc); + sc->hacr = HACR_DEFAULT; + CMD(sc); + + if (sc->intr_handle != NULL) { + BUS_TEARDOWN_INTR(parent, dev, sc->res_irq, sc->intr_handle); + sc->intr_handle = NULL; + } + + bus_generic_detach(dev); + + wl_free_resources(dev); + lwkt_serialize_exit(ifp->if_serializer); + return (0); +} + +static int +wl_alloc_resources(device_t dev) +{ + struct wl_softc *sc = device_get_softc(dev); + int ports = 16; /* Number of ports */ + + sc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, + &sc->rid_ioport, 0ul, ~0ul, ports, RF_ACTIVE); + if (sc->res_ioport == NULL) + goto fail; + + sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->rid_irq, RF_SHAREABLE | RF_ACTIVE); + if (sc->res_irq == NULL) + goto fail; + return (0); + +fail: + wl_free_resources(dev); + return (ENXIO); +} + +static void +wl_free_resources(device_t dev) +{ + struct wl_softc *sc = device_get_softc(dev); + + if (sc->res_irq != 0) { + bus_deactivate_resource(dev, SYS_RES_IRQ, sc->rid_irq, sc->res_irq); + bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq, sc->res_irq); + sc->res_irq = 0; + } + if (sc->res_ioport != 0) { + bus_deactivate_resource(dev, SYS_RES_IOPORT, + sc->rid_ioport, sc->res_ioport); + bus_release_resource(dev, SYS_RES_IOPORT, + sc->rid_ioport, sc->res_ioport); + sc->res_ioport = 0; + } } /* * Print out interesting information about the 82596. */ static void -wldump(int unit) +wldump(struct wl_softc *sc) { - struct wl_softc *sp = WLSOFTC(unit); - int base = sp->base; + int base = sc->base; int i; - printf("hasr %04x\n", inw(HASR(base))); + if_printf(&sc->wl_if, "hasr %04x\n", inw(HASR(base))); - printf("scb at %04x:\n ", OFFSET_SCB); + if_printf(&sc->wl_if, "scb at %04x:\n ", OFFSET_SCB); outw(PIOR1(base), OFFSET_SCB); for(i = 0; i < 8; i++) printf("%04x ", inw(PIOP1(base))); printf("\n"); - printf("cu at %04x:\n ", OFFSET_CU); + if_printf(&sc->wl_if, "cu at %04x:\n ", OFFSET_CU); outw(PIOR1(base), OFFSET_CU); for(i = 0; i < 8; i++) printf("%04x ", inw(PIOP1(base))); printf("\n"); - printf("tbd at %04x:\n ", OFFSET_TBD); + if_printf(&sc->wl_if, "tbd at %04x:\n ", OFFSET_TBD); outw(PIOR1(base), OFFSET_TBD); for(i = 0; i < 4; i++) printf("%04x ", inw(PIOP1(base))); @@ -551,19 +670,18 @@ wldump(int unit) /* Initialize the Modem Management Controller */ static void -wlinitmmc(int unit) +wlinitmmc(struct wl_softc *sc) { - struct wl_softc *sp = WLSOFTC(unit); - int base = sp->base; + int base = sc->base; int configured; - int mode = sp->mode; + int mode = sc->mode; int i; /* 2.4 Gz */ /* enter 8 bit operation */ - sp->hacr = (HACR_DEFAULT & ~HACR_16BITS); - CMD(unit); + sc->hacr = (HACR_DEFAULT & ~HACR_16BITS); + CMD(sc); - configured = sp->psa[WLPSA_CONFIGURED] & 1; + configured = sc->psa[WLPSA_CONFIGURED] & 1; /* * Set default modem control parameters. Taken from NCR document @@ -578,7 +696,7 @@ wlinitmmc(int unit) MMC_WRITE(MMC_DECAY_UPDAT_PRM, 0x00); if (!configured) { MMC_WRITE(MMC_LOOPT_SEL, 0x00); - if (sp->psa[WLPSA_COMPATNO] & 1) { + if (sc->psa[WLPSA_COMPATNO] & 1) { MMC_WRITE(MMC_THR_PRE_SET, 0x01); /* 0x04 for AT and 0x01 for MCA */ } else { MMC_WRITE(MMC_THR_PRE_SET, 0x04); /* 0x04 for AT and 0x01 for MCA */ @@ -586,7 +704,7 @@ wlinitmmc(int unit) MMC_WRITE(MMC_QUALITY_THR, 0x03); } else { /* use configuration defaults from parameter storage area */ - if (sp->psa[WLPSA_NWIDENABLE] & 1) { + if (sc->psa[WLPSA_NWIDENABLE] & 1) { if ((mode & (MOD_PROM | MOD_ENAL)) && wl_ignore_nwid) { MMC_WRITE(MMC_LOOPT_SEL, 0x40); } else { @@ -595,23 +713,23 @@ wlinitmmc(int unit) } else { MMC_WRITE(MMC_LOOPT_SEL, 0x40); /* disable network id check */ } - MMC_WRITE(MMC_THR_PRE_SET, sp->psa[WLPSA_THRESH]); - MMC_WRITE(MMC_QUALITY_THR, sp->psa[WLPSA_QUALTHRESH]); + MMC_WRITE(MMC_THR_PRE_SET, sc->psa[WLPSA_THRESH]); + MMC_WRITE(MMC_QUALITY_THR, sc->psa[WLPSA_QUALTHRESH]); } MMC_WRITE(MMC_FREEZE, 0x00); MMC_WRITE(MMC_ENCR_ENABLE, 0x00); - MMC_WRITE(MMC_NETW_ID_L,sp->nwid[1]); /* set NWID */ - MMC_WRITE(MMC_NETW_ID_H,sp->nwid[0]); + MMC_WRITE(MMC_NETW_ID_L,sc->nwid[1]); /* set NWID */ + MMC_WRITE(MMC_NETW_ID_H,sc->nwid[0]); /* enter normal 16 bit mode operation */ - sp->hacr = HACR_DEFAULT; - CMD(unit); - CMD(unit); /* virtualpc1 needs this! */ + sc->hacr = HACR_DEFAULT; + CMD(sc); + CMD(sc); /* virtualpc1 needs this! */ - if (sp->psa[WLPSA_COMPATNO]== /* 2.4 Gz: half-card ver */ + if (sc->psa[WLPSA_COMPATNO]== /* 2.4 Gz: half-card ver */ WLPSA_COMPATNO_WL24B) { /* 2.4 Gz */ - i=sp->chan24<<4; /* 2.4 Gz: position ch # */ + i=sc->chan24<<4; /* 2.4 Gz: position ch # */ MMC_WRITE(MMC_EEADDR,i+0x0f); /* 2.4 Gz: named ch, wc=16 */ MMC_WRITE(MMC_EECTRL,MMC_EECTRL_DWLD+ /* 2.4 Gz: Download Synths */ MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */ @@ -622,7 +740,10 @@ wlinitmmc(int unit) +MMC_EECTRLstat_EEBUSY))==0) /* 2.4 Gz: */ break; /* 2.4 Gz: download finished */ } /* 2.4 Gz */ - if (i==1000) printf("wl: synth load failed\n"); /* 2.4 Gz */ + if (i==1000) { + if_printf(&sc->wl_if, + "synth load failed\n"); /* 2.4 Gz */ + } MMC_WRITE(MMC_EEADDR,0x61); /* 2.4 Gz: default pwr, wc=2 */ MMC_WRITE(MMC_EECTRL,MMC_EECTRL_DWLD+ /* 2.4 Gz: Download Xmit Pwr */ MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */ @@ -633,18 +754,21 @@ wlinitmmc(int unit) +MMC_EECTRLstat_EEBUSY))==0) /* 2.4 Gz: */ break; /* 2.4 Gz: download finished */ } /* 2.4 Gz */ - if (i==1000) printf("wl: xmit pwr load failed\n"); /* 2.4 Gz */ + if (i==1000) { + if_printf(&sc->wl_if, + "xmit pwr load failed\n");/* 2.4 Gz */ + } MMC_WRITE(MMC_ANALCTRL, /* 2.4 Gz: EXT ant+polarity */ MMC_ANALCTRL_ANTPOL + /* 2.4 Gz: */ MMC_ANALCTRL_EXTANT); /* 2.4 Gz: */ - i=sp->chan24<<4; /* 2.4 Gz: position ch # */ + i=sc->chan24<<4; /* 2.4 Gz: position ch # */ MMC_WRITE(MMC_EEADDR,i); /* 2.4 Gz: get frequency */ MMC_WRITE(MMC_EECTRL, /* 2.4 Gz: EEPROM read */ MMC_EECTRL_EEOP_READ); /* 2.4 Gz: */ DELAY(40); /* 2.4 Gz */ i = wlmmcread(base,MMC_EEDATALrv) /* 2.4 Gz: freq val */ + (wlmmcread(base,MMC_EEDATAHrv)<<8); /* 2.4 Gz */ - sp->freq24 = (i>>6)+2400; /* 2.4 Gz: save real freq */ + sc->freq24 = (i>>6)+2400; /* 2.4 Gz: save real freq */ } } @@ -665,27 +789,18 @@ wlinit(void *xsc) struct wl_softc *sc = xsc; struct ifnet *ifp = &sc->wl_if; int stat; - u_long oldpri; #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlinit()\n",sc->unit); + if (ifp->if_flags & IFF_DEBUG) + if_printf(ifp, "entered wlinit()\n"); #endif -#if defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD_version >= 300000) - if (TAILQ_EMPTY(&ifp->if_addrhead)) { -#else - if (ifp->if_addrlist == (struct ifaddr *)0) { -#endif - return; - } - oldpri = splimp(); - if ((stat = wlhwrst(sc->unit)) == TRUE) { - sc->wl_if.if_flags |= IFF_RUNNING; /* same as DSF_RUNNING */ + if ((stat = wlhwrst(sc)) == TRUE) { + ifp->if_flags |= IFF_RUNNING; /* same as DSF_RUNNING */ /* * OACTIVE is used by upper-level routines * and must be set */ - sc->wl_if.if_flags &= ~IFF_OACTIVE; /* same as tbusy below */ + ifp->if_flags &= ~IFF_OACTIVE; /* same as tbusy below */ sc->flags |= DSF_RUNNING; sc->tbusy = 0; @@ -693,9 +808,8 @@ wlinit(void *xsc) wlstart(ifp); } else { - printf("wl%d init(): trouble resetting board.\n", sc->unit); + if_printf(ifp, "init(): trouble resetting board.\n"); } - splx(oldpri); } /* @@ -704,45 +818,43 @@ wlinit(void *xsc) * This routine resets the WaveLAN board that corresponds to the * board number passed in. * - * input : board number to do a hardware reset + * input : softc pointer for this interface * output : board is reset * */ static int -wlhwrst(int unit) +wlhwrst(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); - #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlhwrst()\n",unit); + if_printf(&sc->wl_if, "entered wlhwrst()\n"); #endif sc->hacr = HACR_RESET; - CMD(unit); /* reset the board */ + CMD(sc); /* reset the board */ /* clear reset command and set PIO#1 in autoincrement mode */ sc->hacr = HACR_DEFAULT; - CMD(unit); + CMD(sc); #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - wlmmcstat(unit); /* Display MMC registers */ + wlmmcstat(sc); /* Display MMC registers */ #endif /* WLDEBUG */ - wlbldcu(unit); /* set up command unit structures */ + wlbldcu(sc); /* set up command unit structures */ - if (wldiag(unit) == 0) + if (wldiag(sc) == 0) return(0); - if (wlconfig(unit) == 0) + if (wlconfig(sc) == 0) return(0); /* * insert code for loopback test here */ - wlrustrt(unit); /* start receive unit */ + wlrustrt(sc); /* start receive unit */ /* enable interrupts */ sc->hacr = (HACR_DEFAULT | HACR_INTRON); - CMD(unit); + CMD(sc); return(1); } @@ -755,9 +867,8 @@ wlhwrst(int unit) * */ static void -wlbldcu(int unit) +wlbldcu(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; scp_t scp; iscp_t iscp; @@ -792,19 +903,19 @@ wlbldcu(int unit) outw(PIOR1(base), OFFSET_SCB); outsw(PIOP1(base), &scb, sizeof(scb_t)/2); - SET_CHAN_ATTN(unit); + SET_CHAN_ATTN(sc); outw(PIOR0(base), OFFSET_ISCP + 0); /* address of iscp_busy */ for (i = 1000000; inw(PIOP0(base)) && (i-- > 0); ); - if (i <= 0) printf("wl%d bldcu(): iscp_busy timeout.\n", unit); + if (i <= 0) if_printf(&sc->wl_if, "bldcu(): iscp_busy timeout.\n"); outw(PIOR0(base), OFFSET_SCB + 0); /* address of scb_status */ for (i = STATUS_TRIES; i-- > 0; ) { if (inw(PIOP0(base)) == (SCB_SW_CX|SCB_SW_CNA)) break; } if (i <= 0) - printf("wl%d bldcu(): not ready after reset.\n", unit); - wlack(unit); + if_printf(&sc->wl_if, "bldcu(): not ready after reset.\n"); + wlack(sc); cb.ac_status = 0; cb.ac_command = AC_CW_EL; /* NOP */ @@ -825,22 +936,21 @@ wlbldcu(int unit) * * send a packet * - * input : board number + * input : pointer the appropriate "if" struct * output : stuff sent to board if any there * */ static void wlstart(struct ifnet *ifp) { - int unit = ifp->if_dunit; struct mbuf *m; - struct wl_softc *sc = WLSOFTC(unit); + struct wl_softc *sc = ifp->if_softc; short base = sc->base; int scb_status, cu_status, scb_command; #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlstart()\n",unit); + if (ifp->if_flags & IFF_DEBUG) + if_printf(ifp, "entered wlstart()\n"); #endif outw(PIOR1(base), OFFSET_CU); @@ -859,50 +969,46 @@ wlstart(struct ifnet *ifp) (cu_status & AC_SW_B) == 0){ sc->tbusy = 0; callout_stop(&sc->watchdog_ch); - sc->wl_ac.ac_if.if_flags &= ~IFF_OACTIVE; + ifp->if_flags &= ~IFF_OACTIVE; /* * This is probably just a race. The xmt'r is just * became idle but WE have masked interrupts so ... */ #ifdef WLDEBUG - printf("wl%d: CU idle, scb %04x %04x cu %04x\n", - unit, scb_status, scb_command, cu_status); + if_printf(ifp, "CU idle, scb %04x %04x cu %04x\n", + scb_status, scb_command, cu_status); #endif - if (xmt_watch) printf("!!"); + if (xmt_watch) if_printf(ifp, "!!\n"); } else { return; /* genuinely still busy */ } } else if((scb_status & 0x0700) == SCB_CUS_ACTV || (cu_status & AC_SW_B)){ #ifdef WLDEBUG - printf("wl%d: CU unexpectedly busy; scb %04x cu %04x\n", - unit, scb_status, cu_status); + if_printf(ifp, "CU unexpectedly busy; scb %04x cu %04x\n", + scb_status, cu_status); #endif - if (xmt_watch) printf("wl%d: busy?!",unit); + if (xmt_watch) if_printf(ifp, "busy?!"); return; /* hey, why are we busy? */ } /* get ourselves some data */ ifp = &(sc->wl_if); - IF_DEQUEUE(&ifp->if_snd, m); - if (m != (struct mbuf *)0) { - /* let BPF see it before we commit it */ - if (ifp->if_bpf) { - bpf_mtap(ifp, m); - } + m = ifq_dequeue(&ifp->if_snd, NULL); + if (m != NULL) { + BPF_MTAP(ifp, m); sc->tbusy++; /* set the watchdog timer so that if the board * fails to interrupt we will restart */ /* try 10 ticks, not very long */ callout_reset(&sc->watchdog_ch, 10, wlwatchdog, sc); - sc->wl_ac.ac_if.if_flags |= IFF_OACTIVE; - sc->wl_if.if_opackets++; - wlxmt(unit, m); + ifp->if_flags |= IFF_OACTIVE; + ifp->if_opackets++; + wlxmt(sc, m); } else { - sc->wl_ac.ac_if.if_flags &= ~IFF_OACTIVE; + ifp->if_flags &= ~IFF_OACTIVE; } - return; } /* @@ -918,15 +1024,15 @@ wlstart(struct ifnet *ifp) * the local buffer, the contents are copied to an mbuf chain that * is then enqueued onto the appropriate "if" queue. * - * input : board number, and an frame descriptor address + * input : softc pointer for this interface and + * an frame descriptor address * output : the packet is put into an mbuf chain, and passed up * assumes : if any errors occur, packet is "dropped on the floor" * */ static int -wlread(int unit, u_short fd_p) +wlread(struct wl_softc *sc, u_short fd_p) { - struct wl_softc *sc = WLSOFTC(unit); struct ifnet *ifp = &sc->wl_if; short base = sc->base; fd_t fd; @@ -939,13 +1045,13 @@ wlread(int unit, u_short fd_p) #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlread()\n",unit); + if (ifp->if_flags & IFF_DEBUG) + if_printf(ifp, "entered wlread()\n"); #endif if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { - printf("%s read(): board is not running.\n", ifp->if_xname); + if_printf(ifp, "read(): board is not running.\n"); sc->hacr &= ~HACR_INTRON; - CMD(unit); /* turn off interrupts */ + CMD(sc); /* turn off interrupts */ } /* read ether_header info out of device memory. doesn't * go into mbuf. goes directly into eh structure @@ -956,9 +1062,8 @@ wlread(int unit, u_short fd_p) insw(PIOP1(base), &eh, (len-2)/2); eh.ether_type = ntohs(inw(PIOP1(base))); #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) { - printf("wlread: rcv packet, type is %x\n", eh.ether_type); - } + if (ifp->if_flags & IFF_DEBUG) + if_printf(ifp, "wlread: rcv packet, type is %x\n", eh.ether_type); #endif /* * WARNING. above is done now in ether_input, above may be @@ -967,10 +1072,9 @@ wlread(int unit, u_short fd_p) eh.ether_type = htons(eh.ether_type); if (fd.rbd_offset == I82586NULL) { - printf("wl%d read(): Invalid buffer\n", unit); - if (wlhwrst(unit) != TRUE) { - printf("wl%d read(): hwrst trouble.\n", unit); - } + if_printf(ifp, "read(): Invalid buffer\n"); + if (wlhwrst(sc) != TRUE) + if_printf(ifp, "read(): hwrst trouble.\n"); return 0; } @@ -979,16 +1083,16 @@ wlread(int unit, u_short fd_p) bytes_in_msg = rbd.status & RBD_SW_COUNT; MGETHDR(m, MB_DONTWAIT, MT_DATA); tm = m; - if (m == (struct mbuf *)0) { + if (m == NULL) { /* * not only do we want to return, we need to drop the packet on * the floor to clear the interrupt. * */ - if (wlhwrst(unit) != TRUE) { + if (wlhwrst(sc) != TRUE) { sc->hacr &= ~HACR_INTRON; - CMD(unit); /* turn off interrupts */ - printf("wl%d read(): hwrst trouble.\n", unit); + CMD(sc); /* turn off interrupts */ + if_printf(ifp, "read(): hwrst trouble.\n"); } return 0; } @@ -1005,19 +1109,21 @@ wlread(int unit, u_short fd_p) } else { m_freem(m); - if (wlhwrst(unit) != TRUE) { + if (wlhwrst(sc) != TRUE) { sc->hacr &= ~HACR_INTRON; - CMD(unit); /* turn off interrupts */ - printf("wl%d read(): hwrst trouble.\n", unit); + CMD(sc); /* turn off interrupts */ + if_printf(ifp, "read(): hwrst trouble.\n"); } return 0; } mlen = 0; clen = mlen; - bytes_in_mbuf = m->m_len; + bytes_in_mbuf = m->m_len - sizeof(eh); mb_p = mtod(tm, u_char *); bytes = min(bytes_in_mbuf, bytes_in_msg); + bcopy(&eh, mb_p, sizeof(eh)); + mb_p += sizeof(eh); for (;;) { if (bytes & 1) { len = bytes + 1; @@ -1034,11 +1140,11 @@ wlread(int unit, u_short fd_p) tm = tm->m_next; if (tm == (struct mbuf *)0) { m_freem(m); - printf("wl%d read(): No mbuf nth\n", unit); - if (wlhwrst(unit) != TRUE) { + if_printf(ifp, "read(): No mbuf nth\n"); + if (wlhwrst(sc) != TRUE) { sc->hacr &= ~HACR_INTRON; - CMD(unit); /* turn off interrupts */ - printf("wl%d read(): hwrst trouble.\n", unit); + CMD(sc); /* turn off interrupts */ + if_printf(ifp, "read(): hwrst trouble.\n"); } return 0; } @@ -1084,7 +1190,7 @@ wlread(int unit, u_short fd_p) */ if ( #ifdef WL_USE_IFNET_PROMISC_CHECK /* not defined */ - (sc->wl_ac.ac_if.if_flags & (IFF_PROMISC|IFF_ALLMULTI)) + (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI)) #else /* hw is in promisc mode if this is true */ (sc->mode & (MOD_PROM | MOD_ENAL)) @@ -1098,12 +1204,12 @@ wlread(int unit, u_short fd_p) } #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: wlrecv %d bytes\n", unit, clen); + if (ifp->if_flags & IFF_DEBUG) + if_printf(ifp, "wlrecv %d bytes\n", clen); #endif #ifdef WLCACHE - wl_cache_store(unit, base, &eh, m); + wl_cache_store(sc, base, &eh, m); #endif /* @@ -1111,7 +1217,7 @@ wlread(int unit, u_short fd_p) * to pass the packet upwards. * */ - ether_input(&sc->wl_if, &eh, m); + ifp->if_input(ifp, m); return 1; } @@ -1121,7 +1227,7 @@ wlread(int unit, u_short fd_p) * This routine processes an ioctl request from the "if" layer * above. * - * input : pointer the appropriate "if" struct, command, and data + * input : pointer the appropriate "if" struct, command and data * output : based on command appropriate action is taken on the * WaveLAN board(s) or related structures * return : error is returned containing exit conditions @@ -1131,11 +1237,10 @@ static int wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) { struct ifreq *ifr = (struct ifreq *)data; - int unit = ifp->if_dunit; - struct wl_softc *sc = WLSOFTC(unit); + struct wl_softc *sc = ifp->if_softc; short base = sc->base; short mode = 0; - int opri, error = 0; + int error = 0; int irq, irqval, i, isroot, size; caddr_t up; char * cpt; @@ -1143,17 +1248,10 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlioctl()\n",unit); + if (ifp->if_flags & IFF_DEBUG) + if_printf(ifp, "entered wlioctl()\n"); #endif - opri = splimp(); switch (cmd) { - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, cmd, data); - break; - case SIOCSIFFLAGS: if (ifp->if_flags & IFF_ALLMULTI) { mode |= MOD_ENAL; @@ -1181,10 +1279,10 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) * stop it. */ if ((ifp->if_flags & IFF_UP) == 0 && sc->flags & DSF_RUNNING) { - printf("wl%d ioctl(): board is not running\n", unit); + if_printf(ifp, "ioctl(): board is not running\n"); sc->flags &= ~DSF_RUNNING; sc->hacr &= ~HACR_INTRON; - CMD(unit); /* turn off interrupts */ + CMD(sc); /* turn off interrupts */ } /* else if interface is UP and RUNNING, start it */ @@ -1195,7 +1293,7 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) /* if WLDEBUG set on interface, then printf rf-modem regs */ if(ifp->if_flags & IFF_DEBUG) - wlmmcstat(unit); + wlmmcstat(sc); break; #if MULTICAST case SIOCADDMULTI: @@ -1213,7 +1311,7 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) * note that 82586 cannot do that, must simulate with * promiscuous mode */ - if ( check_allmulti(unit)) { + if (check_allmulti(sc)) { ifp->if_flags |= IFF_ALLMULTI; sc->mode |= MOD_ENAL; sc->flags &= ~DSF_RUNNING; @@ -1291,7 +1389,7 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) sc->psa[WLPSA_NWID+1] = fubyte(up+WLPSA_NWID+1); error = 0; - wlsetpsa(unit); /* update the PSA */ + wlsetpsa(sc); /* update the PSA */ break; @@ -1355,7 +1453,7 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) /* root only */ if ((error = suser(td))) break; - wl_cache_zero(unit); + wl_cache_zero(sc); break; /* read out the number of used cache elements */ @@ -1378,9 +1476,9 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cred) #endif default: - error = EINVAL; + error = ether_ioctl(ifp, cmd, data); + break; } - splx(opri); return (error); } @@ -1399,11 +1497,13 @@ static void wlwatchdog(void *vsc) { struct wl_softc *sc = vsc; - int unit = sc->unit; + struct ifnet *ifp = &sc->wl_if; - log(LOG_ERR, "wl%d: wavelan device timeout on xmit\n", unit); - sc->wl_ac.ac_if.if_oerrors++; + lwkt_serialize_enter(ifp->if_serializer); + log(LOG_ERR, "%s: wavelan device timeout on xmit\n", sc->wl_if.if_xname); + sc->wl_if.if_oerrors++; wlinit(sc); + lwkt_serialize_exit(ifp->if_serializer); } /* @@ -1414,22 +1514,22 @@ wlwatchdog(void *vsc) * is received, or a packet has successfully been transfered and * the unit is ready to transmit another packet. * - * input : board number that interrupted + * input : softc pointer for this interface * output : either a packet is received, or a packet is transfered * */ static void -wlintr(unit) -int unit; +wlintr(void *arg) { - struct wl_softc *sc = &wl_softc[unit]; + struct wl_softc *sc = arg; + struct ifnet *ifp = &sc->wl_if; short base = sc->base; int ac_status; u_short int_type, int_type1; #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: wlintr() called\n",unit); + if (ifp->if_flags & IFF_DEBUG) + if_printf(ifp, "wlintr() called\n"); #endif if((int_type = inw(HASR(base))) & HASR_MMC_INTR) { @@ -1440,44 +1540,47 @@ int unit; if(!(int_type & HASR_INTR)){ /* return if no interrupt from 82586 */ /* commented out. jrb. it happens when reinit occurs - printf("wlintr: int_type %x, dump follows\n", int_type); - wldump(unit); + if_printf(ifp, "%s: int_type %x, dump follows\n", + __func__, int_type); + wldump(sc); */ return; } if (gathersnr) - getsnr(unit); + getsnr(sc); for(;;) { outw(PIOR0(base), OFFSET_SCB + 0); /* get scb status */ int_type = (inw(PIOP0(base)) & SCB_SW_INT); if (int_type == 0) /* no interrupts left */ break; - int_type1 = wlack(unit); /* acknowledge interrupt(s) */ + int_type1 = wlack(sc); /* acknowledge interrupt(s) */ /* make sure no bits disappeared (others may appear) */ - if ((int_type & int_type1) != int_type) - printf("wlack() int bits disappeared : %04x != int_type %04x\n", - int_type1, int_type); + if ((int_type & int_type1) != int_type) { + if_printf(ifp, "wlack() int bits disappeared: " + "%04x != int_type %04x\n", int_type1, int_type); + } int_type = int_type1; /* go with the new status */ /* * incoming packet */ if (int_type & SCB_SW_FR) { - sc->wl_if.if_ipackets++; - wlrcv(unit); + ifp->if_ipackets++; + wlrcv(sc); } /* * receiver not ready */ if (int_type & SCB_SW_RNR) { - sc->wl_if.if_ierrors++; + ifp->if_ierrors++; #ifdef WLDEBUG - if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d intr(): receiver overrun! begin_fd = %x\n", - unit, sc->begin_fd); + if (ifp->if_flags & IFF_DEBUG) { + if_printf(ifp, "intr(): receiver overrun! begin_fd = %x\n", + sc->begin_fd); + } #endif - wlrustrt(unit); + wlrustrt(sc); } /* * CU not ready @@ -1499,55 +1602,55 @@ int unit; if (xmt_watch) { /* report some anomalies */ if (sc->tbusy == 0) { - printf("wl%d: xmt intr but not busy, CU %04x\n", - unit, ac_status); + if_printf(ifp, "xmt intr but not busy, CU %04x\n", + ac_status); } if (ac_status == 0) { - printf("wl%d: xmt intr but ac_status == 0\n", unit); + if_printf(ifp, "xmt intr but ac_status == 0\n"); } if (ac_status & AC_SW_A) { - printf("wl%d: xmt aborted\n",unit); + if_printf(ifp, "xmt aborted\n"); } #ifdef notdef if (ac_status & TC_CARRIER) { - printf("wl%d: no carrier\n", unit); + if_printf(ifp, "no carrier\n"); } #endif /* notdef */ if (ac_status & TC_CLS) { - printf("wl%d: no CTS\n", unit); + if_printf(ifp, "no CTS\n"); } if (ac_status & TC_DMA) { - printf("wl%d: DMA underrun\n", unit); + if_printf(ifp, "DMA underrun\n"); } if (ac_status & TC_DEFER) { - printf("wl%d: xmt deferred\n",unit); + if_printf(ifp, "xmt deferred\n"); } if (ac_status & TC_SQE) { - printf("wl%d: heart beat\n", unit); + if_printf(ifp, "heart beat\n"); } if (ac_status & TC_COLLISION) { - printf("wl%d: too many collisions\n", unit); + if_printf(ifp, "too many collisions\n"); } } /* if the transmit actually failed, or returned some status */ if ((!(ac_status & AC_SW_OK)) || (ac_status & 0xfff)) { if (ac_status & (TC_COLLISION | TC_CLS | TC_DMA)) { - sc->wl_if.if_oerrors++; + ifp->if_oerrors++; } + /* count collisions */ - sc->wl_if.if_collisions += (ac_status & 0xf); + ifp->if_collisions += (ac_status & 0xf); /* if TC_COLLISION set and collision count zero, 16 collisions */ if ((ac_status & 0x20) == 0x20) { - sc->wl_if.if_collisions += 0x10; + ifp->if_collisions += 0x10; } } sc->tbusy = 0; callout_stop(&sc->watchdog_ch); - sc->wl_ac.ac_if.if_flags &= ~IFF_OACTIVE; - wlstart(&(sc->wl_if)); + ifp->if_flags &= ~IFF_OACTIVE; + wlstart(ifp); } } - return; } /* @@ -1560,20 +1663,19 @@ int unit; * to do the actual transfer of the board data (including the * ethernet header) into a packet (consisting of an mbuf chain). * - * input : number of the board to check + * input : softc pointer for this interface * output : if a packet is available, it is "sent up" * */ static void -wlrcv(int unit) +wlrcv(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; u_short fd_p, status, offset, link_offset; #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlrcv()\n",unit); + if_printf(&sc->wl_if, "entered wlrcv()\n"); #endif for (fd_p = sc->begin_fd; fd_p != I82586NULL; fd_p = sc->begin_fd) { @@ -1583,30 +1685,30 @@ wlrcv(int unit) link_offset = inw(PIOP1(base)); offset = inw(PIOP1(base)); /* rbd_offset */ if (status == 0xffff || offset == 0xffff /*I82586NULL*/) { - if (wlhwrst(unit) != TRUE) - printf("wl%d rcv(): hwrst ffff trouble.\n", unit); + if (wlhwrst(sc) != TRUE) + if_printf(&sc->wl_if, "rcv(): hwrst ffff trouble.\n"); return; } else if (status & AC_SW_C) { if (status == (RFD_DONE|RFD_RSC)) { /* lost one */ #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d RCV: RSC %x\n", unit, status); + if_printf(&sc->wl_if, "RCV: RSC %x\n", status); #endif sc->wl_if.if_ierrors++; } else if (!(status & RFD_OK)) { - printf("wl%d RCV: !OK %x\n", unit, status); + if_printf(&sc->wl_if, "RCV: !OK %x\n", status); sc->wl_if.if_ierrors++; } else if (status & 0xfff) { /* can't happen */ - printf("wl%d RCV: ERRs %x\n", unit, status); + if_printf(&sc->wl_if, "RCV: ERRs %x\n", status); sc->wl_if.if_ierrors++; - } else if (!wlread(unit, fd_p)) + } else if (!wlread(sc, fd_p)) return; - if (!wlrequeue(unit, fd_p)) { + if (!wlrequeue(sc, fd_p)) { /* abort on chain error */ - if (wlhwrst(unit) != TRUE) - printf("wl%d rcv(): hwrst trouble.\n", unit); + if (wlhwrst(sc) != TRUE) + if_printf(&sc->wl_if, "rcv(): hwrst trouble.\n"); return; } sc->begin_fd = link_offset; @@ -1614,7 +1716,6 @@ wlrcv(int unit) break; } } - return; } /* @@ -1625,9 +1726,8 @@ wlrcv(int unit) * */ static int -wlrequeue(int unit, u_short fd_p) +wlrequeue(struct wl_softc *sc, u_short fd_p) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; fd_t fd; u_short l_rbdp, f_rbdp, rbd_offset; @@ -1683,14 +1783,13 @@ static int xmt_debug = 0; * locations on the WaveLAN board and starts the board off on * the transmit. * - * input : board number of interest, and a pointer to the mbuf + * input : softc pointer for this interface, and a pointer to the mbuf * output : board memory and registers are set for xfer and attention * */ static void -wlxmt(int unit, struct mbuf *m) +wlxmt(struct wl_softc *sc, struct mbuf *m) { - struct wl_softc *sc = WLSOFTC(unit); u_short xmtdata_p = OFFSET_TBUF; u_short xmtshort_p; struct mbuf *tm_p = m; @@ -1705,7 +1804,7 @@ wlxmt(int unit, struct mbuf *m) #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlxmt()\n",unit); + if_printf(&sc->wl_if, "entered wlxmt()\n"); #endif cb.ac_status = 0; @@ -1720,7 +1819,7 @@ wlxmt(int unit, struct mbuf *m) #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) { if (xmt_debug) { - printf("XMT mbuf: L%d @%p ", count, (void *)mb_p); + if_printf(&sc->wl_if, "XMT mbuf: L%d @%p ", count, (void *)mb_p); printf("ether type %x\n", eh_p->ether_type); } } @@ -1758,7 +1857,7 @@ wlxmt(int unit, struct mbuf *m) outw(PIOP1(base), 0); /* buffer_base */ /* at the end -> coallesce remaining mbufs */ if (tbd_p == OFFSET_TBD + (N_TBD-1) * sizeof (tbd_t)) { - wlsftwsleaze(&count, &mb_p, &tm_p, unit); + wlsftwsleaze(&count, &mb_p, &tm_p); continue; } /* next mbuf short -> coallesce as needed */ @@ -1767,7 +1866,7 @@ wlxmt(int unit, struct mbuf *m) tm_p->m_len > HDW_THRESHOLD) /* ok */; else { - wlhdwsleaze(&count, &mb_p, &tm_p, unit); + wlhdwsleaze(&count, &mb_p, &tm_p); continue; } } @@ -1778,13 +1877,13 @@ wlxmt(int unit, struct mbuf *m) #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) if (xmt_debug) - printf("mbuf+ L%d @%p ", count, (void *)mb_p); + if_printf(&sc->wl_if, "mbuf+ L%d @%p ", count, (void *)mb_p); #endif /* WLDEBUG */ } #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) if (xmt_debug) - printf("CLEN = %d\n", clen); + if_printf(&sc->wl_if, "CLEN = %d\n", clen); #endif /* WLDEBUG */ outw(PIOR0(base), tbd_p); if (clen < ETHERMIN) { @@ -1799,7 +1898,7 @@ wlxmt(int unit, struct mbuf *m) #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) { if (xmt_debug) { - wltbd(unit); + wltbd(sc); printf("\n"); } } @@ -1815,11 +1914,11 @@ wlxmt(int unit, struct mbuf *m) break; } if ((spin == 0) && xmt_watch) { /* not waking up, and we care */ - printf("wl%d: slow accepting xmit\n",unit); + if_printf(&sc->wl_if, "slow accepting xmit\n"); } } outw(PIOP0(base), SCB_CU_STRT); /* new command */ - SET_CHAN_ATTN(unit); + SET_CHAN_ATTN(sc); m_freem(m); @@ -1831,7 +1930,6 @@ wlxmt(int unit, struct mbuf *m) if (wl_xmit_delay) { DELAY(wl_xmit_delay); } - return; } /* @@ -1842,9 +1940,8 @@ wlxmt(int unit, struct mbuf *m) * */ static u_short -wlbldru(int unit) +wlbldru(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; fd_t fd; rbd_t rbd; @@ -1900,30 +1997,28 @@ wlbldru(int unit) * */ static void -wlrustrt(int unit) +wlrustrt(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; u_short rfa; #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlrustrt()\n",unit); + if_printf(&sc->wl_if, "entered wlrustrt()\n"); #endif outw(PIOR0(base), OFFSET_SCB); if (inw(PIOP0(base)) & SCB_RUS_READY){ - printf("wlrustrt: RUS_READY\n"); + if_printf(&sc->wl_if, "wlrustrt: RUS_READY\n"); return; } outw(PIOR0(base), OFFSET_SCB + 2); outw(PIOP0(base), SCB_RU_STRT); /* command */ - rfa = wlbldru(unit); + rfa = wlbldru(sc); outw(PIOR0(base), OFFSET_SCB + 6); /* address of scb_rfa_offset */ outw(PIOP0(base), rfa); - SET_CHAN_ATTN(unit); - return; + SET_CHAN_ATTN(sc); } /* @@ -1934,33 +2029,32 @@ wlrustrt(int unit) * */ static int -wldiag(int unit) +wldiag(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); - short base = sc->base; + short base = sc->base; short status; #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wldiag()\n",unit); + if_printf(&sc->wl_if, "entered wldiag()\n"); #endif outw(PIOR0(base), OFFSET_SCB); status = inw(PIOP0(base)); if (status & SCB_SW_INT) { /* state is 2000 which seems ok - printf("wl%d diag(): unexpected initial state %\n", - unit, inw(PIOP0(base))); + if_printf(&sc->wl_if, "diag(): unexpected initial state %\n", + inw(PIOP0(base))); */ - wlack(unit); + wlack(sc); } outw(PIOR1(base), OFFSET_CU); outw(PIOP1(base), 0); /* ac_status */ outw(PIOP1(base), AC_DIAGNOSE|AC_CW_EL);/* ac_command */ - if(wlcmd(unit, "diag()") == 0) + if(wlcmd(sc, "diag()") == 0) return 0; outw(PIOR0(base), OFFSET_CU); if (inw(PIOP0(base)) & 0x0800) { - printf("wl%d: i82586 Self Test failed!\n", unit); + if_printf(&sc->wl_if, "i82586 Self Test failed!\n"); return 0; } return TRUE; @@ -1973,11 +2067,10 @@ wldiag(int unit) * */ static int -wlconfig(int unit) +wlconfig(struct wl_softc *sc) { configure_t configure; - struct wl_softc *sc = WLSOFTC(unit); - short base = sc->base; + short base = sc->base; #if MULTICAST #if defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD_version >= 300000) @@ -1992,16 +2085,16 @@ wlconfig(int unit) #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: entered wlconfig()\n",unit); + if_printf(&sc->wl_if, "entered wlconfig()\n"); #endif outw(PIOR0(base), OFFSET_SCB); if (inw(PIOP0(base)) & SCB_SW_INT) { /* - printf("wl%d config(): unexpected initial state %x\n", - unit, inw(PIOP0(base))); + if_printf(&sc->wl_if, "config(): unexpected initial state %x\n", + inw(PIOP0(base))); */ } - wlack(unit); + wlack(sc); outw(PIOR1(base), OFFSET_CU); outw(PIOP1(base), 0); /* ac_status */ @@ -2042,7 +2135,7 @@ wlconfig(int unit) outw(PIOR1(base), OFFSET_CU + 6); outsw(PIOP1(base), &configure, sizeof(configure_t)/2); - if(wlcmd(unit, "config()-configure") == 0) + if(wlcmd(sc, "config()-configure") == 0) return 0; #if MULTICAST outw(PIOR1(base), OFFSET_CU); @@ -2050,8 +2143,7 @@ wlconfig(int unit) outw(PIOP1(base), AC_MCSETUP|AC_CW_EL); /* ac_command */ outw(PIOR1(base), OFFSET_CU + 8); #if defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD_version >= 300000) - for (ifma = sc->wl_if.if_multiaddrs.lh_first; ifma; - ifma = ifma->ifma_link.le_next) { + LIST_FOREACH(ifma, &sc->wl_if.if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -2098,7 +2190,7 @@ printf("mcast_addr[%d,%d,%d] %x %x %x %x %x %x\n", lo, hi, cnt, #endif outw(PIOR1(base), OFFSET_CU + 6); /* mc-cnt */ outw(PIOP1(base), cnt * WAVELAN_ADDR_SIZE); - if(wlcmd(unit, "config()-mcaddress") == 0) + if(wlcmd(sc, "config()-mcaddress") == 0) return 0; #endif /* MULTICAST */ @@ -2108,10 +2200,10 @@ printf("mcast_addr[%d,%d,%d] %x %x %x %x %x %x\n", lo, hi, cnt, outw(PIOR1(base), OFFSET_CU + 6); outsw(PIOP1(base), sc->wl_addr, WAVELAN_ADDR_SIZE/2); - if(wlcmd(unit, "config()-address") == 0) + if(wlcmd(sc, "config()-address") == 0) return(0); - wlinitmmc(unit); + wlinitmmc(sc); return(1); } @@ -2123,24 +2215,24 @@ printf("mcast_addr[%d,%d,%d] %x %x %x %x %x %x\n", lo, hi, cnt, * completed. Then acknowledge the command completion. */ static int -wlcmd(int unit, char *str) +wlcmd(struct wl_softc *sc, const char *str) { - struct wl_softc *sc = WLSOFTC(unit); - short base = sc->base; + short base = sc->base; int i; outw(PIOR0(base), OFFSET_SCB + 2); /* address of scb_command */ outw(PIOP0(base), SCB_CU_STRT); - SET_CHAN_ATTN(unit); + SET_CHAN_ATTN(sc); outw(PIOR0(base), OFFSET_CU); for(i = 0; i < 0xffff; i++) if (inw(PIOP0(base)) & AC_SW_C) break; if (i == 0xffff || !(inw(PIOP0(base)) & AC_SW_OK)) { - printf("wl%d: %s failed; status = %d, inw = %x, outw = %x\n", - unit, str, inw(PIOP0(base)) & AC_SW_OK, inw(PIOP0(base)), inw(PIOR0(base))); + if_printf(&sc->wl_if, "%s failed; status = %d, inw = %x, outw = %x\n", + str, inw(PIOP0(base)) & AC_SW_OK, inw(PIOP0(base)), + inw(PIOR0(base))); outw(PIOR0(base), OFFSET_SCB); printf("scb_status %x\n", inw(PIOP0(base))); outw(PIOR0(base), OFFSET_SCB+2); @@ -2155,11 +2247,11 @@ wlcmd(int unit, char *str) outw(PIOR0(base), OFFSET_SCB); if ((inw(PIOP0(base)) & SCB_SW_INT) && (inw(PIOP0(base)) != SCB_SW_CNA)) { /* - printf("wl%d %s: unexpected final state %x\n", - unit, str, inw(PIOP0(base))); + if_printf(&sc->wl_if, "%s: unexpected final state %x\n", + str, inw(PIOP0(base))); */ } - wlack(unit); + wlack(sc); return(TRUE); } @@ -2171,11 +2263,10 @@ wlcmd(int unit, char *str) * conditions that wlack() acknowledged. */ static int -wlack(int unit) +wlack(struct wl_softc *sc) { int i; u_short cmd; - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; outw(PIOR1(base), OFFSET_SCB); @@ -2183,21 +2274,20 @@ wlack(int unit) return(0); #ifdef WLDEBUG if (sc->wl_if.if_flags & IFF_DEBUG) - printf("wl%d: doing a wlack()\n",unit); + if_printf(&sc->wl_if, "doing a wlack()\n"); #endif outw(PIOP1(base), cmd); - SET_CHAN_ATTN(unit); + SET_CHAN_ATTN(sc); outw(PIOR0(base), OFFSET_SCB + 2); /* address of scb_command */ for (i = 1000000; inw(PIOP0(base)) && (i-- > 0); ); if (i < 1) - printf("wl%d wlack(): board not accepting command.\n", unit); + if_printf(&sc->wl_if, "wlack(): board not accepting command.\n"); return(cmd); } static void -wltbd(int unit) +wltbd(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; u_short tbd_p = OFFSET_TBD; tbd_t tbd; @@ -2219,7 +2309,7 @@ wltbd(int unit) } static void -wlhdwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, int unit) +wlhdwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp) { struct mbuf *tm_p = *tm_pp; u_char *mb_p = *mb_pp; @@ -2261,12 +2351,10 @@ wlhdwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, int unit) *countp = count; *mb_pp = (u_char *) t_packet; *tm_pp = tm_p; - return; } - static void -wlsftwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, int unit) +wlsftwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp) { struct mbuf *tm_p = *tm_pp; u_short count = 0; @@ -2286,18 +2374,16 @@ wlsftwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, int unit) *countp = count; *mb_pp = (u_char *) t_packet; *tm_pp = tm_p; - return; } static void -wlmmcstat(int unit) +wlmmcstat(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; u_short tmp; - printf("wl%d: DCE_STATUS: 0x%x, ", unit, - wlmmcread(base,MMC_DCE_STATUS) & 0x0f); + if_printf(&sc->wl_if, "DCE_STATUS: 0x%x, ", + wlmmcread(base,MMC_DCE_STATUS) & 0x0f); tmp = wlmmcread(base,MMC_CORRECT_NWID_H) << 8; tmp |= wlmmcread(base,MMC_CORRECT_NWID_L); printf("Correct NWID's: %d, ", tmp); @@ -2325,7 +2411,7 @@ wlmmcread(u_int base, u_short reg) } static void -getsnr(int unit) +getsnr(struct wl_softc *sc) { MMC_WRITE(MMC_FREEZE,1); /* @@ -2371,11 +2457,10 @@ wlgetpsa(int base, u_char *buf) ** preserve the hacr. */ static void -wlsetpsa(int unit) +wlsetpsa(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; - int i, oldpri; + int i; u_short crc; crc = wlpsacrc(sc->psa); /* calculate CRC of PSA */ @@ -2383,8 +2468,6 @@ wlsetpsa(int unit) sc->psa[WLPSA_CRCHIGH] = (crc >> 8) & 0xff; sc->psa[WLPSA_CRCOK] = 0x55; /* default to 'bad' until programming complete */ - oldpri = splimp(); /* ick, long pause */ - PCMD(base, HACR_DEFAULT & ~HACR_16BITS); PCMD(base, HACR_DEFAULT & ~HACR_16BITS); @@ -2403,8 +2486,6 @@ wlsetpsa(int unit) PCMD(base, HACR_DEFAULT); PCMD(base, HACR_DEFAULT); - - splx(oldpri); } /* @@ -2478,10 +2559,8 @@ SYSCTL_INT(_machdep, OID_AUTO, wl_cache_iponly, CTLFLAG_RW, /* zero out the cache */ static void -wl_cache_zero(int unit) +wl_cache_zero(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); - bzero(&sc->w_sigcache[0], sizeof(struct w_sigcache) * MAXCACHEITEMS); sc->w_sigitems = 0; sc->w_nextcache = 0; @@ -2495,14 +2574,13 @@ wl_cache_zero(int unit) * throw out non-ip (on by default, but can be turned off) */ static -void wl_cache_store (int unit, int base, struct ether_header *eh, +void wl_cache_store (struct wl_softc *sc, int base, struct ether_header *eh, struct mbuf *m) { struct ip *ip = NULL; /* Avoid GCC warning */ int i; int signal, silence; int w_insertcache; /* computed index for cache entry storage */ - struct wl_softc *sc = WLSOFTC(unit); int ipflag = wl_cache_iponly; /* filters: @@ -2622,9 +2700,8 @@ void wl_cache_store (int unit, int base, struct ether_header *eh, #if defined(__FreeBSD__) && __FreeBSD_version < 300000 /* not required */ static int -check_allmulti(int unit) +check_allmulti(struct wl_softc *sc) { - struct wl_softc *sc = WLSOFTC(unit); short base = sc->base; struct ether_multi *enm; struct ether_multistep step;