summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2011-11-01 16:13:59 +0000
committermarius <marius@FreeBSD.org>2011-11-01 16:13:59 +0000
commitb4610d98b0096971fd87d53d90c40f4da7db34e2 (patch)
treead9ba266ea9f21e3bb8157cdc1c2c7c8b1a6b9a3 /sys/dev
parentd08a02f709c03ad61dd57d1fa39412d6de62189d (diff)
downloadFreeBSD-src-b4610d98b0096971fd87d53d90c40f4da7db34e2.zip
FreeBSD-src-b4610d98b0096971fd87d53d90c40f4da7db34e2.tar.gz
- Import the common MII bitbang'ing code from NetBSD and convert drivers to
take advantage of it instead of duplicating it. This reduces the size of the i386 GENERIC kernel by about 4k. The only potential in-tree user left unconverted is xe(4), which generally should be changed to use miibus(4) instead of implementing PHY handling on its own, as otherwise it makes not much sense to add a dependency on miibus(4)/mii_bitbang(4) to xe(4) just for the MII bitbang'ing code. The common MII bitbang'ing code also is useful in the embedded space for using GPIO pins to implement MII access. - Based on lessons learnt with dc(4) (see r185750), add bus barriers to the MII bitbang read and write functions of the other drivers converted in order to ensure the intended ordering. Given that register access via an index register as well as register bank/window switching is subject to the same problem, also add bus barriers to the respective functions of smc(4), tl(4) and xl(4). - Sprinkle some const. Thanks to the following testers: Andrew Bliznak (nge(4)), nwhitehorn@ (bm(4)), yongari@ (sis(4) and ste(4)) Thanks to Hans-Joerg Sirtl for supplying hardware to test stge(4). Reviewed by: yongari (subset of drivers) Obtained from: NetBSD (partially)
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/bm/if_bm.c218
-rw-r--r--sys/dev/bm/if_bmreg.h10
-rw-r--r--sys/dev/bm/if_bmvar.h12
-rw-r--r--sys/dev/dc/if_dc.c210
-rw-r--r--sys/dev/dc/if_dcreg.h22
-rw-r--r--sys/dev/mii/mii_bitbang.c180
-rw-r--r--sys/dev/mii/mii_bitbang.h54
-rw-r--r--sys/dev/nge/if_nge.c230
-rw-r--r--sys/dev/nge/if_ngereg.h24
-rw-r--r--sys/dev/sis/if_sis.c226
-rw-r--r--sys/dev/sis/if_sisreg.h19
-rw-r--r--sys/dev/smc/if_smc.c145
-rw-r--r--sys/dev/ste/if_ste.c225
-rw-r--r--sys/dev/ste/if_stereg.h22
-rw-r--r--sys/dev/stge/if_stge.c236
-rw-r--r--sys/dev/stge/if_stgereg.h20
-rw-r--r--sys/dev/tl/if_tl.c343
-rw-r--r--sys/dev/tl/if_tlreg.h37
-rw-r--r--sys/dev/wb/if_wb.c272
-rw-r--r--sys/dev/wb/if_wbreg.h22
-rw-r--r--sys/dev/xl/if_xl.c205
-rw-r--r--sys/dev/xl/if_xlreg.h32
22 files changed, 799 insertions, 1965 deletions
diff --git a/sys/dev/bm/if_bm.c b/sys/dev/bm/if_bm.c
index 1977f92..c478e7b 100644
--- a/sys/dev/bm/if_bm.c
+++ b/sys/dev/bm/if_bm.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/ofw/ofw_bus.h>
@@ -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,171 +162,36 @@ DRIVER_MODULE(miibus, bm, miibus_driver, miibus_devclass, 0, 0);
*/
/*
- * 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)
-{
- 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);
-}
-
-/*
- * Write a bit to the MII bus.
- */
-static void
-bm_mii_writebit(struct bm_softc *sc, int bit)
-{
- u_int16_t regval;
-
- 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);
-}
-
-/*
- * Read a bit from the MII bus.
- */
-static int
-bm_mii_readbit(struct bm_softc *sc)
-{
- u_int16_t regval, bitin;
-
- /* ~BM_MII_OENABLE */
- regval = 0;
-
- 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;
-
- return (bitin == BM_MII_DATAIN);
-}
-
-/*
- * 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)
+bm_mii_bitbang_write(device_t dev, uint32_t val)
{
- 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;
- }
+ struct bm_softc *sc;
- /*
- * Skip through idle bit-times
- */
- bm_mii_writebit(sc, 0);
- bm_mii_writebit(sc, 0);
+ sc = device_get_softc(dev);
- return ((ack) ? 1 : 0);
+ CSR_WRITE_2(sc, BM_MII_CSR, val);
+ CSR_BARRIER(sc, BM_MII_CSR, 2,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
}
/*
- * Write to a PHY register through the MII.
+ * Read the MII serial port for the MII bit-bang module.
*/
-static int
-bm_mii_writereg(struct bm_softc *sc, struct bm_mii_frame *frame)
+static uint32_t
+bm_mii_bitbang_read(device_t dev)
{
- /*
- * 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);
+ struct bm_softc *sc;
+ uint32_t reg;
- 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);
+ sc = device_get_softc(dev);
- /*
- * Idle bit.
- */
- bm_mii_writebit(sc, 0);
+ reg = CSR_READ_2(sc, BM_MII_CSR);
+ CSR_BARRIER(sc, BM_MII_CSR, 2,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
- return (0);
+ return (reg);
}
/*
@@ -323,34 +200,15 @@ bm_mii_writereg(struct bm_softc *sc, struct bm_mii_frame *frame)
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));
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- frame.mii_data = data;
- bm_mii_writereg(sc, &frame);
+ mii_bitbang_readreg(dev, &bm_mii_bitbang_ops, phy, reg);
return (0);
}
diff --git a/sys/dev/bm/if_bmreg.h b/sys/dev/bm/if_bmreg.h
index 15ee1fe..39d9b48 100644
--- a/sys/dev/bm/if_bmreg.h
+++ b/sys/dev/bm/if_bmreg.h
@@ -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)
diff --git a/sys/dev/bm/if_bmvar.h b/sys/dev/bm/if_bmvar.h
index 7d31489..b50d65b 100644
--- a/sys/dev/bm/if_bmvar.h
+++ b/sys/dev/bm/if_bmvar.h
@@ -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;
-};
-
diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c
index 184fa8f..57acb39 100644
--- a/sys/dev/dc/if_dc.c
+++ b/sys/dev/dc/if_dc.c
@@ -122,6 +122,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
@@ -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,
@@ -272,12 +273,6 @@ static void dc_eeprom_getword_xircom(struct dc_softc *, int, uint16_t *);
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);
@@ -307,6 +302,24 @@ static int dc_decode_leaf_sym(struct dc_softc *, struct dc_eblock_sym *);
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
@@ -611,185 +624,45 @@ dc_read_eeprom(struct dc_softc *sc, caddr_t dest, int off, int cnt, int be)
}
/*
- * The following two routines are taken from the Macronix 98713
- * Application Notes pp.19-21.
- */
-/*
- * Write a bit to the MII bus.
+ * Write the MII serial port for the MII bit-bang module.
*/
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;
-
- 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);
-
- return (0);
-}
+ struct dc_softc *sc;
+ uint32_t val;
-/*
- * Sync the PHYs by setting data bit and strobing the clock 32 times.
- */
-static void
-dc_mii_sync(struct dc_softc *sc)
-{
- int i;
+ sc = device_get_softc(dev);
- 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);
-}
-
-/*
- * 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);
+ return (val);
}
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)) {
@@ -881,34 +754,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 |
@@ -964,15 +832,11 @@ dc_miibus_writereg(device_t dev, int phy, int reg, int data)
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);
diff --git a/sys/dev/dc/if_dcreg.h b/sys/dev/dc/if_dcreg.h
index acd80c0..cbbe39f 100644
--- a/sys/dev/dc/if_dcreg.h
+++ b/sys/dev/dc/if_dcreg.h
@@ -531,27 +531,9 @@ 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
@@ -827,7 +809,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
diff --git a/sys/dev/mii/mii_bitbang.c b/sys/dev/mii/mii_bitbang.c
new file mode 100644
index 0000000..6a5f5dc
--- /dev/null
+++ b/sys/dev/mii/mii_bitbang.c
@@ -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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
+
+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);
+}
diff --git a/sys/dev/mii/mii_bitbang.h b/sys/dev/mii/mii_bitbang.h
new file mode 100644
index 0000000..2bc7427
--- /dev/null
+++ b/sys/dev/mii/mii_bitbang.h
@@ -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);
diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c
index db20ad2..3d7ad63 100644
--- a/sys/dev/nge/if_nge.c
+++ b/sys/dev/nge/if_nge.c
@@ -117,6 +117,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_vlan_var.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
@@ -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 *, int);
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, int off, int cnt)
}
/*
- * Sync the PHYs by setting data bit and strobing the clock 32 times.
- */
-static void
-nge_mii_sync(struct nge_softc *sc)
-{
- int i;
-
- SIO_SET(NGE_MEAR_MII_DIR|NGE_MEAR_MII_DATA);
-
- for (i = 0; i < 32; i++) {
- SIO_SET(NGE_MEAR_MII_CLK);
- DELAY(1);
- SIO_CLR(NGE_MEAR_MII_CLK);
- DELAY(1);
- }
-}
-
-/*
- * Clock a series of bits through the MII.
- */
-static void
-nge_mii_send(struct nge_softc *sc, uint32_t bits, int cnt)
-{
- int i;
-
- SIO_CLR(NGE_MEAR_MII_CLK);
-
- 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);
- }
-}
-
-/*
- * Read an PHY register through the MII.
+ * Read the MII serial port for the MII bit-bang module.
*/
-static int
-nge_mii_readreg(struct nge_softc *sc, struct nge_mii_frame *frame)
+static uint32_t
+nge_mii_bitbang_read(device_t dev)
{
- 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);
- }
+ struct nge_softc *sc;
+ uint32_t val;
-fail:
+ sc = device_get_softc(dev);
- SIO_CLR(NGE_MEAR_MII_CLK);
- DELAY(1);
- SIO_SET(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);
- if (ack)
- return (1);
- return (0);
+ return (val);
}
/*
- * Write to a PHY register through the MII.
+ * Write the MII serial port for the MII bit-bang module.
*/
-static int
-nge_mii_writereg(struct nge_softc *sc, struct nge_mii_frame *frame)
+static void
+nge_mii_bitbang_write(device_t dev, uint32_t val)
{
+ struct nge_softc *sc;
- /*
- * 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);
+ sc = device_get_softc(dev);
- return (0);
+ CSR_WRITE_4(sc, NGE_MEAR, val);
+ CSR_BARRIER_4(sc, NGE_MEAR,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
}
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,12 +502,7 @@ nge_miibus_writereg(device_t dev, int phy, int reg, int data)
return (0);
}
- bzero((char *)&frame, sizeof(frame));
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- frame.mii_data = data;
- nge_mii_writereg(sc, &frame);
+ mii_bitbang_writereg(dev, &nge_mii_bitbang_ops, phy, reg, data);
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;
diff --git a/sys/dev/nge/if_ngereg.h b/sys/dev/nge/if_ngereg.h
index 4ad1bf9..9df0d92 100644
--- a/sys/dev/nge/if_ngereg.h
+++ b/sys/dev/nge/if_ngereg.h
@@ -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,8 +674,9 @@ 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)
diff --git a/sys/dev/sis/if_sis.c b/sys/dev/sis/if_sis.c
index d0be783..630281d 100644
--- a/sys/dev/sis/if_sis.c
+++ b/sys/dev/sis/if_sis.c
@@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
@@ -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, caddr_t dest)
#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)
-{
- int i;
-
- SIO_CLR(SIS_MII_CLK);
-
- 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);
- }
-}
-
-/*
- * Read an PHY register through the MII.
- */
-static int
-sis_mii_readreg(struct sis_softc *sc, struct sis_mii_frame *frame)
+sis_mii_bitbang_write(device_t dev, uint32_t val)
{
- 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);
+ struct sis_softc *sc;
- /*
- * Turn off xmit.
- */
- SIO_CLR(SIS_MII_DIR);
+ sc = device_get_softc(dev);
- return (0);
+ CSR_WRITE_4(sc, SIS_EECTL, val);
+ CSR_BARRIER(sc, SIS_EECTL, 4,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
}
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, int data)
}
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;
diff --git a/sys/dev/sis/if_sisreg.h b/sys/dev/sis/if_sisreg.h
index c86a13d..b400806 100644
--- a/sys/dev/sis/if_sisreg.h
+++ b/sys/dev/sis/if_sisreg.h
@@ -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
diff --git a/sys/dev/smc/if_smc.c b/sys/dev/smc/if_smc.c
index 4aa0396..9404f56 100644
--- a/sys/dev/smc/if_smc.c
+++ b/sys/dev/smc/if_smc.c
@@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$");
#include <dev/smc/if_smcvar.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#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 @@ smc_read_multi_2(struct smc_softc *sc, bus_addr_t offset, uint16_t *datap,
}
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);
-
- /*
- * 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);
- }
+ val = smc_read_2(sc, MGMT);
+ smc_barrier(sc, MGMT, 2,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
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,26 +982,7 @@ 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);
-
- /*
- * 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));
+ val = mii_bitbang_readreg(dev, &smc_mii_bitbang_ops, phy, reg);
SMC_UNLOCK(sc);
return (val);
@@ -1014,23 +999,7 @@ smc_miibus_writereg(device_t dev, int phy, int reg, int data)
smc_select_bank(sc, 3);
- /*
- * Send idle pattern.
- */
- smc_mii_writebits(sc, 0xffffffff, 32);
-
- /*
- * 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));
+ mii_bitbang_writereg(dev, &smc_mii_bitbang_ops, phy, reg, data);
SMC_UNLOCK(sc);
return (0);
diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c
index 846761c..a6fc00b 100644
--- a/sys/dev/ste/if_ste.c
+++ b/sys/dev/ste/if_ste.c
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
@@ -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,210 +202,51 @@ DRIVER_MODULE(miibus, ste, miibus_driver, miibus_devclass, 0, 0);
#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.
- */
-static void
-ste_mii_sync(struct ste_softc *sc)
-{
- int i;
-
- MII_SET(STE_PHYCTL_MDIR|STE_PHYCTL_MDATA);
-
- for (i = 0; i < 32; i++) {
- MII_SET(STE_PHYCTL_MCLK);
- DELAY(1);
- MII_CLR(STE_PHYCTL_MCLK);
- DELAY(1);
- }
-}
-
-/*
- * Clock a series of bits through the MII.
- */
-static void
-ste_mii_send(struct ste_softc *sc, uint32_t bits, int cnt)
-{
- int i;
-
- MII_CLR(STE_PHYCTL_MCLK);
-
- 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);
- }
-}
-
/*
- * Read an PHY register through the MII.
+ * Read the MII serial port for the MII bit-bang module.
*/
-static int
-ste_mii_readreg(struct ste_softc *sc, struct ste_mii_frame *frame)
+static uint32_t
+ste_mii_bitbang_read(device_t dev)
{
- 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);
- }
+ struct ste_softc *sc;
+ uint32_t val;
-fail:
+ sc = device_get_softc(dev);
- MII_CLR(STE_PHYCTL_MCLK);
- DELAY(1);
- MII_SET(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);
- if (ack)
- return (1);
- return (0);
+ return (val);
}
/*
- * Write to a PHY register through the MII.
+ * Write the MII serial port for the MII bit-bang module.
*/
-static int
-ste_mii_writereg(struct ste_softc *sc, struct ste_mii_frame *frame)
+static void
+ste_mii_bitbang_write(device_t dev, uint32_t val)
{
+ struct ste_softc *sc;
- /*
- * 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);
+ sc = device_get_softc(dev);
- return (0);
+ CSR_WRITE_1(sc, STE_PHYCTL, val);
+ CSR_BARRIER(sc, STE_PHYCTL, 1,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
}
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));
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- frame.mii_data = data;
- ste_mii_writereg(sc, &frame);
+ mii_bitbang_writereg(dev, &ste_mii_bitbang_ops, phy, reg, data);
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;
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 840e0bf..e3aa51b 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -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
diff --git a/sys/dev/stge/if_stge.c b/sys/dev/stge/if_stge.c
index 5058a4d..b18da27 100644
--- a/sys/dev/stge/if_stge.c
+++ b/sys/dev/stge/if_stge.c
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
@@ -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, int, int);
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,176 +240,40 @@ 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)
-{
- int i;
-
- MII_CLR(PC_MgmtClk);
-
- 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);
- }
-}
-
-/*
- * Read an PHY register through the MII.
- */
-static int
-stge_mii_readreg(struct stge_softc *sc, struct stge_mii_frame *frame)
+stge_mii_bitbang_write(device_t dev, uint32_t val)
{
- 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);
+ struct stge_softc *sc;
- /*
- * Turn off xmit.
- */
- MII_CLR(PC_MgmtDir);
+ sc = device_get_softc(dev);
- return(0);
+ CSR_WRITE_1(sc, STGE_PhyCtrl, val);
+ CSR_BARRIER(sc, STGE_PhyCtrl, 1,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
}
/*
@@ -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, uint16_t *data)
static int
stge_probe(device_t dev)
{
- struct stge_product *sp;
+ const struct stge_product *sp;
int i;
uint16_t vendor, devid;
diff --git a/sys/dev/stge/if_stgereg.h b/sys/dev/stge/if_stgereg.h
index 6ecbdf9..f14142a 100644
--- a/sys/dev/stge/if_stgereg.h
+++ b/sys/dev/stge/if_stgereg.h
@@ -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
diff --git a/sys/dev/tl/if_tl.c b/sys/dev/tl/if_tl.c
index a256552..b7f4100 100644
--- a/sys/dev/tl/if_tl.c
+++ b/sys/dev/tl/if_tl.c
@@ -203,6 +203,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
@@ -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 *, int);
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, 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,89 +722,26 @@ tl_mii_readreg(sc, frame)
tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MINTEN);
}
- /*
- * Turn on data xmit.
- */
- tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MTXEN);
-
- /*
- * 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);
+ val = mii_bitbang_readreg(dev, &tl_mii_bitbang_ops, phy, reg);
- /* 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);
-
- /*
- * Set up frame for TX.
- */
+ sc = device_get_softc(dev);
- 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.
*/
@@ -761,67 +750,12 @@ tl_mii_writereg(sc, frame)
tl_dio_clrbit(sc, TL_NETSIO, TL_SIO_MINTEN);
}
- /*
- * Turn on data output.
- */
- tl_dio_setbit(sc, TL_NETSIO, TL_SIO_MTXEN);
-
- 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);
+ mii_bitbang_writereg(dev, &tl_mii_bitbang_ops, phy, reg, data);
- 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);
}
@@ -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;
}
/*
diff --git a/sys/dev/tl/if_tlreg.h b/sys/dev/tl/if_tlreg.h
index 4e340b1..4a82cc5 100644
--- a/sys/dev/tl/if_tlreg.h
+++ b/sys/dev/tl/if_tlreg.h
@@ -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))
diff --git a/sys/dev/wb/if_wb.c b/sys/dev/wb/if_wb.c
index f924d3e..daac022 100644
--- a/sys/dev/wb/if_wb.c
+++ b/sys/dev/wb/if_wb.c
@@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
/* "device miibus" required. See GENERIC if you get errors here. */
@@ -129,7 +130,7 @@ MODULE_DEPEND(wb, miibus, 1, 1, 1);
/*
* Various supported device vendors/types and their names.
*/
-static struct wb_type wb_devs[] = {
+static const struct wb_type const wb_devs[] = {
{ WB_VENDORID, WB_DEVICEID_840F,
"Winbond W89C840F 10/100BaseTX" },
{ CP_VENDORID, CP_DEVICEID_RL100,
@@ -166,10 +167,6 @@ static void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static void wb_eeprom_putbyte(struct wb_softc *, int);
static void wb_eeprom_getword(struct wb_softc *, int, u_int16_t *);
static void wb_read_eeprom(struct wb_softc *, caddr_t, int, int, int);
-static void wb_mii_sync(struct wb_softc *);
-static void wb_mii_send(struct wb_softc *, u_int32_t, int);
-static int wb_mii_readreg(struct wb_softc *, struct wb_mii_frame *);
-static int wb_mii_writereg(struct wb_softc *, struct wb_mii_frame *);
static void wb_setcfg(struct wb_softc *, u_int32_t);
static void wb_setmulti(struct wb_softc *);
@@ -182,6 +179,24 @@ static int wb_miibus_readreg(device_t, int, int);
static int wb_miibus_writereg(device_t, int, int, int);
static void wb_miibus_statchg(device_t);
+/*
+ * MII bit-bang glue
+ */
+static uint32_t wb_mii_bitbang_read(device_t);
+static void wb_mii_bitbang_write(device_t, uint32_t);
+
+static const struct mii_bitbang_ops wb_mii_bitbang_ops = {
+ wb_mii_bitbang_read,
+ wb_mii_bitbang_write,
+ {
+ WB_SIO_MII_DATAOUT, /* MII_BIT_MDO */
+ WB_SIO_MII_DATAIN, /* MII_BIT_MDI */
+ WB_SIO_MII_CLK, /* MII_BIT_MDC */
+ WB_SIO_MII_DIR, /* MII_BIT_DIR_HOST_PHY */
+ 0, /* MII_BIT_DIR_PHY_HOST */
+ }
+};
+
#ifdef WB_USEIOSPACE
#define WB_RES SYS_RES_IOPORT
#define WB_RID WB_PCI_LOIO
@@ -262,8 +277,6 @@ wb_eeprom_putbyte(sc, addr)
SIO_CLR(WB_SIO_EE_CLK);
DELAY(100);
}
-
- return;
}
/*
@@ -304,8 +317,6 @@ wb_eeprom_getword(sc, addr, dest)
CSR_WRITE_4(sc, WB_SIO, 0);
*dest = word;
-
- return;
}
/*
@@ -330,194 +341,39 @@ wb_read_eeprom(sc, dest, off, cnt, swap)
else
*ptr = word;
}
-
- return;
}
/*
- * Sync the PHYs by setting data bit and strobing the clock 32 times.
+ * Read the MII serial port for the MII bit-bang module.
*/
-static void
-wb_mii_sync(sc)
- struct wb_softc *sc;
+static uint32_t
+wb_mii_bitbang_read(device_t dev)
{
- register int i;
+ struct wb_softc *sc;
+ uint32_t val;
- SIO_SET(WB_SIO_MII_DIR|WB_SIO_MII_DATAIN);
+ sc = device_get_softc(dev);
- for (i = 0; i < 32; i++) {
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
- }
+ val = CSR_READ_4(sc, WB_SIO);
+ CSR_BARRIER(sc, WB_SIO, 4,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
- return;
+ return (val);
}
/*
- * Clock a series of bits through the MII.
+ * Write the MII serial port for the MII bit-bang module.
*/
static void
-wb_mii_send(sc, bits, cnt)
- struct wb_softc *sc;
- u_int32_t bits;
- int cnt;
-{
- int i;
-
- SIO_CLR(WB_SIO_MII_CLK);
-
- for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
- if (bits & i) {
- SIO_SET(WB_SIO_MII_DATAIN);
- } else {
- SIO_CLR(WB_SIO_MII_DATAIN);
- }
- DELAY(1);
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
- SIO_SET(WB_SIO_MII_CLK);
- }
-}
-
-/*
- * Read an PHY register through the MII.
- */
-static int
-wb_mii_readreg(sc, frame)
- struct wb_softc *sc;
- struct wb_mii_frame *frame;
-
+wb_mii_bitbang_write(device_t dev, uint32_t val)
{
- int i, ack;
-
- /*
- * Set up frame for RX.
- */
- frame->mii_stdelim = WB_MII_STARTDELIM;
- frame->mii_opcode = WB_MII_READOP;
- frame->mii_turnaround = 0;
- frame->mii_data = 0;
-
- CSR_WRITE_4(sc, WB_SIO, 0);
-
- /*
- * Turn on data xmit.
- */
- SIO_SET(WB_SIO_MII_DIR);
-
- wb_mii_sync(sc);
-
- /*
- * Send command/address info.
- */
- wb_mii_send(sc, frame->mii_stdelim, 2);
- wb_mii_send(sc, frame->mii_opcode, 2);
- wb_mii_send(sc, frame->mii_phyaddr, 5);
- wb_mii_send(sc, frame->mii_regaddr, 5);
-
- /* Idle bit */
- SIO_CLR((WB_SIO_MII_CLK|WB_SIO_MII_DATAIN));
- DELAY(1);
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
-
- /* Turn off xmit. */
- SIO_CLR(WB_SIO_MII_DIR);
- /* Check for ack */
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
- ack = CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT;
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
-
- /*
- * Now try reading data bits. If the ack failed, we still
- * need to clock through 16 cycles to keep the PHY(s) in sync.
- */
- if (ack) {
- for(i = 0; i < 16; i++) {
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
- }
- goto fail;
- }
-
- for (i = 0x8000; i; i >>= 1) {
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
- if (!ack) {
- if (CSR_READ_4(sc, WB_SIO) & WB_SIO_MII_DATAOUT)
- frame->mii_data |= i;
- DELAY(1);
- }
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
- }
-
-fail:
+ struct wb_softc *sc;
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
-
- if (ack)
- return(1);
- return(0);
-}
-
-/*
- * Write to a PHY register through the MII.
- */
-static int
-wb_mii_writereg(sc, frame)
- struct wb_softc *sc;
- struct wb_mii_frame *frame;
-
-{
-
- /*
- * Set up frame for TX.
- */
-
- frame->mii_stdelim = WB_MII_STARTDELIM;
- frame->mii_opcode = WB_MII_WRITEOP;
- frame->mii_turnaround = WB_MII_TURNAROUND;
-
- /*
- * Turn on data output.
- */
- SIO_SET(WB_SIO_MII_DIR);
-
- wb_mii_sync(sc);
-
- wb_mii_send(sc, frame->mii_stdelim, 2);
- wb_mii_send(sc, frame->mii_opcode, 2);
- wb_mii_send(sc, frame->mii_phyaddr, 5);
- wb_mii_send(sc, frame->mii_regaddr, 5);
- wb_mii_send(sc, frame->mii_turnaround, 2);
- wb_mii_send(sc, frame->mii_data, 16);
-
- /* Idle bit. */
- SIO_SET(WB_SIO_MII_CLK);
- DELAY(1);
- SIO_CLR(WB_SIO_MII_CLK);
- DELAY(1);
-
- /*
- * Turn off xmit.
- */
- SIO_CLR(WB_SIO_MII_DIR);
+ sc = device_get_softc(dev);
- return(0);
+ CSR_WRITE_4(sc, WB_SIO, val);
+ CSR_BARRIER(sc, WB_SIO, 4,
+ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
}
static int
@@ -525,18 +381,8 @@ wb_miibus_readreg(dev, phy, reg)
device_t dev;
int phy, reg;
{
- struct wb_softc *sc;
- struct wb_mii_frame frame;
-
- sc = device_get_softc(dev);
- bzero((char *)&frame, sizeof(frame));
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- wb_mii_readreg(sc, &frame);
-
- return(frame.mii_data);
+ return (mii_bitbang_readreg(dev, &wb_mii_bitbang_ops, phy, reg));
}
static int
@@ -544,18 +390,8 @@ wb_miibus_writereg(dev, phy, reg, data)
device_t dev;
int phy, reg, data;
{
- struct wb_softc *sc;
- struct wb_mii_frame frame;
- sc = device_get_softc(dev);
-
- bzero((char *)&frame, sizeof(frame));
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- frame.mii_data = data;
-
- wb_mii_writereg(sc, &frame);
+ mii_bitbang_writereg(dev, &wb_mii_bitbang_ops, phy, reg, data);
return(0);
}
@@ -570,8 +406,6 @@ wb_miibus_statchg(dev)
sc = device_get_softc(dev);
mii = device_get_softc(sc->wb_miibus);
wb_setcfg(sc, mii->mii_media_active);
-
- return;
}
/*
@@ -627,8 +461,6 @@ wb_setmulti(sc)
CSR_WRITE_4(sc, WB_MAR0, hashes[0]);
CSR_WRITE_4(sc, WB_MAR1, hashes[1]);
CSR_WRITE_4(sc, WB_NETCFG, rxfilt);
-
- return;
}
/*
@@ -671,8 +503,6 @@ wb_setcfg(sc, media)
if (restart)
WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON|WB_NETCFG_RX_ON);
-
- return;
}
static void
@@ -742,7 +572,7 @@ static int
wb_probe(dev)
device_t dev;
{
- struct wb_type *t;
+ const struct wb_type *t;
t = wb_devs;
@@ -1001,7 +831,7 @@ wb_bfree(buf, args)
void *buf;
void *args;
{
- return;
+
}
/*
@@ -1127,8 +957,6 @@ wb_rxeoc(sc)
WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_RX_ON);
if (CSR_READ_4(sc, WB_ISR) & WB_RXSTATE_SUSPEND)
CSR_WRITE_4(sc, WB_RXSTART, 0xFFFFFFFF);
-
- return;
}
/*
@@ -1185,8 +1013,6 @@ wb_txeof(sc)
sc->wb_cdata.wb_tx_head = cur_tx->wb_nextdesc;
}
-
- return;
}
/*
@@ -1212,8 +1038,6 @@ wb_txeoc(sc)
CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
}
}
-
- return;
}
static void
@@ -1300,8 +1124,6 @@ wb_intr(arg)
}
WB_UNLOCK(sc);
-
- return;
}
static void
@@ -1320,8 +1142,6 @@ wb_tick(xsc)
if (sc->wb_timer > 0 && --sc->wb_timer == 0)
wb_watchdog(sc);
callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc);
-
- return;
}
/*
@@ -1520,8 +1340,6 @@ wb_start_locked(ifp)
* Set a timeout in case the chip goes out to lunch.
*/
sc->wb_timer = 5;
-
- return;
}
static void
@@ -1647,8 +1465,6 @@ wb_init_locked(sc)
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc);
-
- return;
}
/*
@@ -1690,8 +1506,6 @@ wb_ifmedia_sts(ifp, ifmr)
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
WB_UNLOCK(sc);
-
- return;
}
static int
@@ -1757,8 +1571,6 @@ wb_watchdog(sc)
if (ifp->if_snd.ifq_head != NULL)
wb_start_locked(ifp);
-
- return;
}
/*
@@ -1809,8 +1621,6 @@ wb_stop(sc)
sizeof(sc->wb_ldata->wb_tx_list));
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
- return;
}
/*
diff --git a/sys/dev/wb/if_wbreg.h b/sys/dev/wb/if_wbreg.h
index 95d0a8e..16eb8a1 100644
--- a/sys/dev/wb/if_wbreg.h
+++ b/sys/dev/wb/if_wbreg.h
@@ -341,26 +341,9 @@ struct wb_chain_data {
struct wb_type {
u_int16_t wb_vid;
u_int16_t wb_did;
- char *wb_name;
+ const char *wb_name;
};
-struct wb_mii_frame {
- u_int8_t mii_stdelim;
- u_int8_t mii_opcode;
- u_int8_t mii_phyaddr;
- u_int8_t mii_regaddr;
- u_int8_t mii_turnaround;
- u_int16_t mii_data;
-};
-
-/*
- * MII constants
- */
-#define WB_MII_STARTDELIM 0x01
-#define WB_MII_READOP 0x02
-#define WB_MII_WRITEOP 0x01
-#define WB_MII_TURNAROUND 0x02
-
struct wb_softc {
struct ifnet *wb_ifp; /* interface info */
device_t wb_dev;
@@ -395,6 +378,9 @@ struct wb_softc {
#define CSR_READ_2(sc, reg) bus_read_2(sc->wb_res, reg)
#define CSR_READ_1(sc, reg) bus_read_1(sc->wb_res, reg)
+#define CSR_BARRIER(sc, reg, length, flags) \
+ bus_barrier(sc->wb_res, reg, length, flags)
+
#define WB_TIMEOUT 1000
/*
diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c
index e09e434..b774e7f 100644
--- a/sys/dev/xl/if_xl.c
+++ b/sys/dev/xl/if_xl.c
@@ -127,6 +127,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <dev/mii/mii.h>
+#include <dev/mii/mii_bitbang.h>
#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
@@ -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 ifmediareq *);
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, 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.
- */
-static void
-xl_mii_sync(struct xl_softc *sc)
-{
- register int i;
-
- XL_SEL_WIN(4);
- MII_SET(XL_MII_DIR|XL_MII_DATA);
-
- 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);
- }
-}
/*
- * Clock a series of bits through the MII.
+ * Read 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)
+static uint32_t
+xl_mii_bitbang_read(device_t dev)
{
- int i;
-
- XL_SEL_WIN(4);
- MII_CLR(XL_MII_CLK);
-
- 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);
- }
-}
-
-/*
- * 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;
- }
+ struct xl_softc *sc;
+ uint32_t val;
- 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);
- }
+ sc = device_get_softc(dev);
-fail:
- MII_CLR(XL_MII_CLK);
- MII_SET(XL_MII_CLK);
+ /* 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 (ack ? 1 : 0);
+ return (val);
}
/*
- * Write to a PHY register through the MII.
+ * Write the MII serial port for the MII bit-bang module.
*/
-static int
-xl_mii_writereg(struct xl_softc *sc, struct xl_mii_frame *frame)
+static void
+xl_mii_bitbang_write(device_t dev, uint32_t val)
{
+ struct xl_softc *sc;
- /* 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);
+ sc = device_get_softc(dev);
- return (0);
+ /* 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);
}
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;
-
- xl_mii_readreg(sc, &frame);
+ /* Select the window 4. */
+ XL_SEL_WIN(4);
- 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);
}
diff --git a/sys/dev/xl/if_xlreg.h b/sys/dev/xl/if_xlreg.h
index f5494f5..b27e038 100644
--- a/sys/dev/xl/if_xlreg.h
+++ b/sys/dev/xl/if_xlreg.h
@@ -556,27 +556,10 @@ struct xl_chain_data {
struct xl_type {
u_int16_t xl_vid;
u_int16_t xl_did;
- 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;
+ const char *xl_name;
};
/*
- * 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
/*
OpenPOWER on IntegriCloud