Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 6 Nov 2011 21:09:24 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r227278 - in stable/8/sys: arm/conf conf dev/bm dev/dc dev/mii dev/nge dev/sis dev/smc dev/ste dev/stge dev/tl dev/wb dev/xl modules/mii pci
Message-ID:  <201111062109.pA6L9OLV042060@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Sun Nov  6 21:09:23 2011
New Revision: 227278
URL: http://svn.freebsd.org/changeset/base/227278

Log:
  MFC: r226995, r227042
  
  - 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 8k. The only potential in-tree users left
    unconverted are ed(4) and xe(4). Xe(4) 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 it
    just for the MII bitbang'ing code. Ed(4) has some chip specific things
    interwinded with the MII bitbang'ing code and it's unclear whether it can
    be converted to common code, at least not without thorough testing of all
    the various chips supported by ed(4).
    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)

Added:
  stable/8/sys/dev/mii/mii_bitbang.c
     - copied unchanged from r226995, head/sys/dev/mii/mii_bitbang.c
  stable/8/sys/dev/mii/mii_bitbang.h
     - copied unchanged from r226995, head/sys/dev/mii/mii_bitbang.h
Modified:
  stable/8/sys/arm/conf/GUMSTIX
  stable/8/sys/conf/NOTES
  stable/8/sys/conf/files
  stable/8/sys/dev/bm/if_bm.c
  stable/8/sys/dev/bm/if_bmreg.h
  stable/8/sys/dev/bm/if_bmvar.h
  stable/8/sys/dev/dc/if_dc.c
  stable/8/sys/dev/dc/if_dcreg.h
  stable/8/sys/dev/nge/if_nge.c
  stable/8/sys/dev/nge/if_ngereg.h
  stable/8/sys/dev/sis/if_sis.c
  stable/8/sys/dev/sis/if_sisreg.h
  stable/8/sys/dev/smc/if_smc.c
  stable/8/sys/dev/ste/if_ste.c
  stable/8/sys/dev/ste/if_stereg.h
  stable/8/sys/dev/stge/if_stge.c
  stable/8/sys/dev/stge/if_stgereg.h
  stable/8/sys/dev/tl/if_tl.c
  stable/8/sys/dev/tl/if_tlreg.h
  stable/8/sys/dev/wb/if_wb.c
  stable/8/sys/dev/wb/if_wbreg.h
  stable/8/sys/dev/xl/if_xl.c
  stable/8/sys/dev/xl/if_xlreg.h
  stable/8/sys/modules/mii/Makefile
  stable/8/sys/pci/if_rl.c
  stable/8/sys/pci/if_rlreg.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/arm/conf/GUMSTIX
==============================================================================
--- stable/8/sys/arm/conf/GUMSTIX	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/arm/conf/GUMSTIX	Sun Nov  6 21:09:23 2011	(r227278)
@@ -72,6 +72,7 @@ options 	PREEMPTION
 device		loop
 device		ether
 device		mii
+device		mii_bitbang
 device		smc
 device		smcphy
 device		uart

Modified: stable/8/sys/conf/NOTES
==============================================================================
--- stable/8/sys/conf/NOTES	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/conf/NOTES	Sun Nov  6 21:09:23 2011	(r227278)
@@ -1819,13 +1819,15 @@ device		puc
 # MII bus support is required for many PCI Ethernet NICs,
 # namely those which use MII-compliant transceivers or implement
 # transceiver control interfaces that operate like an MII.  Adding
-# "device miibus" to the kernel config pulls in support for
-# the generic miibus API and all of the PHY drivers, including a
-# generic one for PHYs that aren't specifically handled by an
-# individual driver.  Support for specific PHYs may be built by adding
-# "device mii" then adding the appropriate PHY driver.
-device  	miibus		# MII support including all PHYs
+# "device miibus" to the kernel config pulls in support for the generic
+# miibus API, the common support for for bit-bang'ing the MII and all
+# of the PHY drivers, including a generic one for PHYs that aren't
+# specifically handled by an individual driver.  Support for specific
+# PHYs may be built by adding "device mii", "device mii_bitbang" if
+# needed by the NIC driver and then adding the appropriate PHY driver.
 device  	mii		# Minimal MII support
+device  	mii_bitbang	# Common module for bit-bang'ing the MII
+device  	miibus		# MII support w/ bit-bang'ing and all PHYs
 
 device  	acphy		# Altima Communications AC101
 device  	amphy		# AMD AM79c873 / Davicom DM910{1,2}

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/conf/files	Sun Nov  6 21:09:23 2011	(r227278)
@@ -1309,6 +1309,7 @@ dev/mii/ip1000phy.c		optional miibus | i
 dev/mii/jmphy.c			optional miibus | jmphy
 dev/mii/lxtphy.c		optional miibus | lxtphy
 dev/mii/mii.c			optional miibus | mii
+dev/mii/mii_bitbang.c		optional miibus | mii_bitbang
 dev/mii/mii_physubr.c		optional miibus | mii
 dev/mii/miibus_if.m		optional miibus | mii
 dev/mii/mlphy.c			optional miibus | mlphy

Modified: stable/8/sys/dev/bm/if_bm.c
==============================================================================
--- stable/8/sys/dev/bm/if_bm.c	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/dev/bm/if_bm.c	Sun Nov  6 21:09:23 2011	(r227278)
@@ -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,
  */
 
 /*
- * Write to the MII csr, introducing a delay to allow valid
- * MII clock pulses to be formed
- */
-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.
+ * Write the MII serial port for the MII bit-bang module.
  */
 static void
-bm_mii_sync(struct bm_softc *sc)
+bm_mii_bitbang_write(device_t dev, uint32_t val)
 {
-	int i;
-	u_int16_t regval;
-
-	regval = BM_MII_OENABLE | BM_MII_DATAOUT;
-
-	bm_miicsr_dwrite(sc, regval);
-	for (i = 0; i < 32; i++) {
-		bm_miicsr_dwrite(sc, regval | BM_MII_CLK);
-		bm_miicsr_dwrite(sc, regval);
-	}
-}
-
-/*
- * Clock a series of bits through the MII.
- */
-static void
-bm_mii_send(struct bm_softc *sc, u_int32_t bits, int cnt)
-{
-	int i;
-
-	for (i = (0x1 << (cnt - 1)); i; i >>= 1)
-		bm_mii_writebit(sc, bits & i);
-}
-
-/*
- * Read a PHY register through the MII.
- */
-static int
-bm_mii_readreg(struct bm_softc *sc, struct bm_mii_frame *frame)
-{
-	int i, ack, bit;
-
-	/*
-	 * Set up frame for RX.
-	 */
-	frame->mii_stdelim = BM_MII_STARTDELIM;
-	frame->mii_opcode = BM_MII_READOP;
-	frame->mii_turnaround = 0;
-	frame->mii_data = 0;
-
-	/*
-	 * Sync the PHYs
-	 */
-	bm_mii_sync(sc);
-
-	/*
-	 * Send command/address info
-	 */
-	bm_mii_send(sc, frame->mii_stdelim, 2);
-	bm_mii_send(sc, frame->mii_opcode, 2);
-	bm_mii_send(sc, frame->mii_phyaddr, 5);
-	bm_mii_send(sc, frame->mii_regaddr, 5);
-
-	/*
-	 * Check for ack.
-	 */
-	ack = bm_mii_readbit(sc);
-
-	/*
-	 * Now try reading data bits. If the ack failed, we still
-	 * need to clock through 16 cycles to keep the PHY(s) in sync.
-	 */
-	for (i = 0x8000; i; i >>= 1) {
-		bit = bm_mii_readbit(sc);
-		if (!ack && bit)
-			frame->mii_data |= i;
-	}
+	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, str
 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);
 }

Modified: stable/8/sys/dev/bm/if_bmreg.h
==============================================================================
--- stable/8/sys/dev/bm/if_bmreg.h	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/dev/bm/if_bmreg.h	Sun Nov  6 21:09:23 2011	(r227278)
@@ -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)

Modified: stable/8/sys/dev/bm/if_bmvar.h
==============================================================================
--- stable/8/sys/dev/bm/if_bmvar.h	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/dev/bm/if_bmvar.h	Sun Nov  6 21:09:23 2011	(r227278)
@@ -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;
-};
-

Modified: stable/8/sys/dev/dc/if_dc.c
==============================================================================
--- stable/8/sys/dev/dc/if_dc.c	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/dev/dc/if_dc.c	Sun Nov  6 21:09:23 2011	(r227278)
@@ -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,
@@ -267,12 +268,6 @@ static void dc_eeprom_getword_xircom(str
 static void dc_eeprom_width(struct dc_softc *);
 static void dc_read_eeprom(struct dc_softc *, caddr_t, int, int, int);
 
-static void dc_mii_writebit(struct dc_softc *, int);
-static int dc_mii_readbit(struct dc_softc *);
-static void dc_mii_sync(struct dc_softc *);
-static void dc_mii_send(struct dc_softc *, uint32_t, int);
-static int dc_mii_readreg(struct dc_softc *, struct dc_mii_frame *);
-static int dc_mii_writereg(struct dc_softc *, struct dc_mii_frame *);
 static int dc_miibus_readreg(device_t, int, int);
 static int dc_miibus_writereg(device_t, int, int, int);
 static void dc_miibus_statchg(device_t);
@@ -301,6 +296,24 @@ static int dc_decode_leaf_sym(struct dc_
 static void dc_apply_fixup(struct dc_softc *, int);
 static int dc_check_multiport(struct dc_softc *);
 
+/*
+ * MII bit-bang glue
+ */
+static uint32_t dc_mii_bitbang_read(device_t);
+static void dc_mii_bitbang_write(device_t, uint32_t);
+
+static const struct mii_bitbang_ops dc_mii_bitbang_ops = {
+	dc_mii_bitbang_read,
+	dc_mii_bitbang_write,
+	{
+		DC_SIO_MII_DATAOUT,	/* MII_BIT_MDO */
+		DC_SIO_MII_DATAIN,	/* MII_BIT_MDI */
+		DC_SIO_MII_CLK,		/* MII_BIT_MDC */
+		0,			/* MII_BIT_DIR_HOST_PHY */
+		DC_SIO_MII_DIR,		/* MII_BIT_DIR_PHY_HOST */
+	}
+};
+
 #ifdef DC_USEIOSPACE
 #define	DC_RES			SYS_RES_IOPORT
 #define	DC_RID			DC_PCI_CFBIO
@@ -605,185 +618,45 @@ dc_read_eeprom(struct dc_softc *sc, cadd
 }
 
 /*
- * 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_BARRIER_4(sc, DC_SIO,
-	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
-	DELAY(1);
-	CSR_WRITE_4(sc, DC_SIO, reg);
+	CSR_WRITE_4(sc, DC_SIO, val);
 	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)) {
@@ -858,34 +731,29 @@ dc_miibus_readreg(device_t dev, int phy,
 		}
 
 		rval = CSR_READ_4(sc, phy_reg) & 0x0000FFFF;
-
 		if (rval == 0xFFFF)
 			return (0);
 		return (rval);
 	}
 
-	frame.mii_phyaddr = phy;
-	frame.mii_regaddr = reg;
 	if (sc->dc_type == DC_TYPE_98713) {
 		phy_reg = CSR_READ_4(sc, DC_NETCFG);
 		CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL);
 	}
-	dc_mii_readreg(sc, &frame);
+	rval = mii_bitbang_readreg(dev, &dc_mii_bitbang_ops, phy, reg);
 	if (sc->dc_type == DC_TYPE_98713)
 		CSR_WRITE_4(sc, DC_NETCFG, phy_reg);
 
-	return (frame.mii_data);
+	return (rval);
 }
 
 static int
 dc_miibus_writereg(device_t dev, int phy, int reg, int data)
 {
 	struct dc_softc *sc;
-	struct dc_mii_frame frame;
 	int i, phy_reg = 0;
 
 	sc = device_get_softc(dev);
-	bzero(&frame, sizeof(frame));
 
 	if (DC_IS_PNIC(sc)) {
 		CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE |
@@ -931,15 +799,11 @@ dc_miibus_writereg(device_t dev, int phy
 		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);
 

Modified: stable/8/sys/dev/dc/if_dcreg.h
==============================================================================
--- stable/8/sys/dev/dc/if_dcreg.h	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/dev/dc/if_dcreg.h	Sun Nov  6 21:09:23 2011	(r227278)
@@ -525,27 +525,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
@@ -804,7 +786,7 @@ struct dc_softc {
 #define	CSR_READ_4(sc, reg)		\
 	bus_space_read_4(sc->dc_btag, sc->dc_bhandle, reg)
 
-#define	CSR_BARRIER_4(sc, reg, flags)		\
+#define	CSR_BARRIER_4(sc, reg, flags)					\
 	bus_space_barrier(sc->dc_btag, sc->dc_bhandle, reg, 4, flags)
 
 #define	DC_TIMEOUT		1000

Copied: stable/8/sys/dev/mii/mii_bitbang.c (from r226995, head/sys/dev/mii/mii_bitbang.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/8/sys/dev/mii/mii_bitbang.c	Sun Nov  6 21:09:23 2011	(r227278, copy of r226995, head/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);
+}

Copied: stable/8/sys/dev/mii/mii_bitbang.h (from r226995, head/sys/dev/mii/mii_bitbang.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/8/sys/dev/mii/mii_bitbang.h	Sun Nov  6 21:09:23 2011	(r227278, copy of r226995, head/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);

Modified: stable/8/sys/dev/nge/if_nge.c
==============================================================================
--- stable/8/sys/dev/nge/if_nge.c	Sun Nov  6 21:09:10 2011	(r227277)
+++ stable/8/sys/dev/nge/if_nge.c	Sun Nov  6 21:09:23 2011	(r227278)
@@ -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 ng
 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_s
 static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
 static int sysctl_hw_nge_int_holdoff(SYSCTL_HANDLER_ARGS);
 
+/*
+ * MII bit-bang glue
+ */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111062109.pA6L9OLV042060>