Index: arm/conf/GUMSTIX =================================================================== --- arm/conf/GUMSTIX (revision 226148) +++ arm/conf/GUMSTIX (working copy) @@ -70,6 +70,7 @@ options PREEMPTION device loop device ether device mii +device mii_bitbang device smc device smcphy device uart Index: conf/NOTES =================================================================== --- conf/NOTES (revision 226165) +++ conf/NOTES (working copy) @@ -1846,13 +1846,15 @@ device puc # MII bus support is required for many PCI Ethernet NICs, # namely those which use MII-compliant transceivers or implement # transceiver control interfaces that operate like an MII. Adding -# "device miibus" to the kernel config pulls in support for -# the generic miibus API and all of the PHY drivers, including a -# generic one for PHYs that aren't specifically handled by an -# individual driver. Support for specific PHYs may be built by adding -# "device mii" then adding the appropriate PHY driver. -device miibus # MII support including all PHYs +# "device miibus" to the kernel config pulls in support for the generic +# miibus API, the common support for for bit-bang'ing the MII and all +# of the PHY drivers, including a generic one for PHYs that aren't +# specifically handled by an individual driver. Support for specific +# PHYs may be built by adding "device mii", "device mii_bitbang" if +# needed by the NIC driver and then adding the appropriate PHY driver. device mii # Minimal MII support +device mii_bitbang # Common module for bit-bang'ing the MII +device miibus # MII support w/ bit-bang'ing and all PHYs device acphy # Altima Communications AC101 device amphy # AMD AM79c873 / Davicom DM910{1,2} Index: conf/files =================================================================== --- conf/files (revision 226154) +++ conf/files (working copy) @@ -1425,6 +1425,7 @@ dev/mii/ip1000phy.c optional miibus | ip1000phy dev/mii/jmphy.c optional miibus | jmphy dev/mii/lxtphy.c optional miibus | lxtphy dev/mii/mii.c optional miibus | mii +dev/mii/mii_bitbang.c optional miibus | mii_bitbang dev/mii/mii_physubr.c optional miibus | mii dev/mii/miibus_if.m optional miibus | mii dev/mii/mlphy.c optional miibus | mlphy Index: dev/bm/if_bm.c =================================================================== --- dev/bm/if_bm.c (revision 226148) +++ dev/bm/if_bm.c (working copy) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -105,17 +106,28 @@ static void bm_tick (void *xsc); static int bm_ifmedia_upd (struct ifnet *); static void bm_ifmedia_sts (struct ifnet *, struct ifmediareq *); -static void bm_miicsr_dwrite (struct bm_softc *, u_int16_t); -static void bm_mii_writebit (struct bm_softc *, int); -static int bm_mii_readbit (struct bm_softc *); -static void bm_mii_sync (struct bm_softc *); -static void bm_mii_send (struct bm_softc *, u_int32_t, int); -static int bm_mii_readreg (struct bm_softc *, struct bm_mii_frame *); -static int bm_mii_writereg (struct bm_softc *, struct bm_mii_frame *); static int bm_miibus_readreg (device_t, int, int); static int bm_miibus_writereg (device_t, int, int, int); static void bm_miibus_statchg (device_t); +/* + * MII bit-bang glue + */ +static uint32_t bm_mii_bitbang_read(device_t); +static void bm_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops bm_mii_bitbang_ops = { + bm_mii_bitbang_read, + bm_mii_bitbang_write, + { + BM_MII_DATAOUT, /* MII_BIT_MDO */ + BM_MII_DATAIN, /* MII_BIT_MDI */ + BM_MII_CLK, /* MII_BIT_MDC */ + BM_MII_OENABLE, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + static device_method_t bm_methods[] = { /* Device interface */ DEVMETHOD(device_probe, bm_probe), @@ -150,208 +162,54 @@ DRIVER_MODULE(miibus, bm, miibus_driver, miibus_de */ /* - * Write to the MII csr, introducing a delay to allow valid - * MII clock pulses to be formed + * Write the MII serial port for the MII bit-bang module. */ static void -bm_miicsr_dwrite(struct bm_softc *sc, u_int16_t val) +bm_mii_bitbang_write(device_t dev, uint32_t val) { - CSR_WRITE_2(sc, BM_MII_CSR, val); - /* - * Assume this is a clock toggle and generate a 1us delay - * to cover both MII's 160ns high/low minimum and 400ns - * cycle miniumum - */ - DELAY(1); -} + struct bm_softc *sc; -/* - * Write a bit to the MII bus. - */ -static void -bm_mii_writebit(struct bm_softc *sc, int bit) -{ - u_int16_t regval; + sc = device_get_softc(dev); - regval = BM_MII_OENABLE; - if (bit) - regval |= BM_MII_DATAOUT; - - bm_miicsr_dwrite(sc, regval); - bm_miicsr_dwrite(sc, regval | BM_MII_CLK); - bm_miicsr_dwrite(sc, regval); + CSR_WRITE_2(sc, BM_MII_CSR, val); + CSR_BARRIER(sc, BM_MII_CSR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } /* - * Read a bit from the MII bus. + * Read the MII serial port for the MII bit-bang module. */ -static int -bm_mii_readbit(struct bm_softc *sc) +static uint32_t +bm_mii_bitbang_read(device_t dev) { - u_int16_t regval, bitin; + struct bm_softc *sc; + uint32_t reg; - /* ~BM_MII_OENABLE */ - regval = 0; + sc = device_get_softc(dev); - bm_miicsr_dwrite(sc, regval); - bm_miicsr_dwrite(sc, regval | BM_MII_CLK); - bm_miicsr_dwrite(sc, regval); - bitin = CSR_READ_2(sc, BM_MII_CSR) & BM_MII_DATAIN; + reg = CSR_READ_2(sc, BM_MII_CSR); + CSR_BARRIER(sc, BM_MII_CSR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - return (bitin == BM_MII_DATAIN); + return (reg); } /* - * Sync the PHYs by setting data bit and strobing the clock 32 times. - */ -static void -bm_mii_sync(struct bm_softc *sc) -{ - int i; - u_int16_t regval; - - regval = BM_MII_OENABLE | BM_MII_DATAOUT; - - bm_miicsr_dwrite(sc, regval); - for (i = 0; i < 32; i++) { - bm_miicsr_dwrite(sc, regval | BM_MII_CLK); - bm_miicsr_dwrite(sc, regval); - } -} - -/* - * Clock a series of bits through the MII. - */ -static void -bm_mii_send(struct bm_softc *sc, u_int32_t bits, int cnt) -{ - int i; - - for (i = (0x1 << (cnt - 1)); i; i >>= 1) - bm_mii_writebit(sc, bits & i); -} - -/* - * Read a PHY register through the MII. - */ -static int -bm_mii_readreg(struct bm_softc *sc, struct bm_mii_frame *frame) -{ - int i, ack, bit; - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = BM_MII_STARTDELIM; - frame->mii_opcode = BM_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - /* - * Sync the PHYs - */ - bm_mii_sync(sc); - - /* - * Send command/address info - */ - bm_mii_send(sc, frame->mii_stdelim, 2); - bm_mii_send(sc, frame->mii_opcode, 2); - bm_mii_send(sc, frame->mii_phyaddr, 5); - bm_mii_send(sc, frame->mii_regaddr, 5); - - /* - * Check for ack. - */ - ack = bm_mii_readbit(sc); - - /* - * Now try reading data bits. If the ack failed, we still - * need to clock through 16 cycles to keep the PHY(s) in sync. - */ - for (i = 0x8000; i; i >>= 1) { - bit = bm_mii_readbit(sc); - if (!ack && bit) - frame->mii_data |= i; - } - - /* - * Skip through idle bit-times - */ - bm_mii_writebit(sc, 0); - bm_mii_writebit(sc, 0); - - return ((ack) ? 1 : 0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -bm_mii_writereg(struct bm_softc *sc, struct bm_mii_frame *frame) -{ - /* - * Set up frame for tx - */ - frame->mii_stdelim = BM_MII_STARTDELIM; - frame->mii_opcode = BM_MII_WRITEOP; - frame->mii_turnaround = BM_MII_TURNAROUND; - - /* - * Sync the phy and start the bitbang write sequence - */ - bm_mii_sync(sc); - - bm_mii_send(sc, frame->mii_stdelim, 2); - bm_mii_send(sc, frame->mii_opcode, 2); - bm_mii_send(sc, frame->mii_phyaddr, 5); - bm_mii_send(sc, frame->mii_regaddr, 5); - bm_mii_send(sc, frame->mii_turnaround, 2); - bm_mii_send(sc, frame->mii_data, 16); - - /* - * Idle bit. - */ - bm_mii_writebit(sc, 0); - - return (0); -} - -/* * MII bus i/f */ static int bm_miibus_readreg(device_t dev, int phy, int reg) { - struct bm_softc *sc; - struct bm_mii_frame frame; - sc = device_get_softc(dev); - bzero(&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - - bm_mii_readreg(sc, &frame); - - return (frame.mii_data); + return (mii_bitbang_readreg(dev, &bm_mii_bitbang_ops, phy, reg)); } static int bm_miibus_writereg(device_t dev, int phy, int reg, int data) { - struct bm_softc *sc; - struct bm_mii_frame frame; - sc = device_get_softc(dev); - bzero(&frame, sizeof(frame)); + mii_bitbang_readreg(dev, &bm_mii_bitbang_ops, phy, reg); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - - bm_mii_writereg(sc, &frame); - return (0); } Index: dev/bm/if_bmreg.h =================================================================== --- dev/bm/if_bmreg.h (revision 226148) +++ dev/bm/if_bmreg.h (working copy) @@ -129,14 +129,6 @@ #define BM_MII_DATAIN 0x0008 /* MDIO data in */ /* - * MII constants - */ -#define BM_MII_STARTDELIM 0x01 -#define BM_MII_READOP 0x02 -#define BM_MII_WRITEOP 0x01 -#define BM_MII_TURNAROUND 0x02 - -/* * Various flags */ @@ -174,3 +166,5 @@ #define CSR_READ_1(sc, reg) \ bus_read_1(sc->sc_memr, reg) +#define CSR_BARRIER(sc, reg, length, flags) \ + bus_barrier(sc->sc_memr, reg, length, flags) Index: dev/bm/if_bmvar.h =================================================================== --- dev/bm/if_bmvar.h (revision 226148) +++ dev/bm/if_bmvar.h (working copy) @@ -46,7 +46,6 @@ /* * software state for transmit job mbufs (may be elements of mbuf chains) */ - struct bm_txsoft { struct mbuf *txs_mbuf; /* head of our mbuf chain */ bus_dmamap_t txs_dmamap; /* our DMA map */ @@ -71,7 +70,6 @@ struct bm_rxsoft { bus_dma_segment_t segment; }; - struct bm_softc { struct ifnet *sc_ifp; struct mtx sc_mtx; @@ -113,13 +111,3 @@ struct bm_softc { dbdma_channel_t *sc_txdma, *sc_rxdma; }; - -struct bm_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; -}; - Index: dev/dc/if_dc.c =================================================================== --- dev/dc/if_dc.c (revision 226148) +++ dev/dc/if_dc.c (working copy) @@ -122,6 +122,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -149,7 +150,7 @@ MODULE_DEPEND(dc, miibus, 1, 1, 1); /* * Various supported device vendors/types and their names. */ -static const struct dc_type dc_devs[] = { +static const struct dc_type const dc_devs[] = { { DC_DEVID(DC_VENDORID_DEC, DC_DEVICEID_21143), 0, "Intel 21143 10/100BaseTX" }, { DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9009), 0, @@ -267,12 +268,6 @@ static void dc_eeprom_getword_xircom(struct dc_sof static void dc_eeprom_width(struct dc_softc *); static void dc_read_eeprom(struct dc_softc *, caddr_t, int, int, int); -static void dc_mii_writebit(struct dc_softc *, int); -static int dc_mii_readbit(struct dc_softc *); -static void dc_mii_sync(struct dc_softc *); -static void dc_mii_send(struct dc_softc *, uint32_t, int); -static int dc_mii_readreg(struct dc_softc *, struct dc_mii_frame *); -static int dc_mii_writereg(struct dc_softc *, struct dc_mii_frame *); static int dc_miibus_readreg(device_t, int, int); static int dc_miibus_writereg(device_t, int, int, int); static void dc_miibus_statchg(device_t); @@ -301,6 +296,24 @@ static int dc_decode_leaf_sym(struct dc_softc *, s static void dc_apply_fixup(struct dc_softc *, int); static int dc_check_multiport(struct dc_softc *); +/* + * MII bit-bang glue + */ +static uint32_t dc_mii_bitbang_read(device_t); +static void dc_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops dc_mii_bitbang_ops = { + dc_mii_bitbang_read, + dc_mii_bitbang_write, + { + DC_SIO_MII_DATAOUT, /* MII_BIT_MDO */ + DC_SIO_MII_DATAIN, /* MII_BIT_MDI */ + DC_SIO_MII_CLK, /* MII_BIT_MDC */ + 0, /* MII_BIT_DIR_HOST_PHY */ + DC_SIO_MII_DIR, /* MII_BIT_DIR_PHY_HOST */ + } +}; + #ifdef DC_USEIOSPACE #define DC_RES SYS_RES_IOPORT #define DC_RID DC_PCI_CFBIO @@ -605,185 +618,45 @@ dc_read_eeprom(struct dc_softc *sc, caddr_t dest, } /* - * The following two routines are taken from the Macronix 98713 - * Application Notes pp.19-21. + * Write the MII serial port for the MII bit-bang module. */ -/* - * Write a bit to the MII bus. - */ static void -dc_mii_writebit(struct dc_softc *sc, int bit) +dc_mii_bitbang_write(device_t dev, uint32_t val) { - uint32_t reg; + struct dc_softc *sc; - reg = DC_SIO_ROMCTL_WRITE | (bit != 0 ? DC_SIO_MII_DATAOUT : 0); - CSR_WRITE_4(sc, DC_SIO, reg); - CSR_BARRIER_4(sc, DC_SIO, - BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - DELAY(1); + sc = device_get_softc(dev); - CSR_WRITE_4(sc, DC_SIO, reg | DC_SIO_MII_CLK); + CSR_WRITE_4(sc, DC_SIO, val); CSR_BARRIER_4(sc, DC_SIO, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - DELAY(1); - CSR_WRITE_4(sc, DC_SIO, reg); - CSR_BARRIER_4(sc, DC_SIO, - BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - DELAY(1); } /* - * Read a bit from the MII bus. + * Read the MII serial port for the MII bit-bang module. */ -static int -dc_mii_readbit(struct dc_softc *sc) +static uint32_t +dc_mii_bitbang_read(device_t dev) { - uint32_t reg; + struct dc_softc *sc; + uint32_t val; - reg = DC_SIO_ROMCTL_READ | DC_SIO_MII_DIR; - CSR_WRITE_4(sc, DC_SIO, reg); - CSR_BARRIER_4(sc, DC_SIO, - BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - DELAY(1); - (void)CSR_READ_4(sc, DC_SIO); - CSR_WRITE_4(sc, DC_SIO, reg | DC_SIO_MII_CLK); - CSR_BARRIER_4(sc, DC_SIO, - BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - DELAY(1); - CSR_WRITE_4(sc, DC_SIO, reg); - CSR_BARRIER_4(sc, DC_SIO, - BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - DELAY(1); - if (CSR_READ_4(sc, DC_SIO) & DC_SIO_MII_DATAIN) - return (1); + sc = device_get_softc(dev); - return (0); -} - -/* - * Sync the PHYs by setting data bit and strobing the clock 32 times. - */ -static void -dc_mii_sync(struct dc_softc *sc) -{ - int i; - - CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_WRITE); + val = CSR_READ_4(sc, DC_SIO); CSR_BARRIER_4(sc, DC_SIO, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - DELAY(1); - for (i = 0; i < 32; i++) - dc_mii_writebit(sc, 1); + return (val); } -/* - * Clock a series of bits through the MII. - */ -static void -dc_mii_send(struct dc_softc *sc, uint32_t bits, int cnt) -{ - int i; - - for (i = (0x1 << (cnt - 1)); i; i >>= 1) - dc_mii_writebit(sc, bits & i); -} - -/* - * Read an PHY register through the MII. - */ static int -dc_mii_readreg(struct dc_softc *sc, struct dc_mii_frame *frame) -{ - int i; - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = DC_MII_STARTDELIM; - frame->mii_opcode = DC_MII_READOP; - - /* - * Sync the PHYs. - */ - dc_mii_sync(sc); - - /* - * Send command/address info. - */ - dc_mii_send(sc, frame->mii_stdelim, 2); - dc_mii_send(sc, frame->mii_opcode, 2); - dc_mii_send(sc, frame->mii_phyaddr, 5); - dc_mii_send(sc, frame->mii_regaddr, 5); - - /* - * Now try reading data bits. If the turnaround failed, we still - * need to clock through 16 cycles to keep the PHY(s) in sync. - */ - frame->mii_turnaround = dc_mii_readbit(sc); - if (frame->mii_turnaround != 0) { - for (i = 0; i < 16; i++) - dc_mii_readbit(sc); - goto fail; - } - for (i = 0x8000; i; i >>= 1) { - if (dc_mii_readbit(sc)) - frame->mii_data |= i; - } - -fail: - - /* Clock the idle bits. */ - dc_mii_writebit(sc, 0); - dc_mii_writebit(sc, 0); - - if (frame->mii_turnaround != 0) - return (1); - return (0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -dc_mii_writereg(struct dc_softc *sc, struct dc_mii_frame *frame) -{ - - /* - * Set up frame for TX. - */ - frame->mii_stdelim = DC_MII_STARTDELIM; - frame->mii_opcode = DC_MII_WRITEOP; - frame->mii_turnaround = DC_MII_TURNAROUND; - - /* - * Sync the PHYs. - */ - dc_mii_sync(sc); - - dc_mii_send(sc, frame->mii_stdelim, 2); - dc_mii_send(sc, frame->mii_opcode, 2); - dc_mii_send(sc, frame->mii_phyaddr, 5); - dc_mii_send(sc, frame->mii_regaddr, 5); - dc_mii_send(sc, frame->mii_turnaround, 2); - dc_mii_send(sc, frame->mii_data, 16); - - /* Clock the idle bits. */ - dc_mii_writebit(sc, 0); - dc_mii_writebit(sc, 0); - - return (0); -} - -static int dc_miibus_readreg(device_t dev, int phy, int reg) { - struct dc_mii_frame frame; - struct dc_softc *sc; + struct dc_softc *sc; int i, rval, phy_reg = 0; sc = device_get_softc(dev); - bzero(&frame, sizeof(frame)); if (sc->dc_pmode != DC_PMODE_MII) { if (phy == (MII_NPHY - 1)) { @@ -858,34 +731,29 @@ dc_miibus_readreg(device_t dev, int phy, int reg) } rval = CSR_READ_4(sc, phy_reg) & 0x0000FFFF; - if (rval == 0xFFFF) return (0); return (rval); } - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; if (sc->dc_type == DC_TYPE_98713) { phy_reg = CSR_READ_4(sc, DC_NETCFG); CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL); } - dc_mii_readreg(sc, &frame); + rval = mii_bitbang_readreg(dev, &dc_mii_bitbang_ops, phy, reg); if (sc->dc_type == DC_TYPE_98713) CSR_WRITE_4(sc, DC_NETCFG, phy_reg); - return (frame.mii_data); + return (rval); } static int dc_miibus_writereg(device_t dev, int phy, int reg, int data) { struct dc_softc *sc; - struct dc_mii_frame frame; int i, phy_reg = 0; sc = device_get_softc(dev); - bzero(&frame, sizeof(frame)); if (DC_IS_PNIC(sc)) { CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE | @@ -931,15 +799,11 @@ dc_miibus_writereg(device_t dev, int phy, int reg, return (0); } - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - if (sc->dc_type == DC_TYPE_98713) { phy_reg = CSR_READ_4(sc, DC_NETCFG); CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL); } - dc_mii_writereg(sc, &frame); + mii_bitbang_writereg(dev, &dc_mii_bitbang_ops, phy, reg, data); if (sc->dc_type == DC_TYPE_98713) CSR_WRITE_4(sc, DC_NETCFG, phy_reg); Index: dev/dc/if_dcreg.h =================================================================== --- dev/dc/if_dcreg.h (revision 226148) +++ dev/dc/if_dcreg.h (working copy) @@ -525,28 +525,10 @@ struct dc_mediainfo { struct dc_type { uint32_t dc_devid; uint8_t dc_minrev; - char *dc_name; + const char *dc_name; }; -struct dc_mii_frame { - uint8_t mii_stdelim; - uint8_t mii_opcode; - uint8_t mii_phyaddr; - uint8_t mii_regaddr; - uint8_t mii_turnaround; - uint16_t mii_data; -}; - /* - * MII constants - */ -#define DC_MII_STARTDELIM 0x01 -#define DC_MII_READOP 0x02 -#define DC_MII_WRITEOP 0x01 -#define DC_MII_TURNAROUND 0x02 - - -/* * Registers specific to clone devices. * This mainly relates to RX filter programming: not all 21x4x clones * use the standard DEC filter programming mechanism. @@ -804,7 +786,7 @@ struct dc_softc { #define CSR_READ_4(sc, reg) \ bus_space_read_4(sc->dc_btag, sc->dc_bhandle, reg) -#define CSR_BARRIER_4(sc, reg, flags) \ +#define CSR_BARRIER_4(sc, reg, flags) \ bus_space_barrier(sc->dc_btag, sc->dc_bhandle, reg, 4, flags) #define DC_TIMEOUT 1000 Index: dev/mii/mii_bitbang.c =================================================================== --- dev/mii/mii_bitbang.c (revision 0) +++ dev/mii/mii_bitbang.c (revision 0) @@ -0,0 +1,180 @@ +/* $NetBSD: mii_bitbang.c,v 1.12 2008/05/04 17:06:09 xtraeme Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following didevlaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following didevlaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Common module for bit-bang'ing the MII. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include + +MODULE_VERSION(mii_bitbang, 1); + +static void mii_bitbang_sendbits(device_t dev, mii_bitbang_ops_t ops, + uint32_t data, int nbits); + +#define MWRITE(x) \ +do { \ + ops->mbo_write(dev, (x)); \ + DELAY(1); \ +} while (/* CONSTCOND */ 0) + +#define MREAD ops->mbo_read(dev) + +#define MDO ops->mbo_bits[MII_BIT_MDO] +#define MDI ops->mbo_bits[MII_BIT_MDI] +#define MDC ops->mbo_bits[MII_BIT_MDC] +#define MDIRPHY ops->mbo_bits[MII_BIT_DIR_HOST_PHY] +#define MDIRHOST ops->mbo_bits[MII_BIT_DIR_PHY_HOST] + +/* + * mii_bitbang_sync: + * + * Synchronize the MII. + */ +void +mii_bitbang_sync(device_t dev, mii_bitbang_ops_t ops) +{ + int i; + uint32_t v; + + v = MDIRPHY | MDO; + + MWRITE(v); + for (i = 0; i < 32; i++) { + MWRITE(v | MDC); + MWRITE(v); + } +} + +/* + * mii_bitbang_sendbits: + * + * Send a series of bits to the MII. + */ +static void +mii_bitbang_sendbits(device_t dev, mii_bitbang_ops_t ops, uint32_t data, + int nbits) +{ + int i; + uint32_t v; + + v = MDIRPHY; + MWRITE(v); + + for (i = 1 << (nbits - 1); i != 0; i >>= 1) { + if (data & i) + v |= MDO; + else + v &= ~MDO; + MWRITE(v); + MWRITE(v | MDC); + MWRITE(v); + } +} + +/* + * mii_bitbang_readreg: + * + * Read a PHY register by bit-bang'ing the MII. + */ +int +mii_bitbang_readreg(device_t dev, mii_bitbang_ops_t ops, int phy, int reg) +{ + int i, error, val; + + mii_bitbang_sync(dev, ops); + + mii_bitbang_sendbits(dev, ops, MII_COMMAND_START, 2); + mii_bitbang_sendbits(dev, ops, MII_COMMAND_READ, 2); + mii_bitbang_sendbits(dev, ops, phy, 5); + mii_bitbang_sendbits(dev, ops, reg, 5); + + /* Switch direction to PHY->host, without a clock transition. */ + MWRITE(MDIRHOST); + + /* Turnaround clock. */ + MWRITE(MDIRHOST | MDC); + MWRITE(MDIRHOST); + + /* Check for error. */ + error = MREAD & MDI; + + /* Idle clock. */ + MWRITE(MDIRHOST | MDC); + MWRITE(MDIRHOST); + + val = 0; + for (i = 0; i < 16; i++) { + val <<= 1; + /* Read data prior to clock low-high transition. */ + if (error == 0 && (MREAD & MDI) != 0) + val |= 1; + + MWRITE(MDIRHOST | MDC); + MWRITE(MDIRHOST); + } + + /* Set direction to host->PHY, without a clock transition. */ + MWRITE(MDIRPHY); + + return (error != 0 ? 0 : val); +} + +/* + * mii_bitbang_writereg: + * + * Write a PHY register by bit-bang'ing the MII. + */ +void +mii_bitbang_writereg(device_t dev, mii_bitbang_ops_t ops, int phy, int reg, + int val) +{ + + mii_bitbang_sync(dev, ops); + + mii_bitbang_sendbits(dev, ops, MII_COMMAND_START, 2); + mii_bitbang_sendbits(dev, ops, MII_COMMAND_WRITE, 2); + mii_bitbang_sendbits(dev, ops, phy, 5); + mii_bitbang_sendbits(dev, ops, reg, 5); + mii_bitbang_sendbits(dev, ops, MII_COMMAND_ACK, 2); + mii_bitbang_sendbits(dev, ops, val, 16); + + MWRITE(MDIRPHY); +} Property changes on: dev/mii/mii_bitbang.c ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + FreeBSD=%H Added: svn:eol-style + native Index: dev/mii/mii_bitbang.h =================================================================== --- dev/mii/mii_bitbang.h (revision 0) +++ dev/mii/mii_bitbang.h (revision 0) @@ -0,0 +1,54 @@ +/* $NetBSD: mii_bitbang.h,v 1.6 2009/05/12 14:31:27 cegger Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define MII_BIT_MDO 0 /* data out (host->PHY) */ +#define MII_BIT_MDI 1 /* data in (PHY->host) */ +#define MII_BIT_MDC 2 /* clock */ +#define MII_BIT_DIR_HOST_PHY 3 /* set direction: host->PHY */ +#define MII_BIT_DIR_PHY_HOST 4 /* set direction: PHY->host */ +#define MII_NBITS 5 + +struct mii_bitbang_ops { + uint32_t (*mbo_read)(device_t); + void (*mbo_write)(device_t, uint32_t); + uint32_t mbo_bits[MII_NBITS]; +}; + +typedef const struct mii_bitbang_ops *mii_bitbang_ops_t; + +int mii_bitbang_readreg(device_t dev, mii_bitbang_ops_t ops, + int phy, int reg); +void mii_bitbang_sync(device_t dev, mii_bitbang_ops_t ops); +void mii_bitbang_writereg(device_t dev, mii_bitbang_ops_t ops, + int phy, int reg, int val); Property changes on: dev/mii/mii_bitbang.h ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + FreeBSD=%H Added: svn:eol-style + native Index: dev/nge/if_nge.c =================================================================== --- dev/nge/if_nge.c (revision 226148) +++ dev/nge/if_nge.c (working copy) @@ -117,6 +117,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -138,7 +139,7 @@ MODULE_DEPEND(nge, miibus, 1, 1, 1); /* * Various supported device vendors/types and their names. */ -static struct nge_type nge_devs[] = { +static const struct nge_type const nge_devs[] = { { NGE_VENDORID, NGE_DEVICEID, "National Semiconductor Gigabit Ethernet" }, { 0, 0, NULL } @@ -180,11 +181,6 @@ static void nge_eeprom_putbyte(struct nge_softc *, static void nge_eeprom_getword(struct nge_softc *, int, uint16_t *); static void nge_read_eeprom(struct nge_softc *, caddr_t, int, int); -static void nge_mii_sync(struct nge_softc *); -static void nge_mii_send(struct nge_softc *, uint32_t, int); -static int nge_mii_readreg(struct nge_softc *, struct nge_mii_frame *); -static int nge_mii_writereg(struct nge_softc *, struct nge_mii_frame *); - static int nge_miibus_readreg(device_t, int, int); static int nge_miibus_writereg(device_t, int, int, int); static void nge_miibus_statchg(device_t); @@ -200,6 +196,24 @@ static void nge_sysctl_node(struct nge_softc *); static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int); static int sysctl_hw_nge_int_holdoff(SYSCTL_HANDLER_ARGS); +/* + * MII bit-bang glue + */ +static uint32_t nge_mii_bitbang_read(device_t); +static void nge_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops nge_mii_bitbang_ops = { + nge_mii_bitbang_read, + nge_mii_bitbang_write, + { + NGE_MEAR_MII_DATA, /* MII_BIT_MDO */ + NGE_MEAR_MII_DATA, /* MII_BIT_MDI */ + NGE_MEAR_MII_CLK, /* MII_BIT_MDC */ + NGE_MEAR_MII_DIR, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + static device_method_t nge_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nge_probe), @@ -366,180 +380,42 @@ nge_read_eeprom(struct nge_softc *sc, caddr_t dest } /* - * 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 -nge_mii_sync(struct nge_softc *sc) +static uint32_t +nge_mii_bitbang_read(device_t dev) { - int i; + struct nge_softc *sc; + uint32_t val; - SIO_SET(NGE_MEAR_MII_DIR|NGE_MEAR_MII_DATA); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - SIO_SET(NGE_MEAR_MII_CLK); - DELAY(1); - SIO_CLR(NGE_MEAR_MII_CLK); - DELAY(1); - } + val = CSR_READ_4(sc, NGE_MEAR); + CSR_BARRIER_4(sc, NGE_MEAR, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + + return (val); } /* - * Clock a series of bits through the MII. + * Write the MII serial port for the MII bit-bang module. */ static void -nge_mii_send(struct nge_softc *sc, uint32_t bits, int cnt) +nge_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct nge_softc *sc; - SIO_CLR(NGE_MEAR_MII_CLK); + sc = device_get_softc(dev); - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { - SIO_SET(NGE_MEAR_MII_DATA); - } else { - SIO_CLR(NGE_MEAR_MII_DATA); - } - DELAY(1); - SIO_CLR(NGE_MEAR_MII_CLK); - DELAY(1); - SIO_SET(NGE_MEAR_MII_CLK); - } + CSR_WRITE_4(sc, NGE_MEAR, val); + CSR_BARRIER_4(sc, NGE_MEAR, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } -/* - * Read an PHY register through the MII. - */ static int -nge_mii_readreg(struct nge_softc *sc, struct nge_mii_frame *frame) -{ - int i, ack; - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = NGE_MII_STARTDELIM; - frame->mii_opcode = NGE_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - CSR_WRITE_4(sc, NGE_MEAR, 0); - - /* - * Turn on data xmit. - */ - SIO_SET(NGE_MEAR_MII_DIR); - - nge_mii_sync(sc); - - /* - * Send command/address info. - */ - nge_mii_send(sc, frame->mii_stdelim, 2); - nge_mii_send(sc, frame->mii_opcode, 2); - nge_mii_send(sc, frame->mii_phyaddr, 5); - nge_mii_send(sc, frame->mii_regaddr, 5); - - /* Idle bit */ - SIO_CLR((NGE_MEAR_MII_CLK|NGE_MEAR_MII_DATA)); - DELAY(1); - SIO_SET(NGE_MEAR_MII_CLK); - DELAY(1); - - /* Turn off xmit. */ - SIO_CLR(NGE_MEAR_MII_DIR); - /* Check for ack */ - SIO_CLR(NGE_MEAR_MII_CLK); - DELAY(1); - ack = CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_MII_DATA; - SIO_SET(NGE_MEAR_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(NGE_MEAR_MII_CLK); - DELAY(1); - SIO_SET(NGE_MEAR_MII_CLK); - DELAY(1); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - SIO_CLR(NGE_MEAR_MII_CLK); - DELAY(1); - if (!ack) { - if (CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_MII_DATA) - frame->mii_data |= i; - DELAY(1); - } - SIO_SET(NGE_MEAR_MII_CLK); - DELAY(1); - } - -fail: - - SIO_CLR(NGE_MEAR_MII_CLK); - DELAY(1); - SIO_SET(NGE_MEAR_MII_CLK); - DELAY(1); - - if (ack) - return (1); - return (0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -nge_mii_writereg(struct nge_softc *sc, struct nge_mii_frame *frame) -{ - - /* - * Set up frame for TX. - */ - - frame->mii_stdelim = NGE_MII_STARTDELIM; - frame->mii_opcode = NGE_MII_WRITEOP; - frame->mii_turnaround = NGE_MII_TURNAROUND; - - /* - * Turn on data output. - */ - SIO_SET(NGE_MEAR_MII_DIR); - - nge_mii_sync(sc); - - nge_mii_send(sc, frame->mii_stdelim, 2); - nge_mii_send(sc, frame->mii_opcode, 2); - nge_mii_send(sc, frame->mii_phyaddr, 5); - nge_mii_send(sc, frame->mii_regaddr, 5); - nge_mii_send(sc, frame->mii_turnaround, 2); - nge_mii_send(sc, frame->mii_data, 16); - - /* Idle bit. */ - SIO_SET(NGE_MEAR_MII_CLK); - DELAY(1); - SIO_CLR(NGE_MEAR_MII_CLK); - DELAY(1); - - /* - * Turn off xmit. - */ - SIO_CLR(NGE_MEAR_MII_DIR); - - return (0); -} - -static int nge_miibus_readreg(device_t dev, int phy, int reg) { struct nge_softc *sc; - struct nge_mii_frame frame; int rv; sc = device_get_softc(dev); @@ -583,20 +459,13 @@ nge_miibus_readreg(device_t dev, int phy, int reg) return (CSR_READ_4(sc, reg)); } - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - nge_mii_readreg(sc, &frame); - - return (frame.mii_data); + return (mii_bitbang_readreg(dev, &nge_mii_bitbang_ops, phy, reg)); } static int nge_miibus_writereg(device_t dev, int phy, int reg, int data) { struct nge_softc *sc; - struct nge_mii_frame frame; sc = device_get_softc(dev); if ((sc->nge_flags & NGE_FLAG_TBI) != 0) { @@ -633,13 +502,8 @@ nge_miibus_writereg(device_t dev, int phy, int reg return (0); } - bzero((char *)&frame, sizeof(frame)); + mii_bitbang_writereg(dev, &nge_mii_bitbang_ops, phy, reg, data); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - nge_mii_writereg(sc, &frame); - return (0); } @@ -813,7 +677,7 @@ nge_rxfilter(struct nge_softc *sc) rxfilt = CSR_READ_4(sc, NGE_RXFILT_CTL); rxfilt &= ~NGE_RXFILTCTL_ENABLE; CSR_WRITE_4(sc, NGE_RXFILT_CTL, rxfilt); - CSR_BARRIER_WRITE_4(sc, NGE_RXFILT_CTL); + CSR_BARRIER_4(sc, NGE_RXFILT_CTL, BUS_SPACE_BARRIER_WRITE); rxfilt &= ~(NGE_RXFILTCTL_ALLMULTI | NGE_RXFILTCTL_ALLPHYS); rxfilt &= ~NGE_RXFILTCTL_BROAD; @@ -882,7 +746,7 @@ done: /* Turn the receive filter on. */ rxfilt |= NGE_RXFILTCTL_ENABLE; CSR_WRITE_4(sc, NGE_RXFILT_CTL, rxfilt); - CSR_BARRIER_WRITE_4(sc, NGE_RXFILT_CTL); + CSR_BARRIER_4(sc, NGE_RXFILT_CTL, BUS_SPACE_BARRIER_WRITE); } static void @@ -932,7 +796,7 @@ nge_reset(struct nge_softc *sc) static int nge_probe(device_t dev) { - struct nge_type *t; + const struct nge_type *t; t = nge_devs; @@ -2216,7 +2080,7 @@ nge_init_locked(struct nge_softc *sc) /* Disable Rx filter prior to programming Rx filter. */ CSR_WRITE_4(sc, NGE_RXFILT_CTL, 0); - CSR_BARRIER_WRITE_4(sc, NGE_RXFILT_CTL); + CSR_BARRIER_4(sc, NGE_RXFILT_CTL, BUS_SPACE_BARRIER_WRITE); mii = device_get_softc(sc->nge_miibus); @@ -2704,12 +2568,12 @@ nge_wol(struct nge_softc *sc) * (i.e. Silent Rx mode.) */ CSR_WRITE_4(sc, NGE_RX_LISTPTR_HI, 0); - CSR_BARRIER_WRITE_4(sc, NGE_RX_LISTPTR_HI); + CSR_BARRIER_4(sc, NGE_RX_LISTPTR_HI, BUS_SPACE_BARRIER_WRITE); CSR_WRITE_4(sc, NGE_RX_LISTPTR_LO, 0); - CSR_BARRIER_WRITE_4(sc, NGE_RX_LISTPTR_LO); + CSR_BARRIER_4(sc, NGE_RX_LISTPTR_LO, BUS_SPACE_BARRIER_WRITE); /* Enable Rx again. */ NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); - CSR_BARRIER_WRITE_4(sc, NGE_CSR); + CSR_BARRIER_4(sc, NGE_CSR, BUS_SPACE_BARRIER_WRITE); /* Configure WOL events. */ reg = 0; Index: dev/nge/if_ngereg.h =================================================================== --- dev/nge/if_ngereg.h (revision 226148) +++ dev/nge/if_ngereg.h (working copy) @@ -611,26 +611,9 @@ struct nge_ring_data { struct nge_type { uint16_t nge_vid; uint16_t nge_did; - char *nge_name; + const char *nge_name; }; -struct nge_mii_frame { - uint8_t mii_stdelim; - uint8_t mii_opcode; - uint8_t mii_phyaddr; - uint8_t mii_regaddr; - uint8_t mii_turnaround; - uint16_t mii_data; -}; - -/* - * MII constants - */ -#define NGE_MII_STARTDELIM 0x01 -#define NGE_MII_READOP 0x02 -#define NGE_MII_WRITEOP 0x01 -#define NGE_MII_TURNAROUND 0x02 - #define NGE_JUMBO_FRAMELEN 9022 #define NGE_JUMBO_MTU \ (NGE_JUMBO_FRAMELEN - sizeof(struct ether_vlan_header) - ETHER_CRC_LEN) @@ -691,9 +674,10 @@ struct nge_softc { */ #define CSR_WRITE_4(sc, reg, val) \ bus_write_4((sc)->nge_res, reg, val) -#define CSR_BARRIER_WRITE_4(sc, reg) \ - bus_barrier((sc)->nge_res, reg, 4, BUS_SPACE_BARRIER_WRITE) +#define CSR_BARRIER_4(sc, reg, flags) \ + bus_barrier((sc)->nge_res, reg, 4, flags) + #define CSR_READ_4(sc, reg) \ bus_read_4((sc)->nge_res, reg) Index: dev/sis/if_sis.c =================================================================== --- dev/sis/if_sis.c (revision 226148) +++ dev/sis/if_sis.c (working copy) @@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -119,10 +120,13 @@ MODULE_DEPEND(sis, miibus, 1, 1, 1); #define CSR_READ_2(sc, reg) bus_read_2(sc->sis_res[0], reg) +#define CSR_BARRIER(sc, reg, length, flags) \ + bus_barrier(sc->sis_res[0], reg, length, flags) + /* * Various supported device vendors/types and their names. */ -static struct sis_type sis_devs[] = { +static const struct sis_type const sis_devs[] = { { SIS_VENDORID, SIS_DEVICEID_900, "SiS 900 10/100BaseTX" }, { SIS_VENDORID, SIS_DEVICEID_7016, "SiS 7016 10/100BaseTX" }, { NS_VENDORID, NS_DEVICEID_DP83815, "NatSemi DP8381[56] 10/100BaseTX" }, @@ -145,6 +149,8 @@ static void sis_init(void *); static void sis_initl(struct sis_softc *); static void sis_intr(void *); static int sis_ioctl(struct ifnet *, u_long, caddr_t); +static uint32_t sis_mii_bitbang_read(device_t); +static void sis_mii_bitbang_write(device_t, uint32_t); static int sis_newbuf(struct sis_softc *, struct sis_rxdesc *); static int sis_resume(device_t); static int sis_rxeof(struct sis_softc *); @@ -159,6 +165,20 @@ static void sis_add_sysctls(struct sis_softc *); static void sis_watchdog(struct sis_softc *); static void sis_wol(struct sis_softc *); +/* + * MII bit-bang glue + */ +static const struct mii_bitbang_ops sis_mii_bitbang_ops = { + sis_mii_bitbang_read, + sis_mii_bitbang_write, + { + SIS_MII_DATA, /* MII_BIT_MDO */ + SIS_MII_DATA, /* MII_BIT_MDI */ + SIS_MII_CLK, /* MII_BIT_MDC */ + SIS_MII_DIR, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; static struct resource_spec sis_res_spec[] = { #ifdef SIS_USEIOSPACE @@ -412,179 +432,41 @@ sis_read_mac(struct sis_softc *sc, device_t dev, c #endif /* - * 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 -sis_mii_sync(struct sis_softc *sc) +static uint32_t +sis_mii_bitbang_read(device_t dev) { - int i; + struct sis_softc *sc; + uint32_t val; - SIO_SET(SIS_MII_DIR|SIS_MII_DATA); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - SIO_SET(SIS_MII_CLK); - DELAY(1); - SIO_CLR(SIS_MII_CLK); - DELAY(1); - } + val = CSR_READ_4(sc, SIS_EECTL); + CSR_BARRIER(sc, SIS_EECTL, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + return (val); } /* - * Clock a series of bits through the MII. + * Write the MII serial port for the MII bit-bang module. */ static void -sis_mii_send(struct sis_softc *sc, uint32_t bits, int cnt) +sis_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct sis_softc *sc; - SIO_CLR(SIS_MII_CLK); + sc = device_get_softc(dev); - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { - SIO_SET(SIS_MII_DATA); - } else { - SIO_CLR(SIS_MII_DATA); - } - DELAY(1); - SIO_CLR(SIS_MII_CLK); - DELAY(1); - SIO_SET(SIS_MII_CLK); - } + CSR_WRITE_4(sc, SIS_EECTL, val); + CSR_BARRIER(sc, SIS_EECTL, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } -/* - * Read an PHY register through the MII. - */ static int -sis_mii_readreg(struct sis_softc *sc, struct sis_mii_frame *frame) -{ - int i, ack; - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = SIS_MII_STARTDELIM; - frame->mii_opcode = SIS_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - /* - * Turn on data xmit. - */ - SIO_SET(SIS_MII_DIR); - - sis_mii_sync(sc); - - /* - * Send command/address info. - */ - sis_mii_send(sc, frame->mii_stdelim, 2); - sis_mii_send(sc, frame->mii_opcode, 2); - sis_mii_send(sc, frame->mii_phyaddr, 5); - sis_mii_send(sc, frame->mii_regaddr, 5); - - /* Idle bit */ - SIO_CLR((SIS_MII_CLK|SIS_MII_DATA)); - DELAY(1); - SIO_SET(SIS_MII_CLK); - DELAY(1); - - /* Turn off xmit. */ - SIO_CLR(SIS_MII_DIR); - - /* Check for ack */ - SIO_CLR(SIS_MII_CLK); - DELAY(1); - ack = CSR_READ_4(sc, SIS_EECTL) & SIS_MII_DATA; - SIO_SET(SIS_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(SIS_MII_CLK); - DELAY(1); - SIO_SET(SIS_MII_CLK); - DELAY(1); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - SIO_CLR(SIS_MII_CLK); - DELAY(1); - if (!ack) { - if (CSR_READ_4(sc, SIS_EECTL) & SIS_MII_DATA) - frame->mii_data |= i; - DELAY(1); - } - SIO_SET(SIS_MII_CLK); - DELAY(1); - } - -fail: - - SIO_CLR(SIS_MII_CLK); - DELAY(1); - SIO_SET(SIS_MII_CLK); - DELAY(1); - - if (ack) - return (1); - return (0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -sis_mii_writereg(struct sis_softc *sc, struct sis_mii_frame *frame) -{ - - /* - * Set up frame for TX. - */ - - frame->mii_stdelim = SIS_MII_STARTDELIM; - frame->mii_opcode = SIS_MII_WRITEOP; - frame->mii_turnaround = SIS_MII_TURNAROUND; - - /* - * Turn on data output. - */ - SIO_SET(SIS_MII_DIR); - - sis_mii_sync(sc); - - sis_mii_send(sc, frame->mii_stdelim, 2); - sis_mii_send(sc, frame->mii_opcode, 2); - sis_mii_send(sc, frame->mii_phyaddr, 5); - sis_mii_send(sc, frame->mii_regaddr, 5); - sis_mii_send(sc, frame->mii_turnaround, 2); - sis_mii_send(sc, frame->mii_data, 16); - - /* Idle bit. */ - SIO_SET(SIS_MII_CLK); - DELAY(1); - SIO_CLR(SIS_MII_CLK); - DELAY(1); - - /* - * Turn off xmit. - */ - SIO_CLR(SIS_MII_DIR); - - return (0); -} - -static int sis_miibus_readreg(device_t dev, int phy, int reg) { struct sis_softc *sc; - struct sis_mii_frame frame; sc = device_get_softc(dev); @@ -628,7 +510,8 @@ sis_miibus_readreg(device_t dev, int phy, int reg) } if (i == SIS_TIMEOUT) { - device_printf(sc->sis_dev, "PHY failed to come ready\n"); + device_printf(sc->sis_dev, + "PHY failed to come ready\n"); return (0); } @@ -638,22 +521,15 @@ sis_miibus_readreg(device_t dev, int phy, int reg) return (0); return (val); - } else { - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - sis_mii_readreg(sc, &frame); - - return (frame.mii_data); - } + } else + return (mii_bitbang_readreg(dev, &sis_mii_bitbang_ops, phy, + reg)); } static int sis_miibus_writereg(device_t dev, int phy, int reg, int data) { struct sis_softc *sc; - struct sis_mii_frame frame; sc = device_get_softc(dev); @@ -686,15 +562,11 @@ sis_miibus_writereg(device_t dev, int phy, int reg } if (i == SIS_TIMEOUT) - device_printf(sc->sis_dev, "PHY failed to come ready\n"); - } else { - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - sis_mii_writereg(sc, &frame); - } + device_printf(sc->sis_dev, + "PHY failed to come ready\n"); + } else + mii_bitbang_writereg(dev, &sis_mii_bitbang_ops, phy, reg, + data); return (0); } @@ -989,7 +861,7 @@ sis_reset(struct sis_softc *sc) static int sis_probe(device_t dev) { - struct sis_type *t; + const struct sis_type *t; t = sis_devs; Index: dev/sis/if_sisreg.h =================================================================== --- dev/sis/if_sisreg.h (revision 226148) +++ dev/sis/if_sisreg.h (working copy) @@ -433,26 +433,9 @@ struct sis_desc { struct sis_type { uint16_t sis_vid; uint16_t sis_did; - char *sis_name; + const char *sis_name; }; -struct sis_mii_frame { - uint8_t mii_stdelim; - uint8_t mii_opcode; - uint8_t mii_phyaddr; - uint8_t mii_regaddr; - uint8_t mii_turnaround; - uint16_t mii_data; -}; - -/* - * MII constants - */ -#define SIS_MII_STARTDELIM 0x01 -#define SIS_MII_READOP 0x02 -#define SIS_MII_WRITEOP 0x01 -#define SIS_MII_TURNAROUND 0x02 - #define SIS_TYPE_900 1 #define SIS_TYPE_7016 2 #define SIS_TYPE_83815 3 Index: dev/smc/if_smc.c =================================================================== --- dev/smc/if_smc.c (revision 226148) +++ dev/smc/if_smc.c (working copy) @@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #define SMC_LOCK(sc) mtx_lock(&(sc)->smc_mtx) @@ -123,11 +124,33 @@ static timeout_t smc_watchdog; static poll_handler_t smc_poll; #endif +/* + * MII bit-bang glue + */ +static uint32_t smc_mii_bitbang_read(device_t); +static void smc_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops smc_mii_bitbang_ops = { + smc_mii_bitbang_read, + smc_mii_bitbang_write, + { + MGMT_MDO, /* MII_BIT_MDO */ + MGMT_MDI, /* MII_BIT_MDI */ + MGMT_MCLK, /* MII_BIT_MDC */ + MGMT_MDOE, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + static __inline void smc_select_bank(struct smc_softc *sc, uint16_t bank) { + bus_barrier(sc->smc_reg, BSR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); bus_write_2(sc->smc_reg, BSR, bank & BSR_BANK_MASK); + bus_barrier(sc->smc_reg, BSR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } /* Never call this when not in bank 2. */ @@ -143,35 +166,35 @@ smc_mmu_wait(struct smc_softc *sc) } static __inline uint8_t -smc_read_1(struct smc_softc *sc, bus_addr_t offset) +smc_read_1(struct smc_softc *sc, bus_size_t offset) { return (bus_read_1(sc->smc_reg, offset)); } static __inline void -smc_write_1(struct smc_softc *sc, bus_addr_t offset, uint8_t val) +smc_write_1(struct smc_softc *sc, bus_size_t offset, uint8_t val) { bus_write_1(sc->smc_reg, offset, val); } static __inline uint16_t -smc_read_2(struct smc_softc *sc, bus_addr_t offset) +smc_read_2(struct smc_softc *sc, bus_size_t offset) { return (bus_read_2(sc->smc_reg, offset)); } static __inline void -smc_write_2(struct smc_softc *sc, bus_addr_t offset, uint16_t val) +smc_write_2(struct smc_softc *sc, bus_size_t offset, uint16_t val) { bus_write_2(sc->smc_reg, offset, val); } static __inline void -smc_read_multi_2(struct smc_softc *sc, bus_addr_t offset, uint16_t *datap, +smc_read_multi_2(struct smc_softc *sc, bus_size_t offset, uint16_t *datap, bus_size_t count) { @@ -179,13 +202,21 @@ static __inline void } static __inline void -smc_write_multi_2(struct smc_softc *sc, bus_addr_t offset, uint16_t *datap, +smc_write_multi_2(struct smc_softc *sc, bus_size_t offset, uint16_t *datap, bus_size_t count) { bus_write_multi_2(sc->smc_reg, offset, datap, count); } +static __inline void +smc_barrier(struct smc_softc *sc, bus_size_t offset, bus_size_t length, + int flags) +{ + + bus_barrier(sc->smc_reg, offset, length, flags); +} + int smc_probe(device_t dev) { @@ -900,70 +931,43 @@ smc_task_intr(void *context, int pending) SMC_UNLOCK(sc); } -static u_int -smc_mii_readbits(struct smc_softc *sc, int nbits) +static uint32_t +smc_mii_bitbang_read(device_t dev) { - u_int mgmt, mask, val; + struct smc_softc *sc; + uint32_t val; + sc = device_get_softc(dev); + SMC_ASSERT_LOCKED(sc); KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3, - ("%s: smc_mii_readbits called with bank %d (!= 3)", + ("%s: smc_mii_bitbang_read called with bank %d (!= 3)", device_get_nameunit(sc->smc_dev), smc_read_2(sc, BSR) & BSR_BANK_MASK)); - /* - * Set up the MGMT (aka MII) register. - */ - mgmt = smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO); - smc_write_2(sc, MGMT, mgmt); + val = smc_read_2(sc, MGMT); + smc_barrier(sc, MGMT, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - /* - * Read the bits in. - */ - for (mask = 1 << (nbits - 1), val = 0; mask; mask >>= 1) { - if (smc_read_2(sc, MGMT) & MGMT_MDI) - val |= mask; - - smc_write_2(sc, MGMT, mgmt); - DELAY(1); - smc_write_2(sc, MGMT, mgmt | MGMT_MCLK); - DELAY(1); - } - return (val); } static void -smc_mii_writebits(struct smc_softc *sc, u_int val, int nbits) +smc_mii_bitbang_write(device_t dev, uint32_t val) { - u_int mgmt, mask; + struct smc_softc *sc; + sc = device_get_softc(dev); + SMC_ASSERT_LOCKED(sc); KASSERT((smc_read_2(sc, BSR) & BSR_BANK_MASK) == 3, - ("%s: smc_mii_writebits called with bank %d (!= 3)", + ("%s: smc_mii_bitbang_write called with bank %d (!= 3)", device_get_nameunit(sc->smc_dev), smc_read_2(sc, BSR) & BSR_BANK_MASK)); - /* - * Set up the MGMT (aka MII) register). - */ - mgmt = smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO); - mgmt |= MGMT_MDOE; - - /* - * Push the bits out. - */ - for (mask = 1 << (nbits - 1); mask; mask >>= 1) { - if (val & mask) - mgmt |= MGMT_MDO; - else - mgmt &= ~MGMT_MDO; - - smc_write_2(sc, MGMT, mgmt); - DELAY(1); - smc_write_2(sc, MGMT, mgmt | MGMT_MCLK); - DELAY(1); - } + smc_write_2(sc, MGMT, val); + smc_barrier(sc, MGMT, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } int @@ -978,27 +982,8 @@ smc_miibus_readreg(device_t dev, int phy, int reg) smc_select_bank(sc, 3); - /* - * Send out the idle pattern. - */ - smc_mii_writebits(sc, 0xffffffff, 32); + val = mii_bitbang_readreg(dev, &smc_mii_bitbang_ops, phy, reg); - /* - * Start code + read opcode + phy address + phy register - */ - smc_mii_writebits(sc, 6 << 10 | phy << 5 | reg, 14); - - /* - * Turnaround + data - */ - val = smc_mii_readbits(sc, 18); - - /* - * Reset the MDIO interface. - */ - smc_write_2(sc, MGMT, - smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO)); - SMC_UNLOCK(sc); return (val); } @@ -1014,24 +999,8 @@ smc_miibus_writereg(device_t dev, int phy, int reg smc_select_bank(sc, 3); - /* - * Send idle pattern. - */ - smc_mii_writebits(sc, 0xffffffff, 32); + mii_bitbang_writereg(dev, &smc_mii_bitbang_ops, phy, reg, data); - /* - * Start code + write opcode + phy address + phy register + turnaround - * + data. - */ - smc_mii_writebits(sc, 5 << 28 | phy << 23 | reg << 18 | 2 << 16 | data, - 32); - - /* - * Reset MDIO interface. - */ - smc_write_2(sc, MGMT, - smc_read_2(sc, MGMT) & ~(MGMT_MCLK | MGMT_MDOE | MGMT_MDO)); - SMC_UNLOCK(sc); return (0); } Index: dev/ste/if_ste.c =================================================================== --- dev/ste/if_ste.c (revision 226148) +++ dev/ste/if_ste.c (working copy) @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -84,7 +85,7 @@ MODULE_DEPEND(ste, miibus, 1, 1, 1); /* * Various supported device vendors/types and their names. */ -static struct ste_type ste_devs[] = { +static const struct ste_type const ste_devs[] = { { ST_VENDORID, ST_DEVICEID_ST201_1, "Sundance ST201 10/100BaseTX" }, { ST_VENDORID, ST_DEVICEID_ST201_2, "Sundance ST201 10/100BaseTX" }, { DL_VENDORID, DL_DEVICEID_DL10050, "D-Link DL10050 10/100BaseTX" }, @@ -112,10 +113,8 @@ static int ste_init_rx_list(struct ste_softc *); static void ste_init_tx_list(struct ste_softc *); static void ste_intr(void *); static int ste_ioctl(struct ifnet *, u_long, caddr_t); -static int ste_mii_readreg(struct ste_softc *, struct ste_mii_frame *); -static void ste_mii_send(struct ste_softc *, uint32_t, int); -static void ste_mii_sync(struct ste_softc *); -static int ste_mii_writereg(struct ste_softc *, struct ste_mii_frame *); +static uint32_t ste_mii_bitbang_read(device_t); +static void ste_mii_bitbang_write(device_t, uint32_t); static int ste_miibus_readreg(device_t, int, int); static void ste_miibus_statchg(device_t); static int ste_miibus_writereg(device_t, int, int, int); @@ -138,6 +137,21 @@ static void ste_txeof(struct ste_softc *); static void ste_wait(struct ste_softc *); static void ste_watchdog(struct ste_softc *); +/* + * MII bit-bang glue + */ +static const struct mii_bitbang_ops ste_mii_bitbang_ops = { + ste_mii_bitbang_read, + ste_mii_bitbang_write, + { + STE_PHYCTL_MDATA, /* MII_BIT_MDO */ + STE_PHYCTL_MDATA, /* MII_BIT_MDI */ + STE_PHYCTL_MCLK, /* MII_BIT_MDC */ + STE_PHYCTL_MDIR, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + static device_method_t ste_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ste_probe), @@ -188,211 +202,52 @@ DRIVER_MODULE(miibus, ste, miibus_driver, miibus_d #define STE_CLRBIT1(sc, reg, x) \ CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) & ~(x)) - -#define MII_SET(x) STE_SETBIT1(sc, STE_PHYCTL, x) -#define MII_CLR(x) STE_CLRBIT1(sc, STE_PHYCTL, x) - /* - * 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 -ste_mii_sync(struct ste_softc *sc) +static uint32_t +ste_mii_bitbang_read(device_t dev) { - int i; + struct ste_softc *sc; + uint32_t val; - MII_SET(STE_PHYCTL_MDIR|STE_PHYCTL_MDATA); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - MII_SET(STE_PHYCTL_MCLK); - DELAY(1); - MII_CLR(STE_PHYCTL_MCLK); - DELAY(1); - } + val = CSR_READ_1(sc, STE_PHYCTL); + CSR_BARRIER(sc, STE_PHYCTL, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + + return (val); } /* - * Clock a series of bits through the MII. + * Write the MII serial port for the MII bit-bang module. */ static void -ste_mii_send(struct ste_softc *sc, uint32_t bits, int cnt) +ste_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct ste_softc *sc; - MII_CLR(STE_PHYCTL_MCLK); + sc = device_get_softc(dev); - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { - MII_SET(STE_PHYCTL_MDATA); - } else { - MII_CLR(STE_PHYCTL_MDATA); - } - DELAY(1); - MII_CLR(STE_PHYCTL_MCLK); - DELAY(1); - MII_SET(STE_PHYCTL_MCLK); - } + CSR_WRITE_1(sc, STE_PHYCTL, val); + CSR_BARRIER(sc, STE_PHYCTL, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } -/* - * Read an PHY register through the MII. - */ static int -ste_mii_readreg(struct ste_softc *sc, struct ste_mii_frame *frame) -{ - int i, ack; - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = STE_MII_STARTDELIM; - frame->mii_opcode = STE_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - CSR_WRITE_2(sc, STE_PHYCTL, 0); - /* - * Turn on data xmit. - */ - MII_SET(STE_PHYCTL_MDIR); - - ste_mii_sync(sc); - - /* - * Send command/address info. - */ - ste_mii_send(sc, frame->mii_stdelim, 2); - ste_mii_send(sc, frame->mii_opcode, 2); - ste_mii_send(sc, frame->mii_phyaddr, 5); - ste_mii_send(sc, frame->mii_regaddr, 5); - - /* Turn off xmit. */ - MII_CLR(STE_PHYCTL_MDIR); - - /* Idle bit */ - MII_CLR((STE_PHYCTL_MCLK|STE_PHYCTL_MDATA)); - DELAY(1); - MII_SET(STE_PHYCTL_MCLK); - DELAY(1); - - /* Check for ack */ - MII_CLR(STE_PHYCTL_MCLK); - DELAY(1); - ack = CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA; - MII_SET(STE_PHYCTL_MCLK); - 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++) { - MII_CLR(STE_PHYCTL_MCLK); - DELAY(1); - MII_SET(STE_PHYCTL_MCLK); - DELAY(1); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - MII_CLR(STE_PHYCTL_MCLK); - DELAY(1); - if (!ack) { - if (CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA) - frame->mii_data |= i; - DELAY(1); - } - MII_SET(STE_PHYCTL_MCLK); - DELAY(1); - } - -fail: - - MII_CLR(STE_PHYCTL_MCLK); - DELAY(1); - MII_SET(STE_PHYCTL_MCLK); - DELAY(1); - - if (ack) - return (1); - return (0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -ste_mii_writereg(struct ste_softc *sc, struct ste_mii_frame *frame) -{ - - /* - * Set up frame for TX. - */ - - frame->mii_stdelim = STE_MII_STARTDELIM; - frame->mii_opcode = STE_MII_WRITEOP; - frame->mii_turnaround = STE_MII_TURNAROUND; - - /* - * Turn on data output. - */ - MII_SET(STE_PHYCTL_MDIR); - - ste_mii_sync(sc); - - ste_mii_send(sc, frame->mii_stdelim, 2); - ste_mii_send(sc, frame->mii_opcode, 2); - ste_mii_send(sc, frame->mii_phyaddr, 5); - ste_mii_send(sc, frame->mii_regaddr, 5); - ste_mii_send(sc, frame->mii_turnaround, 2); - ste_mii_send(sc, frame->mii_data, 16); - - /* Idle bit. */ - MII_SET(STE_PHYCTL_MCLK); - DELAY(1); - MII_CLR(STE_PHYCTL_MCLK); - DELAY(1); - - /* - * Turn off xmit. - */ - MII_CLR(STE_PHYCTL_MDIR); - - return (0); -} - -static int ste_miibus_readreg(device_t dev, int phy, int reg) { - struct ste_softc *sc; - struct ste_mii_frame frame; - sc = device_get_softc(dev); - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - ste_mii_readreg(sc, &frame); - - return (frame.mii_data); + return (mii_bitbang_readreg(dev, &ste_mii_bitbang_ops, phy, reg)); } static int ste_miibus_writereg(device_t dev, int phy, int reg, int data) { - struct ste_softc *sc; - struct ste_mii_frame frame; - sc = device_get_softc(dev); - bzero((char *)&frame, sizeof(frame)); + mii_bitbang_writereg(dev, &ste_mii_bitbang_ops, phy, reg, data); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - - ste_mii_writereg(sc, &frame); - return (0); } @@ -1027,7 +882,7 @@ ste_stats_update(struct ste_softc *sc) static int ste_probe(device_t dev) { - struct ste_type *t; + const struct ste_type *t; t = ste_devs; Index: dev/ste/if_stereg.h =================================================================== --- dev/ste/if_stereg.h (revision 226148) +++ dev/ste/if_stereg.h (working copy) @@ -492,6 +492,9 @@ struct ste_desc_onefrag { #define CSR_READ_1(sc, reg) \ bus_read_1((sc)->ste_res, reg) +#define CSR_BARRIER(sc, reg, length, flags) \ + bus_barrier((sc)->ste_res, reg, length, flags) + #define STE_DESC_ALIGN 8 #define STE_RX_LIST_CNT 128 #define STE_TX_LIST_CNT 128 @@ -519,7 +522,7 @@ struct ste_desc_onefrag { struct ste_type { uint16_t ste_vid; uint16_t ste_did; - char *ste_name; + const char *ste_name; }; struct ste_list_data { @@ -590,20 +593,3 @@ struct ste_softc { #define STE_LOCK(_sc) mtx_lock(&(_sc)->ste_mtx) #define STE_UNLOCK(_sc) mtx_unlock(&(_sc)->ste_mtx) #define STE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->ste_mtx, MA_OWNED) - -struct ste_mii_frame { - uint8_t mii_stdelim; - uint8_t mii_opcode; - uint8_t mii_phyaddr; - uint8_t mii_regaddr; - uint8_t mii_turnaround; - uint16_t mii_data; -}; - -/* - * MII constants - */ -#define STE_MII_STARTDELIM 0x01 -#define STE_MII_READOP 0x02 -#define STE_MII_WRITEOP 0x01 -#define STE_MII_TURNAROUND 0x02 Index: dev/stge/if_stge.c =================================================================== --- dev/stge/if_stge.c (revision 226173) +++ dev/stge/if_stge.c (working copy) @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -86,11 +87,11 @@ MODULE_DEPEND(stge, miibus, 1, 1, 1); /* * Devices supported by this driver. */ -static struct stge_product { +static const struct stge_product { uint16_t stge_vendorid; uint16_t stge_deviceid; const char *stge_name; -} stge_products[] = { +} const stge_products[] = { { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST1023, "Sundance ST-1023 Gigabit Ethernet" }, @@ -160,10 +161,6 @@ static int stge_newbuf(struct stge_softc *, int); static __inline struct mbuf *stge_fixup_rx(struct stge_softc *, struct mbuf *); #endif -static void stge_mii_sync(struct stge_softc *); -static void stge_mii_send(struct stge_softc *, uint32_t, int); -static int stge_mii_readreg(struct stge_softc *, struct stge_mii_frame *); -static int stge_mii_writereg(struct stge_softc *, struct stge_mii_frame *); static int stge_miibus_readreg(device_t, int, int); static int stge_miibus_writereg(device_t, int, int, int); static void stge_miibus_statchg(device_t); @@ -185,6 +182,24 @@ static int sysctl_int_range(SYSCTL_HANDLER_ARGS, i static int sysctl_hw_stge_rxint_nframe(SYSCTL_HANDLER_ARGS); static int sysctl_hw_stge_rxint_dmawait(SYSCTL_HANDLER_ARGS); +/* + * MII bit-bang glue + */ +static uint32_t stge_mii_bitbang_read(device_t); +static void stge_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops stge_mii_bitbang_ops = { + stge_mii_bitbang_read, + stge_mii_bitbang_write, + { + PC_MgmtData, /* MII_BIT_MDO */ + PC_MgmtData, /* MII_BIT_MDI */ + PC_MgmtClk, /* MII_BIT_MDC */ + PC_MgmtDir, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + static device_method_t stge_methods[] = { /* Device interface */ DEVMETHOD(device_probe, stge_probe), @@ -225,179 +240,43 @@ static struct resource_spec stge_res_spec_mem[] = { -1, 0, 0 } }; -#define MII_SET(x) \ - CSR_WRITE_1(sc, STGE_PhyCtrl, CSR_READ_1(sc, STGE_PhyCtrl) | (x)) -#define MII_CLR(x) \ - CSR_WRITE_1(sc, STGE_PhyCtrl, CSR_READ_1(sc, STGE_PhyCtrl) & ~(x)) - /* - * Sync the PHYs by setting data bit and strobing the clock 32 times. + * stge_mii_bitbang_read: [mii bit-bang interface function] + * + * Read the MII serial port for the MII bit-bang module. */ -static void -stge_mii_sync(struct stge_softc *sc) +static uint32_t +stge_mii_bitbang_read(device_t dev) { - int i; + struct stge_softc *sc; + uint32_t val; - MII_SET(PC_MgmtDir | PC_MgmtData); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - MII_SET(PC_MgmtClk); - DELAY(1); - MII_CLR(PC_MgmtClk); - DELAY(1); - } + val = CSR_READ_1(sc, STGE_PhyCtrl); + CSR_BARRIER(sc, STGE_PhyCtrl, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + return (val); } /* - * Clock a series of bits through the MII. + * stge_mii_bitbang_write: [mii big-bang interface function] + * + * Write the MII serial port for the MII bit-bang module. */ static void -stge_mii_send(struct stge_softc *sc, uint32_t bits, int cnt) +stge_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct stge_softc *sc; - MII_CLR(PC_MgmtClk); + sc = device_get_softc(dev); - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) - MII_SET(PC_MgmtData); - else - MII_CLR(PC_MgmtData); - DELAY(1); - MII_CLR(PC_MgmtClk); - DELAY(1); - MII_SET(PC_MgmtClk); - } + CSR_WRITE_1(sc, STGE_PhyCtrl, val); + CSR_BARRIER(sc, STGE_PhyCtrl, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } /* - * Read an PHY register through the MII. - */ -static int -stge_mii_readreg(struct stge_softc *sc, struct stge_mii_frame *frame) -{ - int i, ack; - - /* - * Set up frame for RX. - */ - frame->mii_stdelim = STGE_MII_STARTDELIM; - frame->mii_opcode = STGE_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - CSR_WRITE_1(sc, STGE_PhyCtrl, 0 | sc->sc_PhyCtrl); - /* - * Turn on data xmit. - */ - MII_SET(PC_MgmtDir); - - stge_mii_sync(sc); - - /* - * Send command/address info. - */ - stge_mii_send(sc, frame->mii_stdelim, 2); - stge_mii_send(sc, frame->mii_opcode, 2); - stge_mii_send(sc, frame->mii_phyaddr, 5); - stge_mii_send(sc, frame->mii_regaddr, 5); - - /* Turn off xmit. */ - MII_CLR(PC_MgmtDir); - - /* Idle bit */ - MII_CLR((PC_MgmtClk | PC_MgmtData)); - DELAY(1); - MII_SET(PC_MgmtClk); - DELAY(1); - - /* Check for ack */ - MII_CLR(PC_MgmtClk); - DELAY(1); - ack = CSR_READ_1(sc, STGE_PhyCtrl) & PC_MgmtData; - MII_SET(PC_MgmtClk); - 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++) { - MII_CLR(PC_MgmtClk); - DELAY(1); - MII_SET(PC_MgmtClk); - DELAY(1); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - MII_CLR(PC_MgmtClk); - DELAY(1); - if (!ack) { - if (CSR_READ_1(sc, STGE_PhyCtrl) & PC_MgmtData) - frame->mii_data |= i; - DELAY(1); - } - MII_SET(PC_MgmtClk); - DELAY(1); - } - -fail: - MII_CLR(PC_MgmtClk); - DELAY(1); - MII_SET(PC_MgmtClk); - DELAY(1); - - if (ack) - return(1); - return(0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -stge_mii_writereg(struct stge_softc *sc, struct stge_mii_frame *frame) -{ - - /* - * Set up frame for TX. - */ - frame->mii_stdelim = STGE_MII_STARTDELIM; - frame->mii_opcode = STGE_MII_WRITEOP; - frame->mii_turnaround = STGE_MII_TURNAROUND; - - /* - * Turn on data output. - */ - MII_SET(PC_MgmtDir); - - stge_mii_sync(sc); - - stge_mii_send(sc, frame->mii_stdelim, 2); - stge_mii_send(sc, frame->mii_opcode, 2); - stge_mii_send(sc, frame->mii_phyaddr, 5); - stge_mii_send(sc, frame->mii_regaddr, 5); - stge_mii_send(sc, frame->mii_turnaround, 2); - stge_mii_send(sc, frame->mii_data, 16); - - /* Idle bit. */ - MII_SET(PC_MgmtClk); - DELAY(1); - MII_CLR(PC_MgmtClk); - DELAY(1); - - /* - * Turn off xmit. - */ - MII_CLR(PC_MgmtDir); - - return(0); -} - -/* * sc_miibus_readreg: [mii interface function] * * Read a PHY register on the MII of the TC9021. @@ -406,8 +285,7 @@ static int stge_miibus_readreg(device_t dev, int phy, int reg) { struct stge_softc *sc; - struct stge_mii_frame frame; - int error; + int error, val; sc = device_get_softc(dev); @@ -418,21 +296,11 @@ stge_miibus_readreg(device_t dev, int phy, int reg STGE_MII_UNLOCK(sc); return (error); } - bzero(&frame, sizeof(frame)); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; STGE_MII_LOCK(sc); - error = stge_mii_readreg(sc, &frame); + val = mii_bitbang_readreg(dev, &stge_mii_bitbang_ops, phy, reg); STGE_MII_UNLOCK(sc); - - if (error != 0) { - /* Don't show errors for PHY probe request */ - if (reg != 1) - device_printf(sc->sc_dev, "phy read fail\n"); - return (0); - } - return (frame.mii_data); + return (val); } /* @@ -444,22 +312,12 @@ static int stge_miibus_writereg(device_t dev, int phy, int reg, int val) { struct stge_softc *sc; - struct stge_mii_frame frame; - int error; sc = device_get_softc(dev); - bzero(&frame, sizeof(frame)); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = val; - STGE_MII_LOCK(sc); - error = stge_mii_writereg(sc, &frame); + mii_bitbang_writereg(dev, &stge_mii_bitbang_ops, phy, reg, val); STGE_MII_UNLOCK(sc); - - if (error != 0) - device_printf(sc->sc_dev, "phy write fail\n"); return (0); } @@ -550,7 +408,7 @@ stge_read_eeprom(struct stge_softc *sc, int offset static int stge_probe(device_t dev) { - struct stge_product *sp; + const struct stge_product *sp; int i; uint16_t vendor, devid; Index: dev/stge/if_stgereg.h =================================================================== --- dev/stge/if_stgereg.h (revision 226173) +++ dev/stge/if_stgereg.h (working copy) @@ -99,6 +99,9 @@ #define CSR_READ_1(_sc, reg) \ bus_read_1((_sc)->sc_res[0], (reg)) +#define CSR_BARRIER(_sc, reg, length, flags) \ + bus_barrier((_sc)->sc_res[0], reg, length, flags) + /* * TC9021 buffer fragment descriptor. */ @@ -677,23 +680,6 @@ do { \ #define STGE_TIMEOUT 1000 -struct stge_mii_frame { - uint8_t mii_stdelim; - uint8_t mii_opcode; - uint8_t mii_phyaddr; - uint8_t mii_regaddr; - uint8_t mii_turnaround; - uint16_t mii_data; -}; - -/* - * MII constants - */ -#define STGE_MII_STARTDELIM 0x01 -#define STGE_MII_READOP 0x02 -#define STGE_MII_WRITEOP 0x01 -#define STGE_MII_TURNAROUND 0x02 - #define STGE_RESET_NONE 0x00 #define STGE_RESET_TX 0x01 #define STGE_RESET_RX 0x02 Index: dev/tl/if_tl.c =================================================================== --- dev/tl/if_tl.c (revision 226148) +++ dev/tl/if_tl.c (working copy) @@ -203,6 +203,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -228,7 +229,7 @@ MODULE_DEPEND(tl, miibus, 1, 1, 1); * Various supported device vendors/types and their names. */ -static struct tl_type tl_devs[] = { +static const struct tl_type const tl_devs[] = { { TI_VENDORID, TI_DEVICEID_THUNDERLAN, "Texas Instruments ThunderLAN" }, { COMPAQ_VENDORID, COMPAQ_DEVICEID_NETEL_10, @@ -290,10 +291,6 @@ static u_int8_t tl_eeprom_putbyte(struct tl_softc static u_int8_t tl_eeprom_getbyte(struct tl_softc *, int, u_int8_t *); static int tl_read_eeprom(struct tl_softc *, caddr_t, int, int); -static void tl_mii_sync(struct tl_softc *); -static void tl_mii_send(struct tl_softc *, u_int32_t, int); -static int tl_mii_readreg(struct tl_softc *, struct tl_mii_frame *); -static int tl_mii_writereg(struct tl_softc *, struct tl_mii_frame *); static int tl_miibus_readreg(device_t, int, int); static int tl_miibus_writereg(device_t, int, int, int); static void tl_miibus_statchg(device_t); @@ -318,6 +315,24 @@ static void tl_dio_clrbit(struct tl_softc *, int, static void tl_dio_setbit16(struct tl_softc *, int, int); static void tl_dio_clrbit16(struct tl_softc *, int, int); +/* + * MII bit-bang glue + */ +static uint32_t tl_mii_bitbang_read(device_t); +static void tl_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops tl_mii_bitbang_ops = { + tl_mii_bitbang_read, + tl_mii_bitbang_write, + { + TL_SIO_MDATA, /* MII_BIT_MDO */ + TL_SIO_MDATA, /* MII_BIT_MDI */ + TL_SIO_MCLK, /* MII_BIT_MDC */ + TL_SIO_MTXEN, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + #ifdef TL_USEIOSPACE #define TL_RES SYS_RES_IOPORT #define TL_RID TL_PCI_LOIO @@ -360,7 +375,12 @@ static u_int8_t tl_dio_read8(sc, reg) struct tl_softc *sc; int reg; { + + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); return(CSR_READ_1(sc, TL_DIO_DATA + (reg & 3))); } @@ -368,7 +388,12 @@ static u_int16_t tl_dio_read16(sc, reg) struct tl_softc *sc; int reg; { + + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); return(CSR_READ_2(sc, TL_DIO_DATA + (reg & 3))); } @@ -376,7 +401,12 @@ static u_int32_t tl_dio_read32(sc, reg) struct tl_softc *sc; int reg; { + + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); return(CSR_READ_4(sc, TL_DIO_DATA + (reg & 3))); } @@ -385,9 +415,13 @@ static void tl_dio_write8(sc, reg, val) int reg; int val; { + + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_1(sc, TL_DIO_DATA + (reg & 3), val); - return; } static void tl_dio_write16(sc, reg, val) @@ -395,9 +429,13 @@ static void tl_dio_write16(sc, reg, val) int reg; int val; { + + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_DATA + (reg & 3), val); - return; } static void tl_dio_write32(sc, reg, val) @@ -405,9 +443,13 @@ static void tl_dio_write32(sc, reg, val) int reg; int val; { + + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_4(sc, TL_DIO_DATA + (reg & 3), val); - return; } static void @@ -418,12 +460,16 @@ tl_dio_setbit(sc, reg, bit) { u_int8_t f; + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); f = CSR_READ_1(sc, TL_DIO_DATA + (reg & 3)); f |= bit; + CSR_BARRIER(sc, TL_DIO_DATA + (reg & 3), 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_1(sc, TL_DIO_DATA + (reg & 3), f); - - return; } static void @@ -434,12 +480,16 @@ tl_dio_clrbit(sc, reg, bit) { u_int8_t f; + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); f = CSR_READ_1(sc, TL_DIO_DATA + (reg & 3)); f &= ~bit; + CSR_BARRIER(sc, TL_DIO_DATA + (reg & 3), 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_1(sc, TL_DIO_DATA + (reg & 3), f); - - return; } static void tl_dio_setbit16(sc, reg, bit) @@ -449,12 +499,16 @@ static void tl_dio_setbit16(sc, reg, bit) { u_int16_t f; + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); f = CSR_READ_2(sc, TL_DIO_DATA + (reg & 3)); f |= bit; + CSR_BARRIER(sc, TL_DIO_DATA + (reg & 3), 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_DATA + (reg & 3), f); - - return; } static void tl_dio_clrbit16(sc, reg, bit) @@ -464,12 +518,16 @@ static void tl_dio_clrbit16(sc, reg, bit) { u_int16_t f; + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_ADDR, reg); + CSR_BARRIER(sc, TL_DIO_ADDR, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); f = CSR_READ_2(sc, TL_DIO_DATA + (reg & 3)); f &= ~bit; + CSR_BARRIER(sc, TL_DIO_DATA + (reg & 3), 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); CSR_WRITE_2(sc, TL_DIO_DATA + (reg & 3), f); - - return; } /* @@ -608,61 +666,55 @@ tl_read_eeprom(sc, dest, off, cnt) return(err ? 1 : 0); } -static void -tl_mii_sync(sc) - struct tl_softc *sc; +#define TL_SIO_MII (TL_SIO_MCLK | TL_SIO_MDATA | TL_SIO_MTXEN) + +/* + * Read the MII serial port for the MII bit-bang module. + */ +static uint32_t +tl_mii_bitbang_read(device_t dev) { - register int i; + struct tl_softc *sc; + uint32_t val; - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MTXEN); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - } + val = tl_dio_read8(sc, TL_NETSIO) & TL_SIO_MII; + CSR_BARRIER(sc, TL_NETSIO, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); - return; + return (val); } +/* + * Write the MII serial port for the MII bit-bang module. + */ static void -tl_mii_send(sc, bits, cnt) - struct tl_softc *sc; - u_int32_t bits; - int cnt; +tl_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct tl_softc *sc; - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - if (bits & i) { - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MDATA); - } else { - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MDATA); - } - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - } + sc = device_get_softc(dev); + + val = (tl_dio_read8(sc, TL_NETSIO) & ~TL_SIO_MII) | val; + CSR_BARRIER(sc, TL_NETSIO, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + tl_dio_write8(sc, TL_NETSIO, val); + CSR_BARRIER(sc, TL_NETSIO, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } static int -tl_mii_readreg(sc, frame) - struct tl_softc *sc; - struct tl_mii_frame *frame; - +tl_miibus_readreg(dev, phy, reg) + device_t dev; + int phy, reg; { - int i, ack; - int minten = 0; + struct tl_softc *sc; + int minten, val; - tl_mii_sync(sc); + sc = device_get_softc(dev); /* - * Set up frame for RX. - */ - frame->mii_stdelim = TL_MII_STARTDELIM; - frame->mii_opcode = TL_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - /* * Turn off MII interrupt by forcing MINTEN low. */ minten = tl_dio_read8(sc, TL_NETSIO) & TL_SIO_MINTEN; @@ -670,90 +722,27 @@ static int tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MINTEN); } - /* - * Turn on data xmit. - */ - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MTXEN); + val = mii_bitbang_readreg(dev, &tl_mii_bitbang_ops, phy, reg); - /* - * Send command/address info. - */ - tl_mii_send(sc, frame->mii_stdelim, 2); - tl_mii_send(sc, frame->mii_opcode, 2); - tl_mii_send(sc, frame->mii_phyaddr, 5); - tl_mii_send(sc, frame->mii_regaddr, 5); - - /* - * Turn off xmit. - */ - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MTXEN); - - /* Idle bit */ - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - - /* Check for ack */ - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - ack = tl_dio_read8(sc, TL_NETSIO) & TL_SIO_MDATA; - - /* Complete the cycle */ - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - - /* - * Now try reading data bits. If the ack failed, we still - * need to clock through 16 cycles to keep the PHYs in sync. - */ - if (ack) { - for(i = 0; i < 16; i++) { - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - if (!ack) { - if (tl_dio_read8(sc, TL_NETSIO) & TL_SIO_MDATA) - frame->mii_data |= i; - } - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - } - -fail: - - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - - /* Reenable interrupts */ + /* Reenable interrupts. */ if (minten) { tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MINTEN); } - if (ack) - return(1); - return(0); + return (val); } static int -tl_mii_writereg(sc, frame) - struct tl_softc *sc; - struct tl_mii_frame *frame; - +tl_miibus_writereg(dev, phy, reg, data) + device_t dev; + int phy, reg, data; { + struct tl_softc *sc; int minten; - tl_mii_sync(sc); + sc = device_get_softc(dev); /* - * Set up frame for TX. - */ - - frame->mii_stdelim = TL_MII_STARTDELIM; - frame->mii_opcode = TL_MII_WRITEOP; - frame->mii_turnaround = TL_MII_TURNAROUND; - - /* * Turn off MII interrupt by forcing MINTEN low. */ minten = tl_dio_read8(sc, TL_NETSIO) & TL_SIO_MINTEN; @@ -761,71 +750,16 @@ static int tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MINTEN); } - /* - * Turn on data output. - */ - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MTXEN); + mii_bitbang_writereg(dev, &tl_mii_bitbang_ops, phy, reg, data); - tl_mii_send(sc, frame->mii_stdelim, 2); - tl_mii_send(sc, frame->mii_opcode, 2); - tl_mii_send(sc, frame->mii_phyaddr, 5); - tl_mii_send(sc, frame->mii_regaddr, 5); - tl_mii_send(sc, frame->mii_turnaround, 2); - tl_mii_send(sc, frame->mii_data, 16); - - tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MCLK); - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MCLK); - - /* - * Turn off xmit. - */ - tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MTXEN); - - /* Reenable interrupts */ - if (minten) + /* Reenable interrupts. */ + if (minten) { tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MINTEN); + } return(0); } -static int -tl_miibus_readreg(dev, phy, reg) - device_t dev; - int phy, reg; -{ - struct tl_softc *sc; - struct tl_mii_frame frame; - - sc = device_get_softc(dev); - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - tl_mii_readreg(sc, &frame); - - return(frame.mii_data); -} - -static int -tl_miibus_writereg(dev, phy, reg, data) - device_t dev; - int phy, reg, data; -{ - struct tl_softc *sc; - struct tl_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; - - tl_mii_writereg(sc, &frame); - - return(0); -} - static void tl_miibus_statchg(dev) device_t dev; @@ -841,8 +775,6 @@ tl_miibus_statchg(dev) } else { tl_dio_clrbit(sc, TL_NETCMD, TL_CMD_DUPLEX); } - - return; } /* @@ -865,8 +797,6 @@ tl_setmode(sc, media) tl_dio_clrbit(sc, TL_NETCMD, TL_CMD_DUPLEX); } } - - return; } /* @@ -909,8 +839,6 @@ tl_setfilt(sc, addr, slot) for (i = 0; i < ETHER_ADDR_LEN; i++) tl_dio_write8(sc, regaddr + i, *(addr + i)); - - return; } /* @@ -980,8 +908,6 @@ tl_setmulti(sc) tl_dio_write32(sc, TL_HASH1, hashes[0]); tl_dio_write32(sc, TL_HASH2, hashes[1]); - - return; } /* @@ -1000,7 +926,7 @@ tl_hardreset(dev) sc = device_get_softc(dev); - tl_mii_sync(sc); + mii_bitbang_sync(dev, &tl_mii_bitbang_ops); flags = BMCR_LOOP|BMCR_ISO|BMCR_PDOWN; @@ -1010,11 +936,10 @@ tl_hardreset(dev) tl_miibus_writereg(dev, 31, MII_BMCR, BMCR_ISO); DELAY(50000); tl_miibus_writereg(dev, 31, MII_BMCR, BMCR_LOOP|BMCR_ISO); - tl_mii_sync(sc); + mii_bitbang_sync(dev, &tl_mii_bitbang_ops); while(tl_miibus_readreg(dev, 31, MII_BMCR) & BMCR_RESET); DELAY(50000); - return; } static void @@ -1072,8 +997,6 @@ tl_softreset(sc, internal) /* Wait for things to settle down a little. */ DELAY(500); - - return; } /* @@ -1084,7 +1007,7 @@ static int tl_probe(dev) device_t dev; { - struct tl_type *t; + const struct tl_type *t; t = tl_devs; @@ -1105,7 +1028,7 @@ tl_attach(dev) device_t dev; { u_int16_t did, vid; - struct tl_type *t; + const struct tl_type *t; struct ifnet *ifp; struct tl_softc *sc; int error, flags, i, rid, unit; @@ -1415,9 +1338,9 @@ static int tl_list_rx_init(sc) struct tl_softc *sc; { - struct tl_chain_data *cd; - struct tl_list_data *ld; - int i; + struct tl_chain_data *cd; + struct tl_list_data *ld; + int i; cd = &sc->tl_cdata; ld = sc->tl_ldata; @@ -1783,8 +1706,6 @@ tl_intr(xsc) tl_start_locked(ifp); TL_UNLOCK(sc); - - return; } static void @@ -1843,8 +1764,6 @@ tl_stats_update(xsc) mii = device_get_softc(sc->tl_miibus); mii_tick(mii); } - - return; } /* @@ -2046,8 +1965,6 @@ tl_start_locked(ifp) * Set a timeout in case the chip goes out to lunch. */ sc->tl_timer = 5; - - return; } static void @@ -2143,8 +2060,6 @@ tl_init_locked(sc) /* Start the stats update counter */ callout_reset(&sc->tl_stat_callout, hz, tl_stats_update, sc); - - return; } /* @@ -2204,8 +2119,6 @@ tl_ifmedia_sts(ifp, ifmr) ifmr->ifm_status = mii->mii_media_status; } TL_UNLOCK(sc); - - return; } static int @@ -2284,8 +2197,6 @@ tl_watchdog(sc) tl_softreset(sc, 1); tl_init_locked(sc); - - return; } /* @@ -2351,8 +2262,6 @@ tl_stop(sc) sizeof(sc->tl_ldata->tl_tx_list)); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - return; } /* Index: dev/tl/if_tlreg.h =================================================================== --- dev/tl/if_tlreg.h (revision 226148) +++ dev/tl/if_tlreg.h (working copy) @@ -32,11 +32,10 @@ * $FreeBSD$ */ - struct tl_type { u_int16_t tl_vid; u_int16_t tl_did; - char *tl_name; + const char *tl_name; }; /* @@ -203,6 +202,7 @@ struct tl_softc { #define TL_INT_MASK 0x001C #define TL_VEC_MASK 0x1FE0 + /* * Host command register bits */ @@ -390,36 +390,6 @@ struct tl_softc { #define TL_MASK_MASK5 0x20 #define TL_MASK_MASK4 0x10 -/* - * MII frame format - */ -#ifdef ANSI_DOESNT_ALLOW_BITFIELDS -struct tl_mii_frame { - u_int16_t mii_stdelim:2, - mii_opcode:2, - mii_phyaddr:5, - mii_regaddr:5, - mii_turnaround:2; - u_int16_t mii_data; -}; -#else -struct tl_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; -}; -#endif -/* - * MII constants - */ -#define TL_MII_STARTDELIM 0x01 -#define TL_MII_READOP 0x02 -#define TL_MII_WRITEOP 0x01 -#define TL_MII_TURNAROUND 0x02 - #define TL_LAST_FRAG 0x80000000 #define TL_CSTAT_UNUSED 0x8000 #define TL_CSTAT_FRAMECMP 0x4000 @@ -499,6 +469,9 @@ struct tl_stats { #define CSR_READ_2(sc, reg) bus_read_2(sc->tl_res, reg) #define CSR_READ_1(sc, reg) bus_read_1(sc->tl_res, reg) +#define CSR_BARRIER(sc, reg, length, flags) \ + bus_barrier(sc->tl_res, reg, length, flags) + #define CMD_PUT(sc, x) CSR_WRITE_4(sc, TL_HOSTCMD, x) #define CMD_SET(sc, x) \ CSR_WRITE_4(sc, TL_HOSTCMD, CSR_READ_4(sc, TL_HOSTCMD) | (x)) Index: dev/wb/if_wb.c =================================================================== --- dev/wb/if_wb.c (revision 226148) +++ dev/wb/if_wb.c (working copy) @@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include /* "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 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,213 +341,48 @@ 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; +wb_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct wb_softc *sc; - SIO_CLR(WB_SIO_MII_CLK); + sc = device_get_softc(dev); - 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); - } + CSR_WRITE_4(sc, WB_SIO, val); + CSR_BARRIER(sc, WB_SIO, 4, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } -/* - * Read an PHY register through the MII. - */ static int -wb_mii_readreg(sc, frame) - struct wb_softc *sc; - struct wb_mii_frame *frame; - -{ - 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: - - 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); - - return(0); -} - -static int 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,19 +390,9 @@ 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); + mii_bitbang_writereg(dev, &wb_mii_bitbang_ops, phy, reg, data); - bzero((char *)&frame, sizeof(frame)); - - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - - wb_mii_writereg(sc, &frame); - 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; } /* Index: dev/wb/if_wbreg.h =================================================================== --- dev/wb/if_wbreg.h (revision 226148) +++ dev/wb/if_wbreg.h (working copy) @@ -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 /* Index: dev/xl/if_xl.c =================================================================== --- dev/xl/if_xl.c (revision 226148) +++ dev/xl/if_xl.c (working copy) @@ -127,6 +127,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -160,7 +161,7 @@ MODULE_DEPEND(xl, miibus, 1, 1, 1); /* * Various supported device vendors/types and their names. */ -static const struct xl_type xl_devs[] = { +static const struct xl_type const xl_devs[] = { { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT, "3Com 3c900-TPO Etherlink XL" }, { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO, @@ -258,10 +259,6 @@ static void xl_ifmedia_sts(struct ifnet *, struct static int xl_eeprom_wait(struct xl_softc *); static int xl_read_eeprom(struct xl_softc *, caddr_t, int, int, int); -static void xl_mii_sync(struct xl_softc *); -static void xl_mii_send(struct xl_softc *, u_int32_t, int); -static int xl_mii_readreg(struct xl_softc *, struct xl_mii_frame *); -static int xl_mii_writereg(struct xl_softc *, struct xl_mii_frame *); static void xl_rxfilter(struct xl_softc *); static void xl_rxfilter_90x(struct xl_softc *); @@ -286,6 +283,24 @@ static int xl_miibus_writereg(device_t, int, int, static void xl_miibus_statchg(device_t); static void xl_miibus_mediainit(device_t); +/* + * MII bit-bang glue + */ +static uint32_t xl_mii_bitbang_read(device_t); +static void xl_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops xl_mii_bitbang_ops = { + xl_mii_bitbang_read, + xl_mii_bitbang_write, + { + XL_MII_DATA, /* MII_BIT_MDO */ + XL_MII_DATA, /* MII_BIT_MDI */ + XL_MII_CLK, /* MII_BIT_MDC */ + XL_MII_DIR, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + static device_method_t xl_methods[] = { /* Device interface */ DEVMETHOD(device_probe, xl_probe), @@ -359,194 +374,66 @@ xl_wait(struct xl_softc *sc) * some chips/CPUs/processor speeds/bus speeds/etc but not * with others. */ -#define MII_SET(x) \ - CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \ - CSR_READ_2(sc, XL_W4_PHY_MGMT) | (x)) -#define MII_CLR(x) \ - CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \ - CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~(x)) - /* - * 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 -xl_mii_sync(struct xl_softc *sc) +static uint32_t +xl_mii_bitbang_read(device_t dev) { - register int i; + struct xl_softc *sc; + uint32_t val; - XL_SEL_WIN(4); - MII_SET(XL_MII_DIR|XL_MII_DATA); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - MII_SET(XL_MII_CLK); - MII_SET(XL_MII_DATA); - MII_SET(XL_MII_DATA); - MII_CLR(XL_MII_CLK); - MII_SET(XL_MII_DATA); - MII_SET(XL_MII_DATA); - } + /* We're already in window 4. */ + val = CSR_READ_2(sc, XL_W4_PHY_MGMT); + CSR_BARRIER(sc, XL_W4_PHY_MGMT, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + + return (val); } /* - * Clock a series of bits through the MII. + * Write the MII serial port for the MII bit-bang module. */ static void -xl_mii_send(struct xl_softc *sc, u_int32_t bits, int cnt) +xl_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct xl_softc *sc; - XL_SEL_WIN(4); - MII_CLR(XL_MII_CLK); + sc = device_get_softc(dev); - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { - MII_SET(XL_MII_DATA); - } else { - MII_CLR(XL_MII_DATA); - } - MII_CLR(XL_MII_CLK); - MII_SET(XL_MII_CLK); - } + /* We're already in window 4. */ + CSR_WRITE_2(sc, XL_W4_PHY_MGMT, val); + CSR_BARRIER(sc, XL_W4_PHY_MGMT, 2, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } -/* - * Read an PHY register through the MII. - */ static int -xl_mii_readreg(struct xl_softc *sc, struct xl_mii_frame *frame) -{ - int i, ack; - - /* Set up frame for RX. */ - frame->mii_stdelim = XL_MII_STARTDELIM; - frame->mii_opcode = XL_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - /* Select register window 4. */ - XL_SEL_WIN(4); - - CSR_WRITE_2(sc, XL_W4_PHY_MGMT, 0); - /* Turn on data xmit. */ - MII_SET(XL_MII_DIR); - - xl_mii_sync(sc); - - /* Send command/address info. */ - xl_mii_send(sc, frame->mii_stdelim, 2); - xl_mii_send(sc, frame->mii_opcode, 2); - xl_mii_send(sc, frame->mii_phyaddr, 5); - xl_mii_send(sc, frame->mii_regaddr, 5); - - /* Idle bit */ - MII_CLR((XL_MII_CLK|XL_MII_DATA)); - MII_SET(XL_MII_CLK); - - /* Turn off xmit. */ - MII_CLR(XL_MII_DIR); - - /* Check for ack */ - MII_CLR(XL_MII_CLK); - ack = CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA; - MII_SET(XL_MII_CLK); - - /* - * 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++) { - MII_CLR(XL_MII_CLK); - MII_SET(XL_MII_CLK); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - MII_CLR(XL_MII_CLK); - if (!ack) { - if (CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA) - frame->mii_data |= i; - } - MII_SET(XL_MII_CLK); - } - -fail: - MII_CLR(XL_MII_CLK); - MII_SET(XL_MII_CLK); - - return (ack ? 1 : 0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -xl_mii_writereg(struct xl_softc *sc, struct xl_mii_frame *frame) -{ - - /* Set up frame for TX. */ - frame->mii_stdelim = XL_MII_STARTDELIM; - frame->mii_opcode = XL_MII_WRITEOP; - frame->mii_turnaround = XL_MII_TURNAROUND; - - /* Select the window 4. */ - XL_SEL_WIN(4); - - /* Turn on data output. */ - MII_SET(XL_MII_DIR); - - xl_mii_sync(sc); - - xl_mii_send(sc, frame->mii_stdelim, 2); - xl_mii_send(sc, frame->mii_opcode, 2); - xl_mii_send(sc, frame->mii_phyaddr, 5); - xl_mii_send(sc, frame->mii_regaddr, 5); - xl_mii_send(sc, frame->mii_turnaround, 2); - xl_mii_send(sc, frame->mii_data, 16); - - /* Idle bit. */ - MII_SET(XL_MII_CLK); - MII_CLR(XL_MII_CLK); - - /* Turn off xmit. */ - MII_CLR(XL_MII_DIR); - - return (0); -} - -static int xl_miibus_readreg(device_t dev, int phy, int reg) { struct xl_softc *sc; - struct xl_mii_frame frame; sc = device_get_softc(dev); - bzero((char *)&frame, sizeof(frame)); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; + /* Select the window 4. */ + XL_SEL_WIN(4); - xl_mii_readreg(sc, &frame); - - return (frame.mii_data); + return (mii_bitbang_readreg(dev, &xl_mii_bitbang_ops, phy, reg)); } static int xl_miibus_writereg(device_t dev, int phy, int reg, int data) { struct xl_softc *sc; - struct xl_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; + /* Select the window 4. */ + XL_SEL_WIN(4); - xl_mii_writereg(sc, &frame); + mii_bitbang_writereg(dev, &xl_mii_bitbang_ops, phy, reg, data); return (0); } Index: dev/xl/if_xlreg.h =================================================================== --- dev/xl/if_xlreg.h (revision 226148) +++ dev/xl/if_xlreg.h (working copy) @@ -556,27 +556,10 @@ struct xl_chain_data { struct xl_type { u_int16_t xl_vid; u_int16_t xl_did; - char *xl_name; + const char *xl_name; }; -struct xl_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 XL_MII_STARTDELIM 0x01 -#define XL_MII_READOP 0x02 -#define XL_MII_WRITEOP 0x01 -#define XL_MII_TURNAROUND 0x02 - -/* * The 3C905B adapters implement a few features that we want to * take advantage of, namely the multicast hash filter. With older * chips, you only have the option of turning on reception of all @@ -680,8 +663,17 @@ struct xl_stats { #define CSR_READ_1(sc, reg) \ bus_space_read_1(sc->xl_btag, sc->xl_bhandle, reg) -#define XL_SEL_WIN(x) \ - CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_WINSEL | x) +#define CSR_BARRIER(sc, reg, length, flags) \ + bus_space_barrier(sc->xl_btag, sc->xl_bhandle, reg, length, flags) + +#define XL_SEL_WIN(x) do { \ + CSR_BARRIER(sc, XL_COMMAND, 2, \ + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); \ + CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_WINSEL | x); \ + CSR_BARRIER(sc, XL_COMMAND, 2, \ + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); \ +} while (0) + #define XL_TIMEOUT 1000 /* Index: modules/mii/Makefile =================================================================== --- modules/mii/Makefile (revision 226154) +++ modules/mii/Makefile (working copy) @@ -5,14 +5,17 @@ KMOD= miibus SRCS= acphy.c amphy.c atphy.c axphy.c bmtphy.c brgphy.c bus_if.h SRCS+= ciphy.c device_if.h -SRCS+= e1000phy.c gentbi.c icsphy.c ip1000phy.c jmphy.c -SRCS+= lxtphy.c miibus_if.c miibus_if.h mii.c miidevs.h mii_physubr.c +SRCS+= e1000phy.c gentbi.c icsphy.c ip1000phy.c jmphy.c lxtphy.c +SRCS+= miibus_if.c miibus_if.h mii.c miidevs.h mii_bitbang.c mii_physubr.c SRCS+= mlphy.c nsgphy.c nsphy.c nsphyter.c pci_if.h pnaphy.c qsphy.c SRCS+= rdcphy.c rgephy.c rlphy.c tdkphy.c tlphy.c truephy.c SRCS+= ukphy.c ukphy_subr.c SRCS+= xmphy.c EXPORT_SYMS= mii_attach \ + mii_bitbang_readreg \ + mii_bitbang_sync \ + mii_bitbang_writereg \ mii_mediachg \ mii_pollstat \ mii_tick Index: pci/if_rl.c =================================================================== --- pci/if_rl.c (revision 226148) +++ pci/if_rl.c (working copy) @@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -130,7 +131,7 @@ MODULE_DEPEND(rl, miibus, 1, 1, 1); /* * Various supported device vendors/types and their names. */ -static struct rl_type rl_devs[] = { +static const struct rl_type const rl_devs[] = { { RT_VENDORID, RT_DEVICEID_8129, RL_8129, "RealTek 8129 10/100BaseTX" }, { RT_VENDORID, RT_DEVICEID_8139, RL_8139, @@ -187,10 +188,6 @@ static int rl_ioctl(struct ifnet *, u_long, caddr_ static void rl_intr(void *); static void rl_init(void *); static void rl_init_locked(struct rl_softc *sc); -static void rl_mii_send(struct rl_softc *, uint32_t, int); -static void rl_mii_sync(struct rl_softc *); -static int rl_mii_readreg(struct rl_softc *, struct rl_mii_frame *); -static int rl_mii_writereg(struct rl_softc *, struct rl_mii_frame *); static int rl_miibus_readreg(device_t, int, int); static void rl_miibus_statchg(device_t); static int rl_miibus_writereg(device_t, int, int, int); @@ -215,6 +212,24 @@ static void rl_watchdog(struct rl_softc *); static void rl_setwol(struct rl_softc *); static void rl_clrwol(struct rl_softc *); +/* + * MII bit-bang glue + */ +static uint32_t rl_mii_bitbang_read(device_t); +static void rl_mii_bitbang_write(device_t, uint32_t); + +static const struct mii_bitbang_ops rl_mii_bitbang_ops = { + rl_mii_bitbang_read, + rl_mii_bitbang_write, + { + RL_MII_DATAOUT, /* MII_BIT_MDO */ + RL_MII_DATAIN, /* MII_BIT_MDI */ + RL_MII_CLK, /* MII_BIT_MDC */ + RL_MII_DIR, /* MII_BIT_DIR_HOST_PHY */ + 0, /* MII_BIT_DIR_PHY_HOST */ + } +}; + static device_method_t rl_methods[] = { /* Device interface */ DEVMETHOD(device_probe, rl_probe), @@ -340,181 +355,43 @@ rl_read_eeprom(struct rl_softc *sc, uint8_t *dest, } /* - * MII access routines are provided for the 8129, which - * doesn't have a built-in PHY. For the 8139, we fake things - * up by diverting rl_phy_readreg()/rl_phy_writereg() to the - * direct access PHY registers. + * Read the MII serial port for the MII bit-bang module. */ -#define MII_SET(x) \ - CSR_WRITE_1(sc, RL_MII, \ - CSR_READ_1(sc, RL_MII) | (x)) - -#define MII_CLR(x) \ - CSR_WRITE_1(sc, RL_MII, \ - CSR_READ_1(sc, RL_MII) & ~(x)) - -/* - * Sync the PHYs by setting data bit and strobing the clock 32 times. - */ -static void -rl_mii_sync(struct rl_softc *sc) +static uint32_t +rl_mii_bitbang_read(device_t dev) { - register int i; + struct rl_softc *sc; + uint32_t val; - MII_SET(RL_MII_DIR|RL_MII_DATAOUT); + sc = device_get_softc(dev); - for (i = 0; i < 32; i++) { - MII_SET(RL_MII_CLK); - DELAY(1); - MII_CLR(RL_MII_CLK); - DELAY(1); - } + val = CSR_READ_1(sc, RL_MII); + CSR_BARRIER(sc, RL_MII, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); + + return (val); } /* - * Clock a series of bits through the MII. + * Write the MII serial port for the MII bit-bang module. */ static void -rl_mii_send(struct rl_softc *sc, uint32_t bits, int cnt) +rl_mii_bitbang_write(device_t dev, uint32_t val) { - int i; + struct rl_softc *sc; - MII_CLR(RL_MII_CLK); + sc = device_get_softc(dev); - for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { - MII_SET(RL_MII_DATAOUT); - } else { - MII_CLR(RL_MII_DATAOUT); - } - DELAY(1); - MII_CLR(RL_MII_CLK); - DELAY(1); - MII_SET(RL_MII_CLK); - } + CSR_WRITE_1(sc, RL_MII, val); + CSR_BARRIER(sc, RL_MII, 1, + BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); } -/* - * Read an PHY register through the MII. - */ static int -rl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame) -{ - int i, ack; - - /* Set up frame for RX. */ - frame->mii_stdelim = RL_MII_STARTDELIM; - frame->mii_opcode = RL_MII_READOP; - frame->mii_turnaround = 0; - frame->mii_data = 0; - - CSR_WRITE_2(sc, RL_MII, 0); - - /* Turn on data xmit. */ - MII_SET(RL_MII_DIR); - - rl_mii_sync(sc); - - /* Send command/address info. */ - rl_mii_send(sc, frame->mii_stdelim, 2); - rl_mii_send(sc, frame->mii_opcode, 2); - rl_mii_send(sc, frame->mii_phyaddr, 5); - rl_mii_send(sc, frame->mii_regaddr, 5); - - /* Idle bit */ - MII_CLR((RL_MII_CLK|RL_MII_DATAOUT)); - DELAY(1); - MII_SET(RL_MII_CLK); - DELAY(1); - - /* Turn off xmit. */ - MII_CLR(RL_MII_DIR); - - /* Check for ack */ - MII_CLR(RL_MII_CLK); - DELAY(1); - ack = CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN; - MII_SET(RL_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++) { - MII_CLR(RL_MII_CLK); - DELAY(1); - MII_SET(RL_MII_CLK); - DELAY(1); - } - goto fail; - } - - for (i = 0x8000; i; i >>= 1) { - MII_CLR(RL_MII_CLK); - DELAY(1); - if (!ack) { - if (CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN) - frame->mii_data |= i; - DELAY(1); - } - MII_SET(RL_MII_CLK); - DELAY(1); - } - -fail: - MII_CLR(RL_MII_CLK); - DELAY(1); - MII_SET(RL_MII_CLK); - DELAY(1); - - return (ack ? 1 : 0); -} - -/* - * Write to a PHY register through the MII. - */ -static int -rl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame) -{ - - /* Set up frame for TX. */ - frame->mii_stdelim = RL_MII_STARTDELIM; - frame->mii_opcode = RL_MII_WRITEOP; - frame->mii_turnaround = RL_MII_TURNAROUND; - - /* Turn on data output. */ - MII_SET(RL_MII_DIR); - - rl_mii_sync(sc); - - rl_mii_send(sc, frame->mii_stdelim, 2); - rl_mii_send(sc, frame->mii_opcode, 2); - rl_mii_send(sc, frame->mii_phyaddr, 5); - rl_mii_send(sc, frame->mii_regaddr, 5); - rl_mii_send(sc, frame->mii_turnaround, 2); - rl_mii_send(sc, frame->mii_data, 16); - - /* Idle bit. */ - MII_SET(RL_MII_CLK); - DELAY(1); - MII_CLR(RL_MII_CLK); - DELAY(1); - - /* Turn off xmit. */ - MII_CLR(RL_MII_DIR); - - return (0); -} - -static int rl_miibus_readreg(device_t dev, int phy, int reg) { struct rl_softc *sc; - struct rl_mii_frame frame; - uint16_t rval = 0; - uint16_t rl8139_reg = 0; + uint16_t rl8139_reg; sc = device_get_softc(dev); @@ -545,30 +422,22 @@ rl_miibus_readreg(device_t dev, int phy, int reg) * us the results of parallel detection. */ case RL_MEDIASTAT: - rval = CSR_READ_1(sc, RL_MEDIASTAT); - return (rval); + return (CSR_READ_1(sc, RL_MEDIASTAT)); default: device_printf(sc->rl_dev, "bad phy register\n"); return (0); } - rval = CSR_READ_2(sc, rl8139_reg); - return (rval); + return (CSR_READ_2(sc, rl8139_reg)); } - bzero((char *)&frame, sizeof(frame)); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - rl_mii_readreg(sc, &frame); - - return (frame.mii_data); + return (mii_bitbang_readreg(dev, &rl_mii_bitbang_ops, phy, reg)); } static int rl_miibus_writereg(device_t dev, int phy, int reg, int data) { struct rl_softc *sc; - struct rl_mii_frame frame; - uint16_t rl8139_reg = 0; + uint16_t rl8139_reg; sc = device_get_softc(dev); @@ -601,11 +470,7 @@ rl_miibus_writereg(device_t dev, int phy, int reg, return (0); } - bzero((char *)&frame, sizeof(frame)); - frame.mii_phyaddr = phy; - frame.mii_regaddr = reg; - frame.mii_data = data; - rl_mii_writereg(sc, &frame); + mii_bitbang_writereg(dev, &rl_mii_bitbang_ops, phy, reg, data); return (0); } @@ -719,7 +584,7 @@ rl_reset(struct rl_softc *sc) static int rl_probe(device_t dev) { - struct rl_type *t; + const struct rl_type *t; uint16_t devid, revid, vendor; int i; @@ -773,7 +638,7 @@ rl_attach(device_t dev) uint16_t as[3]; struct ifnet *ifp; struct rl_softc *sc; - struct rl_type *t; + const struct rl_type *t; struct sysctl_ctx_list *ctx; struct sysctl_oid_list *children; int error = 0, hwrev, i, phy, pmc, rid; Index: pci/if_rlreg.h =================================================================== --- pci/if_rlreg.h (revision 226148) +++ pci/if_rlreg.h (working copy) @@ -597,33 +597,16 @@ struct rl_type { uint16_t rl_vid; uint16_t rl_did; int rl_basetype; - char *rl_name; + const char *rl_name; }; struct rl_hwrev { uint32_t rl_rev; int rl_type; - char *rl_desc; + const char *rl_desc; int rl_max_mtu; }; -struct rl_mii_frame { - uint8_t mii_stdelim; - uint8_t mii_opcode; - uint8_t mii_phyaddr; - uint8_t mii_regaddr; - uint8_t mii_turnaround; - uint16_t mii_data; -}; - -/* - * MII constants - */ -#define RL_MII_STARTDELIM 0x01 -#define RL_MII_READOP 0x02 -#define RL_MII_WRITEOP 0x01 -#define RL_MII_TURNAROUND 0x02 - #define RL_8129 1 #define RL_8139 2 #define RL_8139CPLUS 3 @@ -880,7 +863,7 @@ struct rl_softc { device_t rl_miibus; bus_dma_tag_t rl_parent_tag; uint8_t rl_type; - struct rl_hwrev *rl_hwrev; + const struct rl_hwrev *rl_hwrev; int rl_eecmd_read; int rl_eewidth; int rl_txthresh; @@ -950,6 +933,9 @@ struct rl_softc { #define CSR_READ_1(sc, reg) \ bus_space_read_1(sc->rl_btag, sc->rl_bhandle, reg) +#define CSR_BARRIER(sc, reg, length, flags) \ + bus_space_barrier(sc->rl_btag, sc->rl_bhandle, reg, length, flags) + #define CSR_SETBIT_1(sc, offset, val) \ CSR_WRITE_1(sc, offset, CSR_READ_1(sc, offset) | (val))