summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2006-02-04 21:48:35 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2006-02-04 21:48:35 +0000
commit6c023455d9fd0b3ca61f1b9fa2775802dde2f1f8 (patch)
tree867b095717466eeb146fa44ffc559ac81fc955a2 /sys/dev/pci
parent638d3699d0a41220530d4aa830c8ac09a5ce87c7 (diff)
- start MII timer in nfe_init() and move timer initialization in nfe_attach()
- set RX filter before enabling RX in nfe_init() - call mii_down() in nfe_stop() - fix setting of full/half-duplex mode - call mii_phy_reset() for each PHY attached and call mii_mediachg() in nfe_ifmedia_upd() - some cleaning while i'm here
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_nfe.c110
-rw-r--r--sys/dev/pci/if_nfereg.h24
-rw-r--r--sys/dev/pci/if_nfevar.h7
3 files changed, 76 insertions, 65 deletions
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c
index c842b1cd355..7bf9db47340 100644
--- a/sys/dev/pci/if_nfe.c
+++ b/sys/dev/pci/if_nfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nfe.c,v 1.12 2006/02/04 16:51:15 damien Exp $ */
+/* $OpenBSD: if_nfe.c,v 1.13 2006/02/04 21:48:34 damien Exp $ */
/*-
* Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr>
@@ -91,8 +91,8 @@ void nfe_free_rx_ring(struct nfe_softc *, struct nfe_rx_ring *);
int nfe_alloc_tx_ring(struct nfe_softc *, struct nfe_tx_ring *);
void nfe_reset_tx_ring(struct nfe_softc *, struct nfe_tx_ring *);
void nfe_free_tx_ring(struct nfe_softc *, struct nfe_tx_ring *);
-int nfe_mediachange(struct ifnet *);
-void nfe_mediastatus(struct ifnet *, struct ifmediareq *);
+int nfe_ifmedia_upd(struct ifnet *);
+void nfe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
void nfe_setmulti(struct nfe_softc *);
void nfe_get_macaddr(struct nfe_softc *, uint8_t *);
void nfe_set_macaddr(struct nfe_softc *, const uint8_t *);
@@ -159,9 +159,6 @@ nfe_attach(struct device *parent, struct device *self, void *aux)
return;
}
- /*
- * Allocate interrupt.
- */
if (pci_intr_map(pa, &ih) != 0) {
printf(": couldn't map interrupt\n");
return;
@@ -245,8 +242,8 @@ nfe_attach(struct device *parent, struct device *self, void *aux)
sc->sc_mii.mii_writereg = nfe_miibus_writereg;
sc->sc_mii.mii_statchg = nfe_miibus_statchg;
- ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_mediachange,
- nfe_mediastatus);
+ ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd,
+ nfe_ifmedia_sts);
mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
MII_OFFSET_ANY, 0);
if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
@@ -260,6 +257,8 @@ nfe_attach(struct device *parent, struct device *self, void *aux)
if_attach(ifp);
ether_ifattach(ifp);
+ timeout_set(&sc->sc_tick_ch, nfe_tick, sc);
+
sc->sc_powerhook = powerhook_establish(nfe_power, sc);
}
@@ -284,20 +283,41 @@ nfe_miibus_statchg(struct device *dev)
{
struct nfe_softc *sc = (struct nfe_softc *)dev;
struct mii_data *mii = &sc->sc_mii;
- uint32_t reg;
+ uint32_t phy, seed, misc = NFE_MISC1_MAGIC, link = NFE_MEDIA_SET;
- reg = NFE_READ(sc, NFE_PHY_INT);
+ phy = NFE_READ(sc, NFE_PHY_IFACE);
+ phy &= ~(NFE_PHY_HDX | NFE_PHY_100TX | NFE_PHY_1000T);
+
+ seed = NFE_READ(sc, NFE_RNDSEED);
+ seed &= ~NFE_SEED_MASK;
+
+ if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) {
+ phy |= NFE_PHY_HDX; /* half-duplex */
+ misc |= NFE_MISC1_HDX;
+ }
switch (IFM_SUBTYPE(mii->mii_media_active)) {
- case IFM_1000_T:
- reg |= NFE_PHY_1000T;
+ case IFM_1000_T: /* full-duplex only */
+ link |= NFE_MEDIA_1000T;
+ seed |= NFE_SEED_1000T;
+ phy |= NFE_PHY_1000T;
break;
case IFM_100_TX:
- reg |= NFE_PHY_100TX;
+ link |= NFE_MEDIA_100TX;
+ seed |= NFE_SEED_100TX;
+ phy |= NFE_PHY_100TX;
+ break;
+ case IFM_10_T:
+ link |= NFE_MEDIA_10T;
+ seed |= NFE_SEED_10T;
break;
}
- NFE_WRITE(sc, NFE_PHY_INT, reg);
+ NFE_WRITE(sc, NFE_RNDSEED, seed); /* XXX: gigabit NICs only? */
+
+ NFE_WRITE(sc, NFE_PHY_IFACE, phy);
+ NFE_WRITE(sc, NFE_MISC1, misc);
+ NFE_WRITE(sc, NFE_LINKSPEED, link);
}
int
@@ -963,22 +983,24 @@ nfe_init(struct ifnet *ifp)
DELAY(10);
NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT1 | rxtxctl);
+ /* configure media */
+ mii_mediachg(&sc->sc_mii);
+
+ /* set Rx filter */
+ nfe_setmulti(sc);
+
/* enable Rx */
NFE_WRITE(sc, NFE_RX_CTL, NFE_RX_START);
/* enable Tx */
NFE_WRITE(sc, NFE_TX_CTL, NFE_TX_START);
- nfe_setmulti(sc);
-
NFE_WRITE(sc, NFE_PHY_STATUS, 0xf);
/* enable interrupts */
NFE_WRITE(sc, NFE_IRQ_MASK, NFE_IRQ_WANTED);
- mii_mediachg(&sc->sc_mii);
-
- timeout_set(&sc->sc_timeout, nfe_tick, sc);
+ timeout_add(&sc->sc_tick_ch, hz);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -991,11 +1013,13 @@ nfe_stop(struct ifnet *ifp, int disable)
{
struct nfe_softc *sc = ifp->if_softc;
- timeout_del(&sc->sc_timeout);
+ timeout_del(&sc->sc_tick_ch);
ifp->if_timer = 0;
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+ mii_down(&sc->sc_mii);
+
/* abort Tx */
NFE_WRITE(sc, NFE_TX_CTL, 0);
@@ -1333,48 +1357,28 @@ nfe_free_tx_ring(struct nfe_softc *sc, struct nfe_tx_ring *ring)
}
int
-nfe_mediachange(struct ifnet *ifp)
+nfe_ifmedia_upd(struct ifnet *ifp)
{
struct nfe_softc *sc = ifp->if_softc;
- struct mii_data *mii = &sc->sc_mii;
- uint32_t val;
-
- DPRINTF(("nfe_mediachange\n"));
-#if 0
- if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
- /* XXX? */
- else
-#endif
- val = 0;
-
- val |= NFE_MEDIA_SET;
+ struct mii_data *mii = &sc->sc_mii;
+ struct mii_softc *miisc;
- switch (IFM_SUBTYPE(mii->mii_media_active)) {
- case IFM_1000_T:
- val |= NFE_MEDIA_1000T;
- break;
- case IFM_100_TX:
- val |= NFE_MEDIA_100TX;
- break;
- case IFM_10_T:
- val |= NFE_MEDIA_10T;
- break;
+ if (mii->mii_instance != 0) {
+ LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
+ mii_phy_reset(miisc);
}
-
- DPRINTF(("nfe_miibus_statchg: val=0x%x\n", val));
- NFE_WRITE(sc, NFE_LINKSPEED, val);
-
- return 0;
+ return mii_mediachg(mii);
}
void
-nfe_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
+nfe_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
{
struct nfe_softc *sc = ifp->if_softc;
+ struct mii_data *mii = &sc->sc_mii;
- mii_pollstat(&sc->sc_mii);
- ifmr->ifm_status = sc->sc_mii.mii_media_status;
- ifmr->ifm_active = sc->sc_mii.mii_media_active;
+ mii_pollstat(mii);
+ ifmr->ifm_status = mii->mii_media_status;
+ ifmr->ifm_active = mii->mii_media_active;
}
void
@@ -1465,5 +1469,5 @@ nfe_tick(void *arg)
mii_tick(&sc->sc_mii);
splx(s);
- timeout_add(&sc->sc_timeout, hz);
+ timeout_add(&sc->sc_tick_ch, hz);
}
diff --git a/sys/dev/pci/if_nfereg.h b/sys/dev/pci/if_nfereg.h
index 44170213fe1..c32685943db 100644
--- a/sys/dev/pci/if_nfereg.h
+++ b/sys/dev/pci/if_nfereg.h
@@ -1,5 +1,6 @@
-/* $OpenBSD: if_nfereg.h,v 1.5 2006/02/04 09:46:48 damien Exp $ */
-/*
+/* $OpenBSD: if_nfereg.h,v 1.6 2006/02/04 21:48:34 damien Exp $ */
+
+/*-
* Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -33,7 +34,7 @@
#define NFE_OFFLD_CFG 0x090
#define NFE_RX_CTL 0x094
#define NFE_RX_STATUS 0x098
-#define NFE_RDM_SEED 0x09c
+#define NFE_RNDSEED 0x09c
#define NFE_SETUP_R1 0x0a0
#define NFE_SETUP_R2 0x0a4
#define NFE_MACADDR_HI 0x0a8
@@ -42,7 +43,7 @@
#define NFE_MULTIADDR_LO 0x0b4
#define NFE_MULTIMASK_HI 0x0b8
#define NFE_MULTIMASK_LO 0x0bc
-#define NFE_PHY_INT 0x0c0
+#define NFE_PHY_IFACE 0x0c0
#define NFE_TX_RING_ADDR 0x100
#define NFE_RX_RING_ADDR 0x104
#define NFE_RING_SIZE 0x108
@@ -104,12 +105,17 @@
#define NFE_MEDIA_100TX 0x00064
#define NFE_MEDIA_10T 0x003e8
-#define NFE_PHY_100TX 0x01
-#define NFE_PHY_1000T 0x02
+#define NFE_PHY_100TX (1 << 0)
+#define NFE_PHY_1000T (1 << 1)
+#define NFE_PHY_HDX (1 << 8)
+
+#define NFE_MISC1_MAGIC 0x003b0f3c
+#define NFE_MISC1_HDX (1 << 1)
-#define NFE_RDM_SEED_FORCE1 0x7f00
-#define NFE_RDM_SEED_FORCE2 0x2d00
-#define NFE_RDM_SEED_FORCE3 0x7400
+#define NFE_SEED_MASK 0x0003ff00
+#define NFE_SEED_10T 0x00007f00
+#define NFE_SEED_100TX 0x00002d00
+#define NFE_SEED_1000T 0x00007400
/* Rx/Tx descriptor */
struct nfe_desc32 {
diff --git a/sys/dev/pci/if_nfevar.h b/sys/dev/pci/if_nfevar.h
index ce0ab9407e5..8ea5c7c71a8 100644
--- a/sys/dev/pci/if_nfevar.h
+++ b/sys/dev/pci/if_nfevar.h
@@ -1,5 +1,6 @@
-/* $OpenBSD: if_nfevar.h,v 1.6 2006/02/04 09:46:48 damien Exp $ */
-/*
+/* $OpenBSD: if_nfevar.h,v 1.7 2006/02/04 21:48:34 damien Exp $ */
+
+/*-
* Copyright (c) 2005 Jonathan Gray <jsg@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -59,7 +60,7 @@ struct nfe_softc {
void *sc_ih;
bus_dma_tag_t sc_dmat;
struct mii_data sc_mii;
- struct timeout sc_timeout;
+ struct timeout sc_tick_ch;
void *sc_powerhook;
int sc_if_flags;