summaryrefslogtreecommitdiffstats
path: root/sys/dev/en
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-06-13 12:08:09 +0000
committerharti <harti@FreeBSD.org>2003-06-13 12:08:09 +0000
commit4ebffe3ab8eef8fd645a97e69b2bdb9632bed579 (patch)
treeff743821ab524457790e820a4efa095b00ceb814 /sys/dev/en
parent38bbc58a38c14d497e813987fe51ef42536d74f7 (diff)
downloadFreeBSD-src-4ebffe3ab8eef8fd645a97e69b2bdb9632bed579.zip
FreeBSD-src-4ebffe3ab8eef8fd645a97e69b2bdb9632bed579.tar.gz
Make the midway driver use the new ATM phy driver. This allows one to
toggle several media options (sonet/sdh, for example) with ifconfig and to see the carrier state in ifconfig's output. It gives also read/write access (given the right privilegs) to the S/Uni registers to user space programs.
Diffstat (limited to 'sys/dev/en')
-rw-r--r--sys/dev/en/if_en_pci.c3
-rw-r--r--sys/dev/en/midway.c85
-rw-r--r--sys/dev/en/midwayvar.h4
3 files changed, 86 insertions, 6 deletions
diff --git a/sys/dev/en/if_en_pci.c b/sys/dev/en/if_en_pci.c
index fec4248..b44bcdb 100644
--- a/sys/dev/en/if_en_pci.c
+++ b/sys/dev/en/if_en_pci.c
@@ -60,15 +60,18 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <net/if_atm.h>
+#include <net/if_media.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
+#include <dev/utopia/utopia.h>
#include <dev/en/midwayreg.h>
#include <dev/en/midwayvar.h>
MODULE_DEPEND(en, pci, 1, 1, 1);
MODULE_DEPEND(en, atm, 1, 1, 1);
+MODULE_DEPEND(en, utopia, 1, 1, 1);
/*
* local structures
diff --git a/sys/dev/en/midway.c b/sys/dev/en/midway.c
index 88639b5..63cd4bc 100644
--- a/sys/dev/en/midway.c
+++ b/sys/dev/en/midway.c
@@ -155,6 +155,7 @@ enum {
#include <sys/sysctl.h>
#include <sys/malloc.h>
#include <machine/resource.h>
+#include <dev/utopia/utopia.h>
#include <dev/en/midwayreg.h>
#include <dev/en/midwayvar.h>
@@ -214,6 +215,7 @@ int en_dumpmem(int,int,int);
DBG(SC, LOCK, ("ENUNLOCK %d\n", __LINE__)); \
mtx_unlock(&sc->en_mtx); \
} while (0)
+#define EN_CHECKLOCK(sc) mtx_assert(&sc->en_mtx, MA_OWNED)
/*
* While a transmit mbuf is waiting to get transmit DMA resources we
@@ -1446,7 +1448,7 @@ en_init(struct en_softc *sc)
*/
en_write(sc, MID_INTENA, MID_INT_TX | MID_INT_DMA_OVR | MID_INT_IDENT |
MID_INT_LERR | MID_INT_DMA_ERR | MID_INT_DMA_RX | MID_INT_DMA_TX |
- MID_INT_SERVICE | /* MID_INT_SUNI | */ MID_INT_STATS);
+ MID_INT_SERVICE | MID_INT_SUNI | MID_INT_STATS);
en_write(sc, MID_MAST_CSR, MID_SETIPL(sc->ipl) | MID_MCSR_ENDMA |
MID_MCSR_ENTX | MID_MCSR_ENRX);
}
@@ -1531,6 +1533,11 @@ en_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifp->if_mtu = ifr->ifr_mtu;
break;
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd);
+ break;
+
default:
error = EINVAL;
break;
@@ -2348,11 +2355,8 @@ en_intr(void *arg)
return;
}
-#if 0
if (reg & MID_INT_SUNI)
- if_printf(&sc->ifatm.ifnet, "interrupt from SUNI (probably "
- "carrier change)\n");
-#endif
+ utopia_intr(&sc->utopia);
kick = 0;
if (reg & MID_INT_TX)
@@ -2395,6 +2399,50 @@ en_intr(void *arg)
EN_UNLOCK(sc);
}
+/*
+ * Read at most n SUNI regs starting at reg into val
+ */
+static int
+en_utopia_readregs(struct ifatm *ifatm, u_int reg, uint8_t *val, u_int *n)
+{
+ struct en_softc *sc = ifatm->ifnet.if_softc;
+ u_int i;
+
+ EN_CHECKLOCK(sc);
+ if (reg >= MID_NSUNI)
+ return (EINVAL);
+ if (reg + *n > MID_NSUNI)
+ *n = MID_NSUNI - reg;
+
+ for (i = 0; i < *n; i++)
+ val[i] = en_read(sc, MID_SUNIOFF + 4 * (reg + i));
+
+ return (0);
+}
+
+/*
+ * change the bits given by mask to them in val in register reg
+ */
+static int
+en_utopia_writereg(struct ifatm *ifatm, u_int reg, u_int mask, u_int val)
+{
+ struct en_softc *sc = ifatm->ifnet.if_softc;
+ uint32_t regval;
+
+ EN_CHECKLOCK(sc);
+ if (reg >= MID_NSUNI)
+ return (EINVAL);
+ regval = en_read(sc, MID_SUNIOFF + 4 * reg);
+ regval = (regval & ~mask) | (val & mask);
+ en_write(sc, MID_SUNIOFF + 4 * reg, regval);
+ return (0);
+}
+
+static const struct utopia_methods en_utopia_methods = {
+ en_utopia_readregs,
+ en_utopia_writereg
+};
+
/*********************************************************************/
/*
* Probing the DMA brokeness of the card
@@ -2787,6 +2835,12 @@ en_attach(struct en_softc *sc)
goto fail;
#endif
+ sc->ifatm.phy = &sc->utopia;
+ utopia_attach(&sc->utopia, &sc->ifatm, &sc->media, &sc->en_mtx,
+ &sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+ &en_utopia_methods);
+ utopia_init_media(&sc->utopia);
+
MGET(sc->padbuf, M_TRYWAIT, MT_DATA);
if (sc->padbuf == NULL)
goto fail;
@@ -2875,6 +2929,16 @@ en_attach(struct en_softc *sc)
"%6D\n", sc->ifatm.mib.esi, ":");
/*
+ * Start SUNI stuff. This will call our readregs/writeregs
+ * functions and these assume the lock to be held so we must get it
+ * here.
+ */
+ EN_LOCK(sc);
+ utopia_start(&sc->utopia);
+ utopia_reset(&sc->utopia);
+ EN_UNLOCK(sc);
+
+ /*
* final commit
*/
atm_ifattach(ifp);
@@ -2894,11 +2958,20 @@ en_attach(struct en_softc *sc)
* Free all internal resources. No access to bus resources here.
* No locking required here (interrupt is already disabled).
*
- * LOCK: unlocked, not needed (but destroyed)
+ * LOCK: unlocked, needed (but destroyed)
*/
void
en_destroy(struct en_softc *sc)
{
+
+ if (sc->utopia.state & UTP_ST_ATTACHED) {
+ /* these assume the lock to be held */
+ EN_LOCK(sc);
+ utopia_stop(&sc->utopia);
+ utopia_detach(&sc->utopia);
+ EN_UNLOCK(sc);
+ }
+
if (sc->padbuf != NULL)
m_free(sc->padbuf);
diff --git a/sys/dev/en/midwayvar.h b/sys/dev/en/midwayvar.h
index 7b29f52..7cbd3b2 100644
--- a/sys/dev/en/midwayvar.h
+++ b/sys/dev/en/midwayvar.h
@@ -211,6 +211,10 @@ struct en_softc {
/* memory zones */
uma_zone_t map_zone;
+ /* media and phy */
+ struct ifmedia media;
+ struct utopia utopia;
+
#ifdef EN_DEBUG
/* debugging */
u_int debug;
OpenPOWER on IntegriCloud