summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>1999-11-19 02:29:28 +0000
committerJason Wright <jason@cvs.openbsd.org>1999-11-19 02:29:28 +0000
commit3a826c7171cff9617c956aa116999de7c4e990d7 (patch)
tree14f77354d9ec583e478652b9cc18ed2f7f875e5c
parent59a5216e2683325a1d92ac903e6cd3ff1ccabe9d (diff)
use bus_dma*
merge with freebsd: use dev/mii layer do a more full reset in wb_reset()
-rw-r--r--sys/dev/pci/if_wb.c729
-rw-r--r--sys/dev/pci/if_wbreg.h159
2 files changed, 236 insertions, 652 deletions
diff --git a/sys/dev/pci/if_wb.c b/sys/dev/pci/if_wb.c
index 85af4a07367..a18e161ccb8 100644
--- a/sys/dev/pci/if_wb.c
+++ b/sys/dev/pci/if_wb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wb.c,v 1.3 1999/09/27 18:17:01 jason Exp $ */
+/* $OpenBSD: if_wb.c,v 1.4 1999/11/19 02:29:27 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -31,7 +31,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: if_wb.c,v 1.13 1999/07/11 00:56:07 wpaul Exp $
+ * $FreeBSD: src/sys/pci/if_wb.c,v 1.26 1999/09/25 17:29:02 wpaul Exp $
*/
/*
@@ -95,6 +95,7 @@
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/device.h>
+#include <sys/queue.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -119,6 +120,8 @@
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
@@ -129,25 +132,10 @@
#include <dev/pci/if_wbreg.h>
-/*
- * Various supported PHY vendors/types and their names. Note that
- * this driver will work with pretty much any MII-compliant PHY,
- * so failure to positively identify the chip is not a fatal error.
- */
-
-struct wb_type wb_phys[] = {
- { TI_PHY_VENDORID, TI_PHY_10BT, "<TI ThunderLAN 10BT (internal)>" },
- { TI_PHY_VENDORID, TI_PHY_100VGPMI, "<TI TNETE211 100VG Any-LAN>" },
- { NS_PHY_VENDORID, NS_PHY_83840A, "<National Semiconductor DP83840A>"},
- { LEVEL1_PHY_VENDORID, LEVEL1_PHY_LXT970, "<Level 1 LXT970>" },
- { INTEL_PHY_VENDORID, INTEL_PHY_82555, "<Intel 82555>" },
- { SEEQ_PHY_VENDORID, SEEQ_PHY_80220, "<SEEQ 80220>" },
- { 0, 0, "<MII-compliant physical interface>" }
-};
-
int wb_probe __P((struct device *, void *, void *));
void wb_attach __P((struct device *, struct device *, void *));
+void wb_bfree __P((struct mbuf *));
int wb_newbuf __P((struct wb_softc *, struct wb_chain_onefrag *,
struct mbuf *));
int wb_encap __P((struct wb_softc *, struct wb_chain *,
@@ -158,6 +146,7 @@ void wb_rxeoc __P((struct wb_softc *));
void wb_txeof __P((struct wb_softc *));
void wb_txeoc __P((struct wb_softc *));
int wb_intr __P((void *));
+void wb_tick __P((void *));
void wb_start __P((struct ifnet *));
int wb_ioctl __P((struct ifnet *, u_long, caddr_t));
void wb_init __P((void *));
@@ -174,20 +163,19 @@ void wb_mii_sync __P((struct wb_softc *));
void wb_mii_send __P((struct wb_softc *, u_int32_t, int));
int wb_mii_readreg __P((struct wb_softc *, struct wb_mii_frame *));
int wb_mii_writereg __P((struct wb_softc *, struct wb_mii_frame *));
-void wb_phy_writereg __P((struct wb_softc *, int, int));
-u_int16_t wb_phy_readreg __P((struct wb_softc *, int));
-
-void wb_autoneg_xmit __P((struct wb_softc *));
-void wb_autoneg_mii __P((struct wb_softc *, int, int));
-void wb_setmode_mii __P((struct wb_softc *, int));
-void wb_getmode_mii __P((struct wb_softc *));
-void wb_setcfg __P((struct wb_softc *, int));
+
+void wb_setcfg __P((struct wb_softc *, u_int32_t));
u_int8_t wb_calchash __P((caddr_t));
void wb_setmulti __P((struct wb_softc *));
void wb_reset __P((struct wb_softc *));
+void wb_fixmedia __P((struct wb_softc *));
int wb_list_rx_init __P((struct wb_softc *));
int wb_list_tx_init __P((struct wb_softc *));
+int wb_miibus_readreg __P((struct device *, int, int));
+void wb_miibus_writereg __P((struct device *, int, int, int));
+void wb_miibus_statchg __P((struct device *));
+
#define WB_SETBIT(sc, reg, x) \
CSR_WRITE_4(sc, reg, \
CSR_READ_4(sc, reg) | x)
@@ -490,31 +478,34 @@ int wb_mii_writereg(sc, frame)
return(0);
}
-u_int16_t wb_phy_readreg(sc, reg)
- struct wb_softc *sc;
- int reg;
+int
+wb_miibus_readreg(dev, phy, reg)
+ struct device *dev;
+ int phy, reg;
{
- struct wb_mii_frame frame;
+ struct wb_softc *sc = (struct wb_softc *)dev;
+ struct wb_mii_frame frame;
bzero((char *)&frame, sizeof(frame));
- frame.mii_phyaddr = sc->wb_phy_addr;
+ frame.mii_phyaddr = phy;
frame.mii_regaddr = reg;
wb_mii_readreg(sc, &frame);
return(frame.mii_data);
}
-void wb_phy_writereg(sc, reg, data)
- struct wb_softc *sc;
- int reg;
- int data;
+void
+wb_miibus_writereg(dev, phy, reg, data)
+ struct device *dev;
+ int phy, reg, data;
{
- struct wb_mii_frame frame;
+ struct wb_softc *sc = (struct wb_softc *)dev;
+ struct wb_mii_frame frame;
bzero((char *)&frame, sizeof(frame));
- frame.mii_phyaddr = sc->wb_phy_addr;
+ frame.mii_phyaddr = phy;
frame.mii_regaddr = reg;
frame.mii_data = data;
@@ -523,6 +514,15 @@ void wb_phy_writereg(sc, reg, data)
return;
}
+void
+wb_miibus_statchg(dev)
+ struct device *dev;
+{
+ struct wb_softc *sc = (struct wb_softc *)dev;
+
+ wb_setcfg(sc, sc->sc_mii.mii_media_active);
+}
+
u_int8_t wb_calchash(addr)
caddr_t addr;
{
@@ -610,302 +610,14 @@ void wb_setmulti(sc)
}
/*
- * Initiate an autonegotiation session.
- */
-void wb_autoneg_xmit(sc)
- struct wb_softc *sc;
-{
- u_int16_t phy_sts;
-
- wb_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
- DELAY(500);
- while(wb_phy_readreg(sc, PHY_BMCR)
- & PHY_BMCR_RESET);
-
- phy_sts = wb_phy_readreg(sc, PHY_BMCR);
- phy_sts |= PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR;
- wb_phy_writereg(sc, PHY_BMCR, phy_sts);
-
- return;
-}
-
-/*
- * Invoke autonegotiation on a PHY.
- */
-void wb_autoneg_mii(sc, flag, verbose)
- struct wb_softc *sc;
- int flag;
- int verbose;
-{
- u_int16_t phy_sts = 0, media, advert, ability;
- struct ifnet *ifp;
- struct ifmedia *ifm;
-
- ifm = &sc->ifmedia;
- ifp = &sc->arpcom.ac_if;
-
- ifm->ifm_media = IFM_ETHER | IFM_AUTO;
-
- /*
- * The 100baseT4 PHY on the 3c905-T4 has the 'autoneg supported'
- * bit cleared in the status register, but has the 'autoneg enabled'
- * bit set in the control register. This is a contradiction, and
- * I'm not sure how to handle it. If you want to force an attempt
- * to autoneg for 100baseT4 PHYs, #define FORCE_AUTONEG_TFOUR
- * and see what happens.
- */
-#ifndef FORCE_AUTONEG_TFOUR
- /*
- * First, see if autoneg is supported. If not, there's
- * no point in continuing.
- */
- phy_sts = wb_phy_readreg(sc, PHY_BMSR);
- if (!(phy_sts & PHY_BMSR_CANAUTONEG)) {
- if (verbose)
- printf("%s: autonegotiation not supported\n",
- sc->sc_dev.dv_xname);
- ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
- return;
- }
-#endif
-
- switch (flag) {
- case WB_FLAG_FORCEDELAY:
- /*
- * XXX Never use this option anywhere but in the probe
- * routine: making the kernel stop dead in its tracks
- * for three whole seconds after we've gone multi-user
- * is really bad manners.
- */
- wb_autoneg_xmit(sc);
- DELAY(5000000);
- break;
- case WB_FLAG_SCHEDDELAY:
- /*
- * Wait for the transmitter to go idle before starting
- * an autoneg session, otherwise wb_start() may clobber
- * our timeout, and we don't want to allow transmission
- * during an autoneg session since that can screw it up.
- */
- if (sc->wb_cdata.wb_tx_head != NULL) {
- sc->wb_want_auto = 1;
- return;
- }
- wb_autoneg_xmit(sc);
- ifp->if_timer = 5;
- sc->wb_autoneg = 1;
- sc->wb_want_auto = 0;
- return;
- break;
- case WB_FLAG_DELAYTIMEO:
- ifp->if_timer = 0;
- sc->wb_autoneg = 0;
- break;
- default:
- printf("%s: invalid autoneg flag: %d\n",
- sc->sc_dev.dv_xname, flag);
- return;
- }
-
- if (wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_AUTONEGCOMP) {
- if (verbose)
- printf("%s: autoneg complete, ", sc->sc_dev.dv_xname);
- phy_sts = wb_phy_readreg(sc, PHY_BMSR);
- } else {
- if (verbose)
- printf("%s: autoneg not complete, ",
- sc->sc_dev.dv_xname);
- }
-
- media = wb_phy_readreg(sc, PHY_BMCR);
-
- /* Link is good. Report modes and set duplex mode. */
- if (wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT) {
- if (verbose)
- printf("link status good ");
- advert = wb_phy_readreg(sc, PHY_ANAR);
- ability = wb_phy_readreg(sc, PHY_LPAR);
-
- if (advert & PHY_ANAR_100BT4 && ability & PHY_ANAR_100BT4) {
- ifm->ifm_media = IFM_ETHER|IFM_100_T4;
- media |= PHY_BMCR_SPEEDSEL;
- media &= ~PHY_BMCR_DUPLEX;
- printf("(100baseT4)\n");
- } else if (advert & PHY_ANAR_100BTXFULL &&
- ability & PHY_ANAR_100BTXFULL) {
- ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX;
- media |= PHY_BMCR_SPEEDSEL;
- media |= PHY_BMCR_DUPLEX;
- printf("(full-duplex, 100Mbps)\n");
- } else if (advert & PHY_ANAR_100BTXHALF &&
- ability & PHY_ANAR_100BTXHALF) {
- ifm->ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX;
- media |= PHY_BMCR_SPEEDSEL;
- media &= ~PHY_BMCR_DUPLEX;
- printf("(half-duplex, 100Mbps)\n");
- } else if (advert & PHY_ANAR_10BTFULL &&
- ability & PHY_ANAR_10BTFULL) {
- ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX;
- media &= ~PHY_BMCR_SPEEDSEL;
- media |= PHY_BMCR_DUPLEX;
- printf("(full-duplex, 10Mbps)\n");
- } else /* if (advert & PHY_ANAR_10BTHALF &&
- ability & PHY_ANAR_10BTHALF) */ {
- ifm->ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
- media &= ~PHY_BMCR_SPEEDSEL;
- media &= ~PHY_BMCR_DUPLEX;
- printf("(half-duplex, 10Mbps)\n");
- }
-
- media &= ~PHY_BMCR_AUTONEGENBL;
-
- /* Set ASIC's duplex mode to match the PHY. */
- wb_setcfg(sc, media);
- wb_phy_writereg(sc, PHY_BMCR, media);
- } else {
- if (verbose)
- printf("no carrier\n");
- }
-
- if (flag != WB_FLAG_FORCEDELAY)
- wb_init(sc);
-
- if (sc->wb_tx_pend) {
- sc->wb_autoneg = 0;
- sc->wb_tx_pend = 0;
- wb_start(ifp);
- }
-
- return;
-}
-
-void wb_getmode_mii(sc)
- struct wb_softc *sc;
-{
- u_int16_t bmsr;
- struct ifnet *ifp;
-
- ifp = &sc->arpcom.ac_if;
-
- bmsr = wb_phy_readreg(sc, PHY_BMSR);
-
- /* fallback */
- sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_HDX;
-
- if (bmsr & PHY_BMSR_10BTHALF) {
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
- }
-
- if (bmsr & PHY_BMSR_10BTFULL) {
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
- sc->ifmedia.ifm_media = IFM_ETHER|IFM_10_T|IFM_FDX;
- }
-
- if (bmsr & PHY_BMSR_100BTXHALF) {
- ifp->if_baudrate = 100000000;
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_TX, 0, NULL);
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_100_TX|IFM_HDX, 0, NULL);
- sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_HDX;
- }
-
- if (bmsr & PHY_BMSR_100BTXFULL) {
- ifp->if_baudrate = 100000000;
- ifmedia_add(&sc->ifmedia,
- IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
- sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_TX|IFM_FDX;
- }
-
- /* Some also support 100BaseT4. */
- if (bmsr & PHY_BMSR_100BT4) {
- ifp->if_baudrate = 100000000;
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_T4, 0, NULL);
- sc->ifmedia.ifm_media = IFM_ETHER|IFM_100_T4;
-#ifdef FORCE_AUTONEG_TFOUR
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0 NULL):
- sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO;
-#endif
- }
-
- if (bmsr & PHY_BMSR_CANAUTONEG) {
- ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
- sc->ifmedia.ifm_media = IFM_ETHER|IFM_AUTO;
- }
-
- return;
-}
-
-/*
- * Set speed and duplex mode.
- */
-void wb_setmode_mii(sc, media)
- struct wb_softc *sc;
- int media;
-{
- u_int16_t bmcr;
- struct ifnet *ifp;
-
- ifp = &sc->arpcom.ac_if;
-
- /*
- * If an autoneg session is in progress, stop it.
- */
- if (sc->wb_autoneg) {
- printf("%s: canceling autoneg session\n", sc->sc_dev.dv_xname);
- ifp->if_timer = sc->wb_autoneg = sc->wb_want_auto = 0;
- bmcr = wb_phy_readreg(sc, PHY_BMCR);
- bmcr &= ~PHY_BMCR_AUTONEGENBL;
- wb_phy_writereg(sc, PHY_BMCR, bmcr);
- }
-
- printf("%s: selecting MII, ", sc->sc_dev.dv_xname);
-
- bmcr = wb_phy_readreg(sc, PHY_BMCR);
-
- bmcr &= ~(PHY_BMCR_AUTONEGENBL|PHY_BMCR_SPEEDSEL|
- PHY_BMCR_DUPLEX|PHY_BMCR_LOOPBK);
-
- if (IFM_SUBTYPE(media) == IFM_100_T4) {
- printf("100Mbps/T4, half-duplex\n");
- bmcr |= PHY_BMCR_SPEEDSEL;
- bmcr &= ~PHY_BMCR_DUPLEX;
- }
-
- if (IFM_SUBTYPE(media) == IFM_100_TX) {
- printf("100Mbps, ");
- bmcr |= PHY_BMCR_SPEEDSEL;
- }
-
- if (IFM_SUBTYPE(media) == IFM_10_T) {
- printf("10Mbps, ");
- bmcr &= ~PHY_BMCR_SPEEDSEL;
- }
-
- if ((media & IFM_GMASK) == IFM_FDX) {
- printf("full duplex\n");
- bmcr |= PHY_BMCR_DUPLEX;
- } else {
- printf("half duplex\n");
- bmcr &= ~PHY_BMCR_DUPLEX;
- }
-
- wb_setcfg(sc, bmcr);
- wb_phy_writereg(sc, PHY_BMCR, bmcr);
-
- return;
-}
-
-/*
* The Winbond manual states that in order to fiddle with the
* 'full-duplex' and '100Mbps' bits in the netconfig register, we
* first have to put the transmit and/or receive logic in the idle state.
*/
-void wb_setcfg(sc, bmcr)
- struct wb_softc *sc;
- int bmcr;
+void
+wb_setcfg(sc, media)
+ struct wb_softc *sc;
+ u_int32_t media;
{
int i, restart = 0;
@@ -925,12 +637,12 @@ void wb_setcfg(sc, bmcr)
"rx to idle state\n", sc->sc_dev.dv_xname);
}
- if (bmcr & PHY_BMCR_SPEEDSEL)
- WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_100MBPS);
- else
+ if (IFM_SUBTYPE(media) == IFM_10_T)
WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_100MBPS);
+ else
+ WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_100MBPS);
- if (bmcr & PHY_BMCR_DUPLEX)
+ if ((media & IFM_GMASK) == IFM_FDX)
WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_FULLDUPLEX);
else
WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_FULLDUPLEX);
@@ -941,11 +653,19 @@ void wb_setcfg(sc, bmcr)
return;
}
-void wb_reset(sc)
- struct wb_softc *sc;
+void
+wb_reset(sc)
+ struct wb_softc *sc;
{
- register int i;
+ register int i;
+ struct mii_data *mii = &sc->sc_mii;
+ CSR_WRITE_4(sc, WB_NETCFG, 0);
+ CSR_WRITE_4(sc, WB_BUSCTL, 0);
+ CSR_WRITE_4(sc, WB_TXADDR, 0);
+ CSR_WRITE_4(sc, WB_RXADDR, 0);
+
+ WB_SETBIT(sc, WB_BUSCTL, WB_BUSCTL_RESET);
WB_SETBIT(sc, WB_BUSCTL, WB_BUSCTL_RESET);
for (i = 0; i < WB_TIMEOUT; i++) {
@@ -959,11 +679,35 @@ void wb_reset(sc)
/* Wait a little while for the chip to get its brains in order. */
DELAY(1000);
- /* Reset the damn PHY too. */
- if (sc->wb_pinfo != NULL)
- wb_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
+ if (mii->mii_instance) {
+ struct mii_softc *miisc;
+ for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
+ miisc = LIST_NEXT(miisc, mii_list))
+ mii_phy_reset(miisc);
+ }
+}
+
+void
+wb_fixmedia(sc)
+ struct wb_softc *sc;
+{
+ struct mii_data *mii = &sc->sc_mii;
+ u_int32_t media;
+
+ if (LIST_FIRST(&mii->mii_phys) == NULL)
+ return;
+
+ mii_pollstat(mii);
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T) {
+ media = mii->mii_media_active & ~IFM_10_T;
+ media |= IFM_100_TX;
+ } if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
+ media = mii->mii_media_active & ~IFM_100_TX;
+ media |= IFM_10_T;
+ } else
+ return;
- return;
+ ifmedia_set(&mii->mii_media, media);
}
/*
@@ -1011,12 +755,11 @@ wb_attach(parent, self, aux)
struct ifnet *ifp = &sc->arpcom.ac_if;
bus_addr_t iobase;
bus_size_t iosize;
- int i, media = IFM_ETHER|IFM_100_TX|IFM_FDX, s;
- u_int round;
- caddr_t roundptr;
- u_int16_t phy_vid, phy_did, phy_sts;
- struct wb_type *p;
+ int s, rseg;
u_int32_t command;
+ bus_dma_segment_t seg;
+ bus_dmamap_t dmamap;
+ caddr_t kva;
s = splimp();
@@ -1108,6 +851,8 @@ wb_attach(parent, self, aux)
}
printf(": %s", intrstr);
+ sc->wb_cachesize = pci_conf_read(pc, pa->pa_tag, WB_PCI_CACHELEN)&0xff;
+
/* Reset the adapter. */
wb_reset(sc);
@@ -1117,29 +862,36 @@ wb_attach(parent, self, aux)
wb_read_eeprom(sc, (caddr_t)&sc->arpcom.ac_enaddr, 0, 3, 0);
printf(" address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
- sc->wb_ldata_ptr = malloc(sizeof(struct wb_list_data) + 8,
- M_DEVBUF, M_NOWAIT);
- if (sc->wb_ldata_ptr == NULL) {
- printf("%s: no memory for list buffers!\n",sc->sc_dev.dv_xname);
+ if (bus_dmamem_alloc(pa->pa_dmat, sizeof(struct wb_list_data),
+ PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
+ printf("%s: can't alloc list data\n", sc->sc_dev.dv_xname);
goto fail;
}
-
- sc->wb_ldata = (struct wb_list_data *)sc->wb_ldata_ptr;
-#ifdef __alpha__
- round = (u_int64_t)sc->wb_ldata_ptr & 0xF;
-#endif
-#ifdef __i386__
- round = (u_int32_t)sc->wb_ldata_ptr & 0xF;
-#endif
- roundptr = sc->wb_ldata_ptr;
- for (i = 0; i < 8; i++) {
- if (round % 8) {
- round++;
- roundptr++;
- } else
- break;
+ if (bus_dmamem_map(pa->pa_dmat, &seg, rseg,
+ sizeof(struct wb_list_data), &kva, BUS_DMA_NOWAIT)) {
+ printf("%s: can't map list data, size %d\n",
+ sc->sc_dev.dv_xname, sizeof(struct wb_list_data));
+ bus_dmamem_free(pa->pa_dmat, &seg, rseg);
+ goto fail;
+ }
+ if (bus_dmamap_create(pa->pa_dmat, sizeof(struct wb_list_data), 1,
+ sizeof(struct wb_list_data), 0, BUS_DMA_NOWAIT, &dmamap)) {
+ printf("%s: can't create dma map\n", sc->sc_dev.dv_xname);
+ bus_dmamem_unmap(pa->pa_dmat, kva,
+ sizeof(struct wb_list_data));
+ bus_dmamem_free(pa->pa_dmat, &seg, rseg);
+ goto fail;
}
- sc->wb_ldata = (struct wb_list_data *)roundptr;
+ if (bus_dmamap_load(pa->pa_dmat, dmamap, kva,
+ sizeof(struct wb_list_data), NULL, BUS_DMA_NOWAIT)) {
+ printf("%s: can't load dma map\n", sc->sc_dev.dv_xname);
+ bus_dmamap_destroy(pa->pa_dmat, dmamap);
+ bus_dmamem_unmap(pa->pa_dmat, kva,
+ sizeof(struct wb_list_data));
+ bus_dmamem_free(pa->pa_dmat, &seg, rseg);
+ goto fail;
+ }
+ sc->wb_ldata = (struct wb_list_data *)kva;
bzero(sc->wb_ldata, sizeof(struct wb_list_data));
ifp->if_softc = sc;
@@ -1153,45 +905,22 @@ wb_attach(parent, self, aux)
ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1;
bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
- for (i = WB_PHYADDR_MIN; i < WB_PHYADDR_MAX + 1; i++) {
- sc->wb_phy_addr = i;
- wb_phy_writereg(sc, PHY_BMCR, PHY_BMCR_RESET);
- DELAY(500);
- while(wb_phy_readreg(sc, PHY_BMCR)
- & PHY_BMCR_RESET);
- if ((phy_sts = wb_phy_readreg(sc, PHY_BMSR)))
- break;
- }
- if (phy_sts) {
- phy_vid = wb_phy_readreg(sc, PHY_VENID);
- phy_did = wb_phy_readreg(sc, PHY_DEVID);
- p = wb_phys;
- while(p->wb_vid) {
- if (phy_vid == p->wb_vid &&
- (phy_did | 0x000F) == p->wb_did) {
- sc->wb_pinfo = p;
- break;
- }
- p++;
- }
- if (sc->wb_pinfo == NULL)
- sc->wb_pinfo = &wb_phys[PHY_UNKNOWN];
- } else {
- printf("%s: MII without any phy!\n", sc->sc_dev.dv_xname);
- goto fail;
- }
-
/*
* Do ifmedia setup.
*/
- ifmedia_init(&sc->ifmedia, 0, wb_ifmedia_upd, wb_ifmedia_sts);
-
- wb_getmode_mii(sc);
- wb_autoneg_mii(sc, WB_FLAG_FORCEDELAY, 1);
- media = sc->ifmedia.ifm_media;
wb_stop(sc);
- ifmedia_set(&sc->ifmedia, media);
+ ifmedia_init(&sc->sc_mii.mii_media, 0, wb_ifmedia_upd, wb_ifmedia_sts);
+ sc->sc_mii.mii_ifp = ifp;
+ sc->sc_mii.mii_readreg = wb_miibus_readreg;
+ sc->sc_mii.mii_writereg = wb_miibus_writereg;
+ sc->sc_mii.mii_statchg = wb_miibus_statchg;
+ mii_phy_probe(self, &sc->sc_mii, 0xffffffff);
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE,0,NULL);
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
+ } else
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
/*
* Call MI attach routines.
@@ -1259,6 +988,7 @@ int wb_list_rx_init(sc)
for (i = 0; i < WB_RX_LIST_CNT; i++) {
cd->wb_rx_chain[i].wb_ptr =
(struct wb_desc *)&ld->wb_rx_list[i];
+ cd->wb_rx_chain[i].wb_buf = (void *)&ld->wb_rxbufs[i];
if (wb_newbuf(sc, &cd->wb_rx_chain[i], NULL) == ENOBUFS)
return(ENOBUFS);
if (i == (WB_RX_LIST_CNT - 1)) {
@@ -1278,6 +1008,12 @@ int wb_list_rx_init(sc)
return(0);
}
+void
+wb_bfree(m)
+ struct mbuf *m;
+{
+}
+
/*
* Initialize an RX descriptor and attach an MBUF cluster.
*/
@@ -1293,16 +1029,15 @@ wb_newbuf(sc, c, m)
MGETHDR(m_new, M_DONTWAIT, MT_DATA);
if (m_new == NULL)
return(ENOBUFS);
-
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
- m_freem(m_new);
- return(ENOBUFS);
- }
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
+ m_new->m_data = m_new->m_ext.ext_buf = c->wb_buf;
+ m_new->m_flags |= M_EXT;
+ m_new->m_ext.ext_size = m_new->m_pkthdr.len =
+ m_new->m_len = WB_BUFBYTES;
+ m_new->m_ext.ext_free = wb_bfree;
+ m_new->m_ext.ext_ref = wb_bfree;
} else {
m_new = m;
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
+ m_new->m_len = m_new->m_pkthdr.len = WB_BUFBYTES;
m_new->m_data = m_new->m_ext.ext_buf;
}
@@ -1310,7 +1045,7 @@ wb_newbuf(sc, c, m)
c->wb_mbuf = m_new;
c->wb_ptr->wb_data = vtophys(mtod(m_new, caddr_t));
- c->wb_ptr->wb_ctl = WB_RXCTL_RLINK | (MCLBYTES - 1);
+ c->wb_ptr->wb_ctl = WB_RXCTL_RLINK | 1536;
c->wb_ptr->wb_status = WB_RXSTAT;
return(0);
@@ -1324,7 +1059,7 @@ void wb_rxeof(sc)
struct wb_softc *sc;
{
struct ether_header *eh;
- struct mbuf *m;
+ struct mbuf *m = NULL;
struct ifnet *ifp;
struct wb_chain_onefrag *cur_rx;
int total_len = 0;
@@ -1338,23 +1073,28 @@ void wb_rxeof(sc)
cur_rx = sc->wb_cdata.wb_rx_head;
sc->wb_cdata.wb_rx_head = cur_rx->wb_nextdesc;
+
m = cur_rx->wb_mbuf;
- if ((rxstat & WB_RXSTAT_MIIERR)
- || WB_RXBYTES(cur_rx->wb_ptr->wb_status) == 0) {
+ if ((rxstat & WB_RXSTAT_MIIERR) ||
+ (WB_RXBYTES(cur_rx->wb_ptr->wb_status) < WB_MIN_FRAMELEN) ||
+ (WB_RXBYTES(cur_rx->wb_ptr->wb_status) > 1536) ||
+ !(rxstat & WB_RXSTAT_LASTFRAG) ||
+ !(rxstat & WB_RXSTAT_RXCMP)) {
ifp->if_ierrors++;
- wb_reset(sc);
+ wb_newbuf(sc, cur_rx, m);
printf("%s: receiver babbling: possible chip "
"bug, forcing reset\n", sc->sc_dev.dv_xname);
- ifp->if_flags |= IFF_OACTIVE;
- ifp->if_timer = 2;
+ wb_fixmedia(sc);
+ wb_reset(sc);
+ wb_init(sc);
return;
}
if (rxstat & WB_RXSTAT_RXERR) {
ifp->if_ierrors++;
wb_newbuf(sc, cur_rx, m);
- continue;
+ break;
}
/* No errors; receive the packet. */
@@ -1374,7 +1114,7 @@ void wb_rxeof(sc)
wb_newbuf(sc, cur_rx, m);
if (m0 == NULL) {
ifp->if_ierrors++;
- continue;
+ break;
}
m_adj(m0, ETHER_ALIGN);
m = m0;
@@ -1483,8 +1223,6 @@ void wb_txeoc(sc)
if (sc->wb_cdata.wb_tx_head == NULL) {
ifp->if_flags &= ~IFF_OACTIVE;
sc->wb_cdata.wb_tx_tail = NULL;
- if (sc->wb_want_auto)
- wb_autoneg_mii(sc, WB_FLAG_SCHEDDELAY, 1);
} else {
if (WB_TXOWN(sc->wb_cdata.wb_tx_head) == WB_UNSENT) {
WB_TXOWN(sc->wb_cdata.wb_tx_head) = WB_TXSTAT_OWN;
@@ -1524,21 +1262,21 @@ int wb_intr(arg)
r = 1;
- if (status & WB_ISR_RX_OK)
- wb_rxeof(sc);
-
- if (status & WB_ISR_RX_IDLE)
- wb_rxeoc(sc);
-
if ((status & WB_ISR_RX_NOBUF) || (status & WB_ISR_RX_ERR)) {
ifp->if_ierrors++;
-#ifdef foo
- wb_stop(sc);
wb_reset(sc);
+ if (status & WB_ISR_RX_ERR)
+ wb_fixmedia(sc);
wb_init(sc);
-#endif
+ continue;
}
+ if (status & WB_ISR_RX_OK)
+ wb_rxeof(sc);
+
+ if (status & WB_ISR_RX_IDLE)
+ wb_rxeoc(sc);
+
if (status & WB_ISR_TX_OK)
wb_txeof(sc);
@@ -1581,6 +1319,19 @@ int wb_intr(arg)
return (r);
}
+void
+wb_tick(xsc)
+ void *xsc;
+{
+ struct wb_softc *sc = xsc;
+ int s;
+
+ s = splimp();
+ mii_tick(&sc->sc_mii);
+ timeout(wb_tick, sc, hz);
+ splx(s);
+}
+
/*
* Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
* pointers to the fragment pointers.
@@ -1688,11 +1439,6 @@ void wb_start(ifp)
sc = ifp->if_softc;
- if (sc->wb_autoneg) {
- sc->wb_tx_pend = 1;
- return;
- }
-
/*
* Check for an available queue slot. If there are none,
* punt.
@@ -1777,19 +1523,12 @@ void wb_start(ifp)
void wb_init(xsc)
void *xsc;
{
- struct wb_softc *sc = xsc;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int s, i;
- u_int16_t phy_bmcr = 0;
-
- if (sc->wb_autoneg)
- return;
+ struct wb_softc *sc = xsc;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ int s, i;
s = splimp();
- if (sc->wb_pinfo != NULL)
- phy_bmcr = wb_phy_readreg(sc, PHY_BMCR);
-
/*
* Cancel pending I/O and free all RX/TX buffers.
*/
@@ -1801,15 +1540,33 @@ void wb_init(xsc)
/*
* Set cache alignment and burst length.
*/
+#ifdef foo
CSR_WRITE_4(sc, WB_BUSCTL, WB_BUSCTL_CONFIG);
WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_THRESH);
WB_SETBIT(sc, WB_NETCFG, WB_TXTHRESH(sc->wb_txthresh));
+#endif
+
+ CSR_WRITE_4(sc, WB_BUSCTL, WB_BUSCTL_MUSTBEONE|WB_BUSCTL_ARBITRATION);
+ WB_SETBIT(sc, WB_BUSCTL, WB_BURSTLEN_16LONG);
+ switch(sc->wb_cachesize) {
+ case 32:
+ WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_32LONG);
+ break;
+ case 16:
+ WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_16LONG);
+ break;
+ case 8:
+ WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_8LONG);
+ break;
+ case 0:
+ default:
+ WB_SETBIT(sc, WB_BUSCTL, WB_CACHEALIGN_NONE);
+ break;
+ }
/* This doesn't tend to work too well at 100Mbps. */
WB_CLRBIT(sc, WB_NETCFG, WB_NETCFG_TX_EARLY_ON);
- wb_setcfg(sc, phy_bmcr);
-
/* Init our MAC address */
for (i = 0; i < ETHER_ADDR_LEN; i++) {
CSR_WRITE_1(sc, WB_NODE0 + i, sc->arpcom.ac_enaddr[i]);
@@ -1868,37 +1625,27 @@ void wb_init(xsc)
CSR_WRITE_4(sc, WB_TXADDR, vtophys(&sc->wb_ldata->wb_tx_list[0]));
WB_SETBIT(sc, WB_NETCFG, WB_NETCFG_TX_ON);
- /* Restore state of BMCR */
- if (sc->wb_pinfo != NULL)
- wb_phy_writereg(sc, PHY_BMCR, phy_bmcr);
-
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
(void)splx(s);
+ timeout(wb_tick, sc, hz);
+
return;
}
/*
* Set media options.
*/
-int wb_ifmedia_upd(ifp)
- struct ifnet *ifp;
+int
+wb_ifmedia_upd(ifp)
+ struct ifnet *ifp;
{
- struct wb_softc *sc;
- struct ifmedia *ifm;
-
- sc = ifp->if_softc;
- ifm = &sc->ifmedia;
+ struct wb_softc *sc = ifp->if_softc;
- if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
- return(EINVAL);
-
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO)
- wb_autoneg_mii(sc, WB_FLAG_SCHEDDELAY, 1);
- else
- wb_setmode_mii(sc, ifm->ifm_media);
+ if (ifp->if_flags & IFF_UP)
+ wb_init(sc);
return(0);
}
@@ -1906,49 +1653,17 @@ int wb_ifmedia_upd(ifp)
/*
* Report current media status.
*/
-void wb_ifmedia_sts(ifp, ifmr)
+void
+wb_ifmedia_sts(ifp, ifmr)
struct ifnet *ifp;
struct ifmediareq *ifmr;
{
- struct wb_softc *sc;
- u_int16_t advert = 0, ability = 0;
-
- sc = ifp->if_softc;
-
- ifmr->ifm_active = IFM_ETHER;
+ struct wb_softc *sc = ifp->if_softc;
+ struct mii_data *mii = &sc->sc_mii;
- if (!(wb_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_AUTONEGENBL)) {
- if (wb_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_SPEEDSEL)
- ifmr->ifm_active = IFM_ETHER|IFM_100_TX;
- else
- ifmr->ifm_active = IFM_ETHER|IFM_10_T;
- if (wb_phy_readreg(sc, PHY_BMCR) & PHY_BMCR_DUPLEX)
- ifmr->ifm_active |= IFM_FDX;
- else
- ifmr->ifm_active |= IFM_HDX;
- return;
- }
-
- ability = wb_phy_readreg(sc, PHY_LPAR);
- advert = wb_phy_readreg(sc, PHY_ANAR);
- if (advert & PHY_ANAR_100BT4 &&
- ability & PHY_ANAR_100BT4) {
- ifmr->ifm_active = IFM_ETHER|IFM_100_T4;
- } else if (advert & PHY_ANAR_100BTXFULL &&
- ability & PHY_ANAR_100BTXFULL) {
- ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_FDX;
- } else if (advert & PHY_ANAR_100BTXHALF &&
- ability & PHY_ANAR_100BTXHALF) {
- ifmr->ifm_active = IFM_ETHER|IFM_100_TX|IFM_HDX;
- } else if (advert & PHY_ANAR_10BTFULL &&
- ability & PHY_ANAR_10BTFULL) {
- ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_FDX;
- } else if (advert & PHY_ANAR_10BTHALF &&
- ability & PHY_ANAR_10BTHALF) {
- ifmr->ifm_active = IFM_ETHER|IFM_10_T|IFM_HDX;
- }
-
- return;
+ mii_pollstat(mii);
+ ifmr->ifm_active = mii->mii_media_active;
+ ifmr->ifm_status = mii->mii_media_status;
}
int wb_ioctl(ifp, command, data)
@@ -1997,7 +1712,7 @@ int wb_ioctl(ifp, command, data)
break;
case SIOCGIFMEDIA:
case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
break;
default:
error = EINVAL;
@@ -2016,18 +1731,14 @@ void wb_watchdog(ifp)
sc = ifp->if_softc;
- if (sc->wb_autoneg) {
- wb_autoneg_mii(sc, WB_FLAG_DELAYTIMEO, 1);
- return;
- }
-
ifp->if_oerrors++;
printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
+#ifdef foo
if (!(wb_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT))
printf("%s: no carrier - transceiver cable problem?\n",
sc->sc_dev.dv_xname);
-
+#endif
wb_stop(sc);
wb_reset(sc);
wb_init(sc);
@@ -2051,6 +1762,8 @@ void wb_stop(sc)
ifp = &sc->arpcom.ac_if;
ifp->if_timer = 0;
+ untimeout(wb_tick, sc);
+
WB_CLRBIT(sc, WB_NETCFG, (WB_NETCFG_RX_ON|WB_NETCFG_TX_ON));
CSR_WRITE_4(sc, WB_IMR, 0x00000000);
CSR_WRITE_4(sc, WB_TXADDR, 0x00000000);
diff --git a/sys/dev/pci/if_wbreg.h b/sys/dev/pci/if_wbreg.h
index 702483cb7fa..41263f023a7 100644
--- a/sys/dev/pci/if_wbreg.h
+++ b/sys/dev/pci/if_wbreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wbreg.h,v 1.3 1999/09/27 18:17:01 jason Exp $ */
+/* $OpenBSD: if_wbreg.h,v 1.4 1999/11/19 02:29:27 jason Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -71,6 +71,7 @@
#define WB_BUSCTL_CACHEALIGN 0x0000C000
#define WB_BUSCTL_DES_BIGENDIAN 0x00100000
#define WB_BUSCTL_WAIT 0x00200000
+#define WB_BUSCTL_MUSTBEONE 0x00400000
#define WB_SKIPLEN_1LONG 0x00000004
#define WB_SKIPLEN_2LONG 0x00000008
@@ -78,6 +79,7 @@
#define WB_SKIPLEN_4LONG 0x00000020
#define WB_SKIPLEN_5LONG 0x00000040
+#define WB_CACHEALIGN_NONE 0x00000000
#define WB_CACHEALIGN_8LONG 0x00004000
#define WB_CACHEALIGN_16LONG 0x00008000
#define WB_CACHEALIGN_32LONG 0x0000C000
@@ -298,7 +300,14 @@ struct wb_txdesc {
#define WB_UNSENT 0x1234
+#define WB_BUFBYTES (1024 * sizeof(u_int32_t))
+
+struct wb_buf {
+ u_int32_t wb_data[1024];
+};
+
struct wb_list_data {
+ struct wb_buf wb_rxbufs[WB_RX_LIST_CNT];
struct wb_desc wb_rx_list[WB_RX_LIST_CNT];
struct wb_txdesc wb_tx_list[WB_TX_LIST_CNT];
};
@@ -313,6 +322,7 @@ struct wb_chain {
struct wb_chain_onefrag {
struct wb_desc *wb_ptr;
struct mbuf *wb_mbuf;
+ void *wb_buf;
struct wb_chain_onefrag *wb_nextdesc;
u_int8_t wb_rlast;
};
@@ -352,25 +362,17 @@ struct wb_mii_frame {
#define WB_MII_WRITEOP 0x01
#define WB_MII_TURNAROUND 0x02
-#define WB_FLAG_FORCEDELAY 1
-#define WB_FLAG_SCHEDDELAY 2
-#define WB_FLAG_DELAYTIMEO 3
-
struct wb_softc {
struct device sc_dev; /* generic device structure */
void * sc_ih; /* interrupt handler cookie */
struct arpcom arpcom; /* interface info */
- struct ifmedia ifmedia; /* media info */
+ mii_data_t sc_mii;
bus_space_handle_t wb_bhandle;
bus_space_tag_t wb_btag;
struct wb_type *wb_info; /* 3Com adapter info */
- struct wb_type *wb_pinfo; /* phy info */
u_int8_t wb_type;
- u_int8_t wb_phy_addr; /* PHY address */
- u_int8_t wb_tx_pend; /* TX pending */
- u_int8_t wb_want_auto;
- u_int8_t wb_autoneg;
u_int16_t wb_txthresh;
+ int wb_cachesize;
caddr_t wb_ldata_ptr;
struct wb_list_data *wb_ldata;
struct wb_chain_data wb_cdata;
@@ -418,41 +420,8 @@ struct wb_softc {
#define CP_DEVICEID_RL100 0x2011
/*
- * Texas Instruments PHY identifiers
- */
-#define TI_PHY_VENDORID 0x4000
-#define TI_PHY_10BT 0x501F
-#define TI_PHY_100VGPMI 0x502F
-
-/*
- * These ID values are for the NS DP83840A 10/100 PHY
- */
-#define NS_PHY_VENDORID 0x2000
-#define NS_PHY_83840A 0x5C0F
-
-/*
- * Level 1 10/100 PHY
- */
-#define LEVEL1_PHY_VENDORID 0x7810
-#define LEVEL1_PHY_LXT970 0x000F
-
-/*
- * Intel 82555 10/100 PHY
- */
-#define INTEL_PHY_VENDORID 0x0A28
-#define INTEL_PHY_82555 0x015F
-
-/*
- * SEEQ 80220 10/100 PHY
- */
-#define SEEQ_PHY_VENDORID 0x0016
-#define SEEQ_PHY_80220 0xF83F
-
-
-/*
* PCI low memory base and low I/O base register, and
- * other PCI registers. Note: some are only available on
- * the 3c905B, in particular those that related to power management.
+ * other PCI registers.
*/
#define WB_PCI_VENDOR_ID 0x00
@@ -460,6 +429,7 @@ struct wb_softc {
#define WB_PCI_COMMAND 0x04
#define WB_PCI_STATUS 0x06
#define WB_PCI_CLASSCODE 0x09
+#define WB_PCI_CACHELEN 0x0C
#define WB_PCI_LATENCY_TIMER 0x0D
#define WB_PCI_HEADER_TYPE 0x0E
#define WB_PCI_LOIO 0x10
@@ -486,105 +456,6 @@ struct wb_softc {
#define WB_PME_EN 0x0010
#define WB_PME_STATUS 0x8000
-#define PHY_UNKNOWN 6
-
-#define WB_PHYADDR_MIN 0x00
-#define WB_PHYADDR_MAX 0x1F
-
-#define PHY_BMCR 0x00
-#define PHY_BMSR 0x01
-#define PHY_VENID 0x02
-#define PHY_DEVID 0x03
-#define PHY_ANAR 0x04
-#define PHY_LPAR 0x05
-#define PHY_ANEXP 0x06
-
-#define PHY_ANAR_NEXTPAGE 0x8000
-#define PHY_ANAR_RSVD0 0x4000
-#define PHY_ANAR_TLRFLT 0x2000
-#define PHY_ANAR_RSVD1 0x1000
-#define PHY_ANAR_RSVD2 0x0800
-#define PHY_ANAR_RSVD3 0x0400
-#define PHY_ANAR_100BT4 0x0200
-#define PHY_ANAR_100BTXFULL 0x0100
-#define PHY_ANAR_100BTXHALF 0x0080
-#define PHY_ANAR_10BTFULL 0x0040
-#define PHY_ANAR_10BTHALF 0x0020
-#define PHY_ANAR_PROTO4 0x0010
-#define PHY_ANAR_PROTO3 0x0008
-#define PHY_ANAR_PROTO2 0x0004
-#define PHY_ANAR_PROTO1 0x0002
-#define PHY_ANAR_PROTO0 0x0001
-
-/*
- * These are the register definitions for the PHY (physical layer
- * interface chip).
- */
-/*
- * PHY BMCR Basic Mode Control Register
- */
-#define PHY_BMCR_RESET 0x8000
-#define PHY_BMCR_LOOPBK 0x4000
-#define PHY_BMCR_SPEEDSEL 0x2000
-#define PHY_BMCR_AUTONEGENBL 0x1000
-#define PHY_BMCR_RSVD0 0x0800 /* write as zero */
-#define PHY_BMCR_ISOLATE 0x0400
-#define PHY_BMCR_AUTONEGRSTR 0x0200
-#define PHY_BMCR_DUPLEX 0x0100
-#define PHY_BMCR_COLLTEST 0x0080
-#define PHY_BMCR_RSVD1 0x0040 /* write as zero, don't care */
-#define PHY_BMCR_RSVD2 0x0020 /* write as zero, don't care */
-#define PHY_BMCR_RSVD3 0x0010 /* write as zero, don't care */
-#define PHY_BMCR_RSVD4 0x0008 /* write as zero, don't care */
-#define PHY_BMCR_RSVD5 0x0004 /* write as zero, don't care */
-#define PHY_BMCR_RSVD6 0x0002 /* write as zero, don't care */
-#define PHY_BMCR_RSVD7 0x0001 /* write as zero, don't care */
-/*
- * RESET: 1 == software reset, 0 == normal operation
- * Resets status and control registers to default values.
- * Relatches all hardware config values.
- *
- * LOOPBK: 1 == loopback operation enabled, 0 == normal operation
- *
- * SPEEDSEL: 1 == 100Mb/s, 0 == 10Mb/s
- * Link speed is selected byt his bit or if auto-negotiation if bit
- * 12 (AUTONEGENBL) is set (in which case the value of this register
- * is ignored).
- *
- * AUTONEGENBL: 1 == Autonegotiation enabled, 0 == Autonegotiation disabled
- * Bits 8 and 13 are ignored when autoneg is set, otherwise bits 8 and 13
- * determine speed and mode. Should be cleared and then set if PHY configured
- * for no autoneg on startup.
- *
- * ISOLATE: 1 == isolate PHY from MII, 0 == normal operation
- *
- * AUTONEGRSTR: 1 == restart autonegotiation, 0 = normal operation
- *
- * DUPLEX: 1 == full duplex mode, 0 == half duplex mode
- *
- * COLLTEST: 1 == collision test enabled, 0 == normal operation
- */
-
-/*
- * PHY, BMSR Basic Mode Status Register
- */
-#define PHY_BMSR_100BT4 0x8000
-#define PHY_BMSR_100BTXFULL 0x4000
-#define PHY_BMSR_100BTXHALF 0x2000
-#define PHY_BMSR_10BTFULL 0x1000
-#define PHY_BMSR_10BTHALF 0x0800
-#define PHY_BMSR_RSVD1 0x0400 /* write as zero, don't care */
-#define PHY_BMSR_RSVD2 0x0200 /* write as zero, don't care */
-#define PHY_BMSR_RSVD3 0x0100 /* write as zero, don't care */
-#define PHY_BMSR_RSVD4 0x0080 /* write as zero, don't care */
-#define PHY_BMSR_MFPRESUP 0x0040
-#define PHY_BMSR_AUTONEGCOMP 0x0020
-#define PHY_BMSR_REMFAULT 0x0010
-#define PHY_BMSR_CANAUTONEG 0x0008
-#define PHY_BMSR_LINKSTAT 0x0004
-#define PHY_BMSR_JABBER 0x0002
-#define PHY_BMSR_EXTENDED 0x0001
-
#ifndef ETHER_CRC_LEN
#define ETHER_CRC_LEN 4
#endif