diff options
Diffstat (limited to 'sys/dev/wb')
-rw-r--r-- | sys/dev/wb/if_wb.c | 272 | ||||
-rw-r--r-- | sys/dev/wb/if_wbreg.h | 22 |
2 files changed, 45 insertions, 249 deletions
diff --git a/sys/dev/wb/if_wb.c b/sys/dev/wb/if_wb.c index f924d3e..daac022 100644 --- a/sys/dev/wb/if_wb.c +++ b/sys/dev/wb/if_wb.c @@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcivar.h> #include <dev/mii/mii.h> +#include <dev/mii/mii_bitbang.h> #include <dev/mii/miivar.h> /* "device miibus" required. See GENERIC if you get errors here. */ @@ -129,7 +130,7 @@ MODULE_DEPEND(wb, miibus, 1, 1, 1); /* * Various supported device vendors/types and their names. */ -static struct wb_type wb_devs[] = { +static const struct wb_type const wb_devs[] = { { WB_VENDORID, WB_DEVICEID_840F, "Winbond W89C840F 10/100BaseTX" }, { CP_VENDORID, CP_DEVICEID_RL100, @@ -166,10 +167,6 @@ static void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *); static void wb_eeprom_putbyte(struct wb_softc *, int); static void wb_eeprom_getword(struct wb_softc *, int, u_int16_t *); static void wb_read_eeprom(struct wb_softc *, caddr_t, int, int, int); -static void wb_mii_sync(struct wb_softc *); -static void wb_mii_send(struct wb_softc *, u_int32_t, int); -static int wb_mii_readreg(struct wb_softc *, struct wb_mii_frame *); -static int wb_mii_writereg(struct wb_softc *, struct wb_mii_frame *); static void wb_setcfg(struct wb_softc *, u_int32_t); static void wb_setmulti(struct wb_softc *); @@ -182,6 +179,24 @@ static int wb_miibus_readreg(device_t, int, int); static int wb_miibus_writereg(device_t, int, int, int); static void wb_miibus_statchg(device_t); +/* + * MII bit-bang glue + */ +static uint32_t wb_mii_bitbang_read(device_t); +static void wb_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops wb_mii_bitbang_ops = { + wb_mii_bitbang_read, + wb_mii_bitbang_write, + { + WB_SIO_MII_DATAOUT, /* MII_BIT_MDO */ + WB_SIO_MII_DATAIN, /* MII_BIT_MDI */ + WB_SIO_MII_CLK, /* MII_BIT_MDC */ + WB_SIO_MII_DIR, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + #ifdef WB_USEIOSPACE #define WB_RES SYS_RES_IOPORT #define WB_RID WB_PCI_LOIO @@ -262,8 +277,6 @@ wb_eeprom_putbyte(sc, addr) SIO_CLR(WB_SIO_EE_CLK); DELAY(100); } - - return; } /* @@ -304,8 +317,6 @@ wb_eeprom_getword(sc, addr, dest) CSR_WRITE_4(sc, WB_SIO, 0); *dest = word; - - return; } /* @@ -330,194 +341,39 @@ wb_read_eeprom(sc, dest, off, cnt, swap) else *ptr = word; } - - return; } /* - * Sync the PHYs by setting data bit and strobing the clock 32 times. + * Read the MII serial port for the MII bit-bang module. */ -static void -wb_mii_sync(sc) - struct wb_softc *sc; +static uint32_t +wb_mii_bitbang_read(device_t dev) { - register int i; + struct wb_softc *sc; + uint32_t val; - SIO_SET(WB_SIO_MII_DIR|WB_SIO_MII_DATAIN); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - } + val = CSR_READ_4(sc, WB_SIO); + CSR_BARRIER(sc, WB_SIO, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - return; + return (val); } /* - * Clock a series of bits through the MII. + * Write the MII serial port for the MII bit-bang module. */ static void -wb_mii_send(sc, bits, cnt) - struct wb_softc *sc; - u_int32_t bits; - int cnt; -{ - int i; - - SIO_CLR(WB_SIO_MII_CLK); - - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { - SIO_SET(WB_SIO_MII_DATAIN); - } else { - SIO_CLR(WB_SIO_MII_DATAIN); - } - DELAY(1); - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - SIO_SET(WB_SIO_MII_CLK); - } -} - -/* - * Read an PHY register through the MII. - */ -static int -wb_mii_readreg(sc, frame) - struct wb_softc *sc; - struct wb_mii_frame *frame; - +wb_mii_bitbang_write(device_t dev, uint32_t val) { - int i, ack; - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = WB_MII_STARTDELIM; - frame->mii_opcode = WB_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - CSR_WRITE_4(sc, WB_SIO, 0); - - /* - * Turn on data xmit. - */ - SIO_SET(WB_SIO_MII_DIR); - - wb_mii_sync(sc); - - /* - * Send command/address info. - */ - wb_mii_send(sc, frame->mii_stdelim, 2); - wb_mii_send(sc, frame->mii_opcode, 2); - wb_mii_send(sc, frame->mii_phyaddr, 5); - wb_mii_send(sc, frame->mii_regaddr, 5); - - /* Idle bit */ - SIO_CLR((WB_SIO_MII_CLK|WB_SIO_MII_DATAIN)); - DELAY(1); - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - - /* Turn off xmit. */ - SIO_CLR(WB_SIO_MII_DIR); - /* Check for ack */ - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - ack = CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT; - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - - /* - * Now try reading data bits. If the ack failed, we still - * need to clock through 16 cycles to keep the PHY(s) in sync. - */ - if (ack) { - for(i = 0; i < 16; i++) { - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - if (!ack) { - if (CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT) - frame->mii_data |= i; - DELAY(1); - } - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - } - -fail: + struct wb_softc *sc; - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - - if (ack) - return(1); - return(0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -wb_mii_writereg(sc, frame) - struct wb_softc *sc; - struct wb_mii_frame *frame; - -{ - - /* - * Set up frame for TX. - */ - - frame->mii_stdelim = WB_MII_STARTDELIM; - frame->mii_opcode = WB_MII_WRITEOP; - frame->mii_turnaround = WB_MII_TURNAROUND; - - /* - * Turn on data output. - */ - SIO_SET(WB_SIO_MII_DIR); - - wb_mii_sync(sc); - - wb_mii_send(sc, frame->mii_stdelim, 2); - wb_mii_send(sc, frame->mii_opcode, 2); - wb_mii_send(sc, frame->mii_phyaddr, 5); - wb_mii_send(sc, frame->mii_regaddr, 5); - wb_mii_send(sc, frame->mii_turnaround, 2); - wb_mii_send(sc, frame->mii_data, 16); - - /* Idle bit. */ - SIO_SET(WB_SIO_MII_CLK); - DELAY(1); - SIO_CLR(WB_SIO_MII_CLK); - DELAY(1); - - /* - * Turn off xmit. - */ - SIO_CLR(WB_SIO_MII_DIR); + sc = device_get_softc(dev); - return(0); + CSR_WRITE_4(sc, WB_SIO, val); + CSR_BARRIER(sc, WB_SIO, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } static int @@ -525,18 +381,8 @@ wb_miibus_readreg(dev, phy, reg) device_t dev; int phy, reg; { - struct wb_softc *sc; - struct wb_mii_frame frame; - - sc = device_get_softc(dev); - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - wb_mii_readreg(sc, &frame); - - return(frame.mii_data); + return (mii_bitbang_readreg(dev, &wb_mii_bitbang_ops, phy, reg)); } static int @@ -544,18 +390,8 @@ wb_miibus_writereg(dev, phy, reg, data) device_t dev; int phy, reg, data; { - struct wb_softc *sc; - struct wb_mii_frame frame; - sc = device_get_softc(dev); - - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - - wb_mii_writereg(sc, &frame); + mii_bitbang_writereg(dev, &wb_mii_bitbang_ops, phy, reg, data); return(0); } @@ -570,8 +406,6 @@ wb_miibus_statchg(dev) sc = device_get_softc(dev); mii = device_get_softc(sc->wb_miibus); wb_setcfg(sc, mii->mii_media_active); - - return; } /* @@ -627,8 +461,6 @@ wb_setmulti(sc) CSR_WRITE_4(sc, WB_MAR0, hashes[0]); CSR_WRITE_4(sc, WB_MAR1, hashes[1]); CSR_WRITE_4(sc, WB_NETCFG, rxfilt); - - return; } /* @@ -671,8 +503,6 @@ wb_setcfg(sc, media) if (restart) WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON|WB_NETCFG_RX_ON); - - return; } static void @@ -742,7 +572,7 @@ static int wb_probe(dev) device_t dev; { - struct wb_type *t; + const struct wb_type *t; t = wb_devs; @@ -1001,7 +831,7 @@ wb_bfree(buf, args) void *buf; void *args; { - return; + } /* @@ -1127,8 +957,6 @@ wb_rxeoc(sc) WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON); if (CSR_READ_4(sc, WB_ISR) & WB_RXSTATE_SUSPEND) CSR_WRITE_4(sc, WB_RXSTART, 0xFFFFFFFF); - - return; } /* @@ -1185,8 +1013,6 @@ wb_txeof(sc) sc->wb_cdata.wb_tx_head = cur_tx->wb_nextdesc; } - - return; } /* @@ -1212,8 +1038,6 @@ wb_txeoc(sc) CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF); } } - - return; } static void @@ -1300,8 +1124,6 @@ wb_intr(arg) } WB_UNLOCK(sc); - - return; } static void @@ -1320,8 +1142,6 @@ wb_tick(xsc) if (sc->wb_timer > 0 && --sc->wb_timer == 0) wb_watchdog(sc); callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); - - return; } /* @@ -1520,8 +1340,6 @@ wb_start_locked(ifp) * Set a timeout in case the chip goes out to lunch. */ sc->wb_timer = 5; - - return; } static void @@ -1647,8 +1465,6 @@ wb_init_locked(sc) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); - - return; } /* @@ -1690,8 +1506,6 @@ wb_ifmedia_sts(ifp, ifmr) ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; WB_UNLOCK(sc); - - return; } static int @@ -1757,8 +1571,6 @@ wb_watchdog(sc) if (ifp->if_snd.ifq_head != NULL) wb_start_locked(ifp); - - return; } /* @@ -1809,8 +1621,6 @@ wb_stop(sc) sizeof(sc->wb_ldata->wb_tx_list)); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - return; } /* diff --git a/sys/dev/wb/if_wbreg.h b/sys/dev/wb/if_wbreg.h index 95d0a8e..16eb8a1 100644 --- a/sys/dev/wb/if_wbreg.h +++ b/sys/dev/wb/if_wbreg.h @@ -341,26 +341,9 @@ struct wb_chain_data { struct wb_type { u_int16_t wb_vid; u_int16_t wb_did; - char *wb_name; + const char *wb_name; }; -struct wb_mii_frame { - u_int8_t mii_stdelim; - u_int8_t mii_opcode; - u_int8_t mii_phyaddr; - u_int8_t mii_regaddr; - u_int8_t mii_turnaround; - u_int16_t mii_data; -}; - -/* - * MII constants - */ -#define WB_MII_STARTDELIM 0x01 -#define WB_MII_READOP 0x02 -#define WB_MII_WRITEOP 0x01 -#define WB_MII_TURNAROUND 0x02 - struct wb_softc { struct ifnet *wb_ifp; /* interface info */ device_t wb_dev; @@ -395,6 +378,9 @@ struct wb_softc { #define CSR_READ_2(sc, reg) bus_read_2(sc->wb_res, reg) #define CSR_READ_1(sc, reg) bus_read_1(sc->wb_res, reg) +#define CSR_BARRIER(sc, reg, length, flags) \ + bus_barrier(sc->wb_res, reg, length, flags) + #define WB_TIMEOUT 1000 /* |