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.
This commit is contained in:
harti 2003-06-13 12:08:09 +00:00
parent e2a62162f8
commit 76737a8bfd
7 changed files with 101 additions and 7 deletions

View File

@ -9,6 +9,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Cd "device en" .Cd "device en"
.Cd "device atm" .Cd "device atm"
.Cd "device utopia"
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Nm .Nm
@ -29,7 +30,12 @@ byte encoding of the following flags.
Thus, parameter 3 means AAL5 and LLC/SNAP encapsulation. Thus, parameter 3 means AAL5 and LLC/SNAP encapsulation.
Note that BPF works only with LLC/SNAP encapsulation. Note that BPF works only with LLC/SNAP encapsulation.
.Pp .Pp
The following sysctls are recognized by the driver: The device driver uses the
.Xr utopia 4
module for communication with the physical and ATM layer chip (SUNI/Lite).
.Pp
The following sysctls are recognized by the driver besides those implemented by
.Xr utopia 4 :
.Bl -tag -width XXX .Bl -tag -width XXX
.It Cm hw.atm.enX.istats .It Cm hw.atm.enX.istats
Contains an array of Contains an array of
@ -63,6 +69,7 @@ The driver extensively uses DMA on PCI.
The first The first
generation PCI chipsets do not work or exhibit poor performance. generation PCI chipsets do not work or exhibit poor performance.
.Sh SEE ALSO .Sh SEE ALSO
.Xr utopia 4 ,
.Xr ifconfig 8 , .Xr ifconfig 8 ,
.Xr route 8 .Xr route 8
.Sh AUTHORS .Sh AUTHORS

View File

@ -1678,12 +1678,15 @@ options MSIZE=512 # mbuf size in bytes
# NATM enables the netnatm protocol family that can be used to # NATM enables the netnatm protocol family that can be used to
# bypass TCP/IP. # bypass TCP/IP.
# #
# utopia provides the access to the ATM PHY chips and is required for en
#
# the current driver supports only PVC operations (no atm-arp, no multicast). # the current driver supports only PVC operations (no atm-arp, no multicast).
# for more details, please read the original documents at # for more details, please read the original documents at
# http://www.ccrc.wustl.edu/pub/chuck/tech/bsdatm/bsdatm.html # http://www.ccrc.wustl.edu/pub/chuck/tech/bsdatm/bsdatm.html
# #
device atm device atm
device en device en
device utopia #ATM PHY driver
options NATM #native ATM options NATM #native ATM
# #

View File

@ -797,6 +797,7 @@ dev/usb/usb_quirks.c optional usb
dev/usb/usb_subr.c optional usb dev/usb/usb_subr.c optional usb
dev/usb/usbdi.c optional usb dev/usb/usbdi.c optional usb
dev/usb/usbdi_util.c optional usb dev/usb/usbdi_util.c optional usb
dev/utopia/utopia.c optional utopia
dev/vinum/vinum.c optional vinum dev/vinum/vinum.c optional vinum
dev/vinum/vinumconfig.c optional vinum dev/vinum/vinumconfig.c optional vinum
dev/vinum/vinumdaemon.c optional vinum dev/vinum/vinumdaemon.c optional vinum

View File

@ -60,15 +60,18 @@ __FBSDID("$FreeBSD$");
#include <net/if.h> #include <net/if.h>
#include <net/if_atm.h> #include <net/if_atm.h>
#include <net/if_media.h>
#include <pci/pcivar.h> #include <pci/pcivar.h>
#include <pci/pcireg.h> #include <pci/pcireg.h>
#include <dev/utopia/utopia.h>
#include <dev/en/midwayreg.h> #include <dev/en/midwayreg.h>
#include <dev/en/midwayvar.h> #include <dev/en/midwayvar.h>
MODULE_DEPEND(en, pci, 1, 1, 1); MODULE_DEPEND(en, pci, 1, 1, 1);
MODULE_DEPEND(en, atm, 1, 1, 1); MODULE_DEPEND(en, atm, 1, 1, 1);
MODULE_DEPEND(en, utopia, 1, 1, 1);
/* /*
* local structures * local structures

View File

@ -155,6 +155,7 @@ enum {
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <machine/resource.h> #include <machine/resource.h>
#include <dev/utopia/utopia.h>
#include <dev/en/midwayreg.h> #include <dev/en/midwayreg.h>
#include <dev/en/midwayvar.h> #include <dev/en/midwayvar.h>
@ -214,6 +215,7 @@ int en_dumpmem(int,int,int);
DBG(SC, LOCK, ("ENUNLOCK %d\n", __LINE__)); \ DBG(SC, LOCK, ("ENUNLOCK %d\n", __LINE__)); \
mtx_unlock(&sc->en_mtx); \ mtx_unlock(&sc->en_mtx); \
} while (0) } 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 * 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 | 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_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 | en_write(sc, MID_MAST_CSR, MID_SETIPL(sc->ipl) | MID_MCSR_ENDMA |
MID_MCSR_ENTX | MID_MCSR_ENRX); 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; ifp->if_mtu = ifr->ifr_mtu;
break; break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd);
break;
default: default:
error = EINVAL; error = EINVAL;
break; break;
@ -2348,11 +2355,8 @@ en_intr(void *arg)
return; return;
} }
#if 0
if (reg & MID_INT_SUNI) if (reg & MID_INT_SUNI)
if_printf(&sc->ifatm.ifnet, "interrupt from SUNI (probably " utopia_intr(&sc->utopia);
"carrier change)\n");
#endif
kick = 0; kick = 0;
if (reg & MID_INT_TX) if (reg & MID_INT_TX)
@ -2395,6 +2399,50 @@ en_intr(void *arg)
EN_UNLOCK(sc); 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 * Probing the DMA brokeness of the card
@ -2787,6 +2835,12 @@ en_attach(struct en_softc *sc)
goto fail; goto fail;
#endif #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); MGET(sc->padbuf, M_TRYWAIT, MT_DATA);
if (sc->padbuf == NULL) if (sc->padbuf == NULL)
goto fail; goto fail;
@ -2874,6 +2928,16 @@ en_attach(struct en_softc *sc)
if_printf(&sc->ifatm.ifnet, "end station identifier (mac address) " if_printf(&sc->ifatm.ifnet, "end station identifier (mac address) "
"%6D\n", sc->ifatm.mib.esi, ":"); "%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 * final commit
*/ */
@ -2894,11 +2958,20 @@ en_attach(struct en_softc *sc)
* Free all internal resources. No access to bus resources here. * Free all internal resources. No access to bus resources here.
* No locking required here (interrupt is already disabled). * No locking required here (interrupt is already disabled).
* *
* LOCK: unlocked, not needed (but destroyed) * LOCK: unlocked, needed (but destroyed)
*/ */
void void
en_destroy(struct en_softc *sc) 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) if (sc->padbuf != NULL)
m_free(sc->padbuf); m_free(sc->padbuf);

View File

@ -211,6 +211,10 @@ struct en_softc {
/* memory zones */ /* memory zones */
uma_zone_t map_zone; uma_zone_t map_zone;
/* media and phy */
struct ifmedia media;
struct utopia utopia;
#ifdef EN_DEBUG #ifdef EN_DEBUG
/* debugging */ /* debugging */
u_int debug; u_int debug;

View File

@ -60,15 +60,18 @@ __FBSDID("$FreeBSD$");
#include <net/if.h> #include <net/if.h>
#include <net/if_atm.h> #include <net/if_atm.h>
#include <net/if_media.h>
#include <pci/pcivar.h> #include <pci/pcivar.h>
#include <pci/pcireg.h> #include <pci/pcireg.h>
#include <dev/utopia/utopia.h>
#include <dev/en/midwayreg.h> #include <dev/en/midwayreg.h>
#include <dev/en/midwayvar.h> #include <dev/en/midwayvar.h>
MODULE_DEPEND(en, pci, 1, 1, 1); MODULE_DEPEND(en, pci, 1, 1, 1);
MODULE_DEPEND(en, atm, 1, 1, 1); MODULE_DEPEND(en, atm, 1, 1, 1);
MODULE_DEPEND(en, utopia, 1, 1, 1);
/* /*
* local structures * local structures