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