svn commit: r187965 - user/thompsa/usb/sys/dev/usb2/ethernet
Andrew Thompson
thompsa at FreeBSD.org
Sat Jan 31 12:47:29 PST 2009
Author: thompsa
Date: Sat Jan 31 20:47:27 2009
New Revision: 187965
URL: http://svn.freebsd.org/changeset/base/187965
Log:
Move most of the ifnet logic into the usb2_ethernet module, this includes,
- make all usb ethernet interfaces named ue%d
- handle all threading in usb2_ethernet
- provide default ioctl handler
- handle mbuf rx
- provide locked callbacks for init,start,stop,etc
The drivers are not much more than data pushers now.
Modified:
user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c
user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h
user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c
user/thompsa/usb/sys/dev/usb2/ethernet/if_axereg.h
user/thompsa/usb/sys/dev/usb2/ethernet/if_cdce2.c
user/thompsa/usb/sys/dev/usb2/ethernet/if_cue2.c
user/thompsa/usb/sys/dev/usb2/ethernet/if_cuereg.h
user/thompsa/usb/sys/dev/usb2/ethernet/if_kue2.c
user/thompsa/usb/sys/dev/usb2/ethernet/if_kuereg.h
user/thompsa/usb/sys/dev/usb2/ethernet/if_rue2.c
user/thompsa/usb/sys/dev/usb2/ethernet/if_ruereg.h
user/thompsa/usb/sys/dev/usb2/ethernet/if_udav2.c
user/thompsa/usb/sys/dev/usb2/ethernet/if_udavreg.h
user/thompsa/usb/sys/dev/usb2/ethernet/usb2_ethernet.c
user/thompsa/usb/sys/dev/usb2/ethernet/usb2_ethernet.h
Modified: user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c
==============================================================================
--- user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c Sat Jan 31 20:46:01 2009 (r187964)
+++ user/thompsa/usb/sys/dev/usb2/ethernet/if_aue2.c Sat Jan 31 20:47:27 2009 (r187965)
@@ -185,13 +185,6 @@ static usb2_callback_t aue_bulk_read_cal
static usb2_callback_t aue_bulk_write_clear_stall_callback;
static usb2_callback_t aue_bulk_write_callback;
-static usb2_task_fn_t aue_promisc_task;
-static usb2_task_fn_t aue_ifmedia_task;
-static usb2_task_fn_t aue_setmulti_task;
-static usb2_task_fn_t aue_tick_task;
-
-static int aue_do_request(struct aue_softc *,
- struct usb2_device_request *, void *);
static uint8_t aue_csr_read_1(struct aue_softc *, uint16_t);
static uint16_t aue_csr_read_2(struct aue_softc *, uint16_t);
static int aue_csr_write_1(struct aue_softc *, uint16_t, uint8_t);
@@ -199,19 +192,16 @@ static int aue_csr_write_2(struct aue_so
static void aue_eeprom_getword(struct aue_softc *, int, uint16_t *);
static void aue_read_eeprom(struct aue_softc *, uint8_t *, uint16_t,
uint16_t);
-static void aue_setmulti(struct aue_softc *);
-static void aue_setpromisc(struct aue_softc *);
static void aue_reset(struct aue_softc *);
static void aue_reset_pegasus_II(struct aue_softc *);
-static void aue_start(struct ifnet *);
-static void aue_init(void *);
-static void aue_init_locked(struct aue_softc *);
-static void aue_stop(struct aue_softc *);
-static void aue_start_transfers(struct aue_softc *);
+static void aue_init(struct usb2_ether *);
+static void aue_stop(struct usb2_ether *);
+static void aue_start(struct usb2_ether *);
+static void aue_tick(struct usb2_ether *);
+static void aue_setmulti(struct usb2_ether *);
+static void aue_setpromisc(struct usb2_ether *);
static int aue_ifmedia_upd(struct ifnet *);
static void aue_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-static int aue_ioctl(struct ifnet *, u_long, caddr_t);
-static void aue_watchdog(void *);
static const struct usb2_config aue_config[AUE_N_TRANSFER] = {
@@ -311,18 +301,6 @@ MODULE_DEPEND(aue, usb2_core, 1, 1, 1);
MODULE_DEPEND(aue, ether, 1, 1, 1);
MODULE_DEPEND(aue, miibus, 1, 1, 1);
-static int
-aue_do_request(struct aue_softc *sc, struct usb2_device_request *req,
- void *data)
-{
- usb2_error_t err;
-
- err = usb2_do_request_flags(sc->sc_udev, &sc->sc_mtx, req, data, 0,
- NULL, 1000);
-
- return (err);
-}
-
#define AUE_SETBIT(sc, reg, x) \
aue_csr_write_1(sc, reg, aue_csr_read_1(sc, reg) | (x))
@@ -342,7 +320,7 @@ aue_csr_read_1(struct aue_softc *sc, uin
USETW(req.wIndex, reg);
USETW(req.wLength, 1);
- err = aue_do_request(sc, &req, &val);
+ err = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val);
if (err)
return (0);
return (val);
@@ -361,7 +339,7 @@ aue_csr_read_2(struct aue_softc *sc, uin
USETW(req.wIndex, reg);
USETW(req.wLength, 2);
- err = aue_do_request(sc, &req, &val);
+ err = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val);
if (err)
return (0);
return (le16toh(val));
@@ -379,7 +357,7 @@ aue_csr_write_1(struct aue_softc *sc, ui
USETW(req.wIndex, reg);
USETW(req.wLength, 1);
- return (aue_do_request(sc, &req, &val));
+ return (usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val));
}
static int
@@ -395,7 +373,7 @@ aue_csr_write_2(struct aue_softc *sc, ui
val = htole16(val);
- return (aue_do_request(sc, &req, &val));
+ return (usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, &val));
}
/*
@@ -440,16 +418,12 @@ static int
aue_miibus_readreg(device_t dev, int phy, int reg)
{
struct aue_softc *sc = device_get_softc(dev);
- int i, do_unlock;
+ int i, locked;
uint16_t val = 0;
- /* avoid recursive locking */
- if (mtx_owned(&sc->sc_mtx)) {
- do_unlock = 0;
- } else {
+ locked = mtx_owned(&sc->sc_mtx);
+ if (!locked)
AUE_LOCK(sc);
- do_unlock = 1;
- }
/*
* The Am79C901 HomePNA PHY actually contains two transceivers: a 1Mbps
@@ -480,7 +454,7 @@ aue_miibus_readreg(device_t dev, int phy
val = aue_csr_read_2(sc, AUE_PHY_DATA);
done:
- if (do_unlock)
+ if (!locked)
AUE_UNLOCK(sc);
return (val);
}
@@ -489,18 +463,14 @@ static int
aue_miibus_writereg(device_t dev, int phy, int reg, int data)
{
struct aue_softc *sc = device_get_softc(dev);
- int i, do_unlock;
+ int i, locked;
if (phy == 3)
return (0);
- /* avoid recursive locking */
- if (mtx_owned(&sc->sc_mtx)) {
- do_unlock = 0;
- } else {
+ locked = mtx_owned(&sc->sc_mtx);
+ if (!locked)
AUE_LOCK(sc);
- do_unlock = 1;
- }
aue_csr_write_2(sc, AUE_PHY_DATA, data);
aue_csr_write_1(sc, AUE_PHY_ADDR, phy);
@@ -514,7 +484,7 @@ aue_miibus_writereg(device_t dev, int ph
if (i == AUE_TIMEOUT)
device_printf(sc->sc_dev, "MII read timed out\n");
- if (do_unlock)
+ if (!locked)
AUE_UNLOCK(sc);
return (0);
}
@@ -524,15 +494,11 @@ aue_miibus_statchg(device_t dev)
{
struct aue_softc *sc = device_get_softc(dev);
struct mii_data *mii = GET_MII(sc);
- uint8_t do_unlock;
+ int locked;
- /* avoid recursive locking */
- if (mtx_owned(&sc->sc_mtx)) {
- do_unlock = 0;
- } else {
+ locked = mtx_owned(&sc->sc_mtx);
+ if (!locked)
AUE_LOCK(sc);
- do_unlock = 1;
- }
AUE_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
@@ -558,27 +524,22 @@ aue_miibus_statchg(device_t dev)
auxmode = aue_miibus_readreg(dev, 0, 0x1b);
aue_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);
}
- if (do_unlock)
+ if (!locked)
AUE_UNLOCK(sc);
}
-static void
-aue_setmulti_task(void *context, struct usb2_task *task)
-{
- struct aue_softc *sc = context;
-
- aue_setmulti(sc);
-}
-
#define AUE_BITS 6
static void
-aue_setmulti(struct aue_softc *sc)
+aue_setmulti(struct usb2_ether *ue)
{
- struct ifnet *ifp = sc->sc_ifp;
+ struct aue_softc *sc = usb2_ether_getsc(ue);
+ struct ifnet *ifp = usb2_ether_getifp(ue);
struct ifmultiaddr *ifma;
uint32_t h = 0, i;
uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ AUE_LOCK_ASSERT(sc, MA_OWNED);
+
if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
AUE_SETBIT(sc, AUE_CTL0, AUE_CTL0_ALLMULTI);
return;
@@ -692,7 +653,7 @@ aue_attach(device_t dev)
{
struct usb2_attach_arg *uaa = device_get_ivars(dev);
struct aue_softc *sc = device_get_softc(dev);
- struct ifnet *ifp;
+ struct usb2_ether *ue = &sc->sc_ue;
uint8_t eaddr[ETHER_ADDR_LEN];
uint8_t iface_index;
int error;
@@ -705,14 +666,7 @@ aue_attach(device_t dev)
sc->sc_flags |= AUE_FLAG_VER_2; /* XXX currently undocumented */
device_set_usb2_desc(dev);
-
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
- usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
-
- USB_TASK_INIT(&sc->sc_promisc_task, aue_promisc_task, sc, &sc->sc_mtx);
- USB_TASK_INIT(&sc->sc_multi_task, aue_setmulti_task, sc, &sc->sc_mtx);
- USB_TASK_INIT(&sc->sc_media_task, aue_ifmedia_task, sc, &sc->sc_mtx);
- USB_TASK_INIT(&sc->sc_tick_task, aue_tick_task, sc, &sc->sc_mtx);
iface_index = AUE_IFACE_IDX;
error = usb2_transfer_setup(uaa->device, &iface_index,
@@ -722,12 +676,6 @@ aue_attach(device_t dev)
device_printf(dev, "allocating USB transfers failed!\n");
goto detach;
}
- error = usb2_proc_create(&sc->sc_tq, USB_PRI_MED,
- device_get_nameunit(dev));
- if (error) {
- device_printf(dev, "could not setup config thread!\n");
- goto detach;
- }
AUE_LOCK(sc);
/* reset the adapter */
@@ -737,45 +685,23 @@ aue_attach(device_t dev)
aue_read_eeprom(sc, eaddr, 0, 3);
AUE_UNLOCK(sc);
- ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL) {
- device_printf(dev, "could not if_alloc()\n");
- goto detach;
- }
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = aue_ioctl;
- ifp->if_start = aue_start;
- ifp->if_init = aue_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
- sc->sc_ifp = ifp;
+ ue->ue_sc = sc;
+ ue->ue_dev = dev;
+ ue->ue_mtx = &sc->sc_mtx;
+ ue->ue_start = aue_start;
+ ue->ue_init = aue_init;
+ ue->ue_stop = aue_stop;
+ ue->ue_tick = aue_tick;
+ ue->ue_setmulti = aue_setmulti;
+ ue->ue_setpromisc = aue_setpromisc;
+ ue->ue_mii_upd = aue_ifmedia_upd;
+ ue->ue_mii_sts = aue_ifmedia_sts;
- /*
- * Do MII setup.
- * NOTE: Doing this causes child devices to be attached to us,
- * which we would normally disconnect at in the detach routine
- * using device_delete_child(). However the USB code is set up
- * such that when this driver is removed, all children devices
- * are removed as well. In effect, the USB code ends up detaching
- * all of our children for us, so we don't have to do is ourselves
- * in aue_detach(). It's important to point this out since if
- * we *do* try to detach the child devices ourselves, we will
- * end up getting the children deleted twice, which will crash
- * the system.
- */
- error = mii_phy_probe(dev, &sc->sc_miibus,
- aue_ifmedia_upd, aue_ifmedia_sts);
+ error = usb2_ether_ifattach(ue, eaddr);
if (error) {
- device_printf(dev, "MII without any PHY!\n");
+ device_printf(dev, "could not attach interface\n");
goto detach;
}
-
- ether_ifattach(ifp, eaddr);
-
return (0); /* success */
detach:
@@ -787,23 +713,15 @@ static int
aue_detach(device_t dev)
{
struct aue_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
+ struct usb2_ether *ue = &sc->sc_ue;
AUE_LOCK(sc);
sc->sc_flags |= AUE_FLAG_DETACH;
- aue_stop(sc);
+ aue_stop(ue);
AUE_UNLOCK(sc);
usb2_transfer_unsetup(sc->sc_xfer, AUE_N_TRANSFER);
- usb2_proc_free(&sc->sc_tq);
-
- if (sc->sc_miibus)
- device_delete_child(dev, sc->sc_miibus);
- if (ifp) {
- ether_ifdetach(ifp);
- if_free(ifp);
- }
- usb2_callout_drain(&sc->sc_watchdog);
+ usb2_ether_ifdetach(ue);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -826,25 +744,24 @@ static void
aue_intr_callback(struct usb2_xfer *xfer)
{
struct aue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
struct aue_intrpkt pkt;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
- if (ifp && (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
- (xfer->actlen >= sizeof(pkt))) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) &&
+ xfer->actlen >= sizeof(pkt)) {
usb2_copy_out(xfer->frbuffers, 0, &pkt, sizeof(pkt));
- if (pkt.aue_txstat0) {
+ if (pkt.aue_txstat0)
ifp->if_oerrors++;
- }
if (pkt.aue_txstat0 & (AUE_TXSTAT0_LATECOLL &
- AUE_TXSTAT0_EXCESSCOLL)) {
+ AUE_TXSTAT0_EXCESSCOLL))
ifp->if_collisions++;
- }
}
+ /* FALLTHROUGH */
case USB_ST_SETUP:
if (sc->sc_flags & AUE_FLAG_INTR_STALL) {
usb2_transfer_start(sc->sc_xfer[AUE_INTR_CS_RD]);
@@ -881,8 +798,9 @@ static void
aue_bulk_read_callback(struct usb2_xfer *xfer)
{
struct aue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m = NULL;
+ struct usb2_ether *ue = &sc->sc_ue;
+ struct ifnet *ifp = usb2_ether_getifp(ue);
+ struct aue_rxpkt stat;
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
@@ -896,41 +814,28 @@ aue_bulk_read_callback(struct usb2_xfer
}
} else {
- if (xfer->actlen <= (4 + ETHER_CRC_LEN)) {
+ if (xfer->actlen <= (sizeof(stat) + ETHER_CRC_LEN)) {
ifp->if_ierrors++;
goto tr_setup;
}
- usb2_copy_out(xfer->frbuffers, xfer->actlen - 4, &sc->sc_rxpkt,
- sizeof(sc->sc_rxpkt));
+ usb2_copy_out(xfer->frbuffers,
+ xfer->actlen - sizeof(stat), &stat, sizeof(stat));
/*
* turn off all the non-error bits in the rx status
* word:
*/
- sc->sc_rxpkt.aue_rxstat &= AUE_RXSTAT_MASK;
-
- if (sc->sc_rxpkt.aue_rxstat) {
+ stat.aue_rxstat &= AUE_RXSTAT_MASK;
+ if (stat.aue_rxstat) {
ifp->if_ierrors++;
goto tr_setup;
}
/* No errors; receive the packet. */
- xfer->actlen -= (4 + ETHER_CRC_LEN);
+ xfer->actlen -= (sizeof(stat) + ETHER_CRC_LEN);
}
+ usb2_ether_rxbuf(ue, xfer, 0, xfer->actlen);
- m = usb2_ether_get_mbuf();
-
- if (m == NULL) {
- ifp->if_ierrors++;
- goto tr_setup;
- }
- xfer->actlen = min(xfer->actlen, m->m_len);
-
- usb2_copy_out(xfer->frbuffers, 0, m->m_data, xfer->actlen);
-
- ifp->if_ipackets++;
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = xfer->actlen;
-
+ /* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -940,17 +845,7 @@ tr_setup:
xfer->frlengths[0] = xfer->max_data_length;
usb2_start_hardware(xfer);
}
-
- /*
- * At the end of a USB callback it is always safe to unlock
- * the private mutex of a device! That is why we do the
- * "if_input" here, and not some lines up!
- */
- if (m) {
- AUE_UNLOCK(sc);
- (ifp->if_input) (ifp, m);
- AUE_LOCK(sc);
- }
+ usb2_ether_rxflush(ue);
return;
default: /* Error */
@@ -983,16 +878,16 @@ static void
aue_bulk_write_callback(struct usb2_xfer *xfer)
{
struct aue_softc *sc = xfer->priv_sc;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ifnet *ifp = usb2_ether_getifp(&sc->sc_ue);
struct mbuf *m;
uint8_t buf[2];
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
DPRINTFN(11, "transfer of %d bytes complete\n", xfer->actlen);
-
ifp->if_opackets++;
+ /* FALLTHROUGH */
case USB_ST_SETUP:
if (sc->sc_flags & AUE_FLAG_WRITE_STALL) {
@@ -1068,9 +963,9 @@ done:
}
static void
-aue_tick_task(void *context, struct usb2_task *task)
+aue_tick(struct usb2_ether *ue)
{
- struct aue_softc *sc = context;
+ struct aue_softc *sc = usb2_ether_getsc(ue);
struct mii_data *mii = GET_MII(sc);
AUE_LOCK_ASSERT(sc, MA_OWNED);
@@ -1080,27 +975,14 @@ aue_tick_task(void *context, struct usb2
&& mii->mii_media_status & IFM_ACTIVE &&
IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
sc->sc_flags |= AUE_FLAG_LINK;
- aue_start_transfers(sc);
+ aue_start(ue);
}
}
static void
-aue_start(struct ifnet *ifp)
+aue_start(struct usb2_ether *ue)
{
- struct aue_softc *sc = ifp->if_softc;
-
- AUE_LOCK(sc);
- aue_start_transfers(sc);
- AUE_UNLOCK(sc);
-}
-
-static void
-aue_start_transfers(struct aue_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
+ struct aue_softc *sc = usb2_ether_getsc(ue);
/*
* start the USB transfers, if not already started:
@@ -1111,19 +993,10 @@ aue_start_transfers(struct aue_softc *sc
}
static void
-aue_init(void *xsc)
+aue_init(struct usb2_ether *ue)
{
- struct aue_softc *sc = xsc;
-
- AUE_LOCK(sc);
- aue_init_locked(sc);
- AUE_UNLOCK(sc);
-}
-
-static void
-aue_init_locked(struct aue_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
+ struct aue_softc *sc = usb2_ether_getsc(ue);
+ struct ifnet *ifp = usb2_ether_getifp(ue);
int i;
AUE_LOCK_ASSERT(sc, MA_OWNED);
@@ -1140,10 +1013,10 @@ aue_init_locked(struct aue_softc *sc)
aue_csr_write_1(sc, AUE_PAR0 + i, IF_LLADDR(ifp)[i]);
/* update promiscuous setting */
- aue_setpromisc(sc);
+ aue_setpromisc(ue);
/* Load the multicast filter. */
- aue_setmulti(sc);
+ aue_setmulti(ue);
/* Enable RX and TX */
aue_csr_write_1(sc, AUE_CTL0, AUE_CTL0_RXSTAT_APPEND | AUE_CTL0_RX_ENB);
@@ -1153,22 +1026,16 @@ aue_init_locked(struct aue_softc *sc)
sc->sc_flags |= AUE_FLAG_READ_STALL | AUE_FLAG_WRITE_STALL;
ifp->if_drv_flags |= IFF_DRV_RUNNING;
- aue_start_transfers(sc);
- usb2_callout_reset(&sc->sc_watchdog, hz, aue_watchdog, sc);
+ aue_start(ue);
}
static void
-aue_promisc_task(void *context, struct usb2_task *task)
+aue_setpromisc(struct usb2_ether *ue)
{
- struct aue_softc *sc = context;
+ struct aue_softc *sc = usb2_ether_getsc(ue);
+ struct ifnet *ifp = usb2_ether_getifp(ue);
- aue_setpromisc(sc);
-}
-
-static void
-aue_setpromisc(struct aue_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
+ AUE_LOCK_ASSERT(sc, MA_OWNED);
/* if we want promiscuous mode, set the allframes bit: */
if (ifp->if_flags & IFF_PROMISC)
@@ -1184,17 +1051,10 @@ static int
aue_ifmedia_upd(struct ifnet *ifp)
{
struct aue_softc *sc = ifp->if_softc;
-
- usb2_proc_enqueue(&sc->sc_tq, &sc->sc_media_task);
- return (0);
-}
-
-static void
-aue_ifmedia_task(void *context, struct usb2_task *task)
-{
- struct aue_softc *sc = context;
struct mii_data *mii = GET_MII(sc);
+ AUE_LOCK_ASSERT(sc, MA_OWNED);
+
sc->sc_flags &= ~AUE_FLAG_LINK;
if (mii->mii_instance) {
struct mii_softc *miisc;
@@ -1203,6 +1063,7 @@ aue_ifmedia_task(void *context, struct u
mii_phy_reset(miisc);
}
mii_mediachg(mii);
+ return (0);
}
/*
@@ -1221,70 +1082,21 @@ aue_ifmedia_sts(struct ifnet *ifp, struc
ifmr->ifm_status = mii->mii_media_status;
}
-static int
-aue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
-{
- struct aue_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
- int error = 0;
-
- switch (command) {
- case SIOCSIFFLAGS:
- AUE_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- usb2_proc_enqueue(&sc->sc_tq,
- &sc->sc_promisc_task);
- else
- aue_init_locked(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- aue_stop(sc);
- }
- AUE_UNLOCK(sc);
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- usb2_proc_enqueue(&sc->sc_tq, &sc->sc_multi_task);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- mii = GET_MII(sc);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
- break;
- default:
- error = ether_ioctl(ifp, command, data);
- break;
- }
- return (error);
-}
-
-static void
-aue_watchdog(void *arg)
-{
- struct aue_softc *sc = arg;
-
- usb2_proc_enqueue(&sc->sc_tq, &sc->sc_tick_task);
- usb2_callout_reset(&sc->sc_watchdog, hz, aue_watchdog, sc);
-}
-
/*
* Stop the adapter and free any mbufs allocated to the
* RX and TX lists.
*/
static void
-aue_stop(struct aue_softc *sc)
+aue_stop(struct usb2_ether *ue)
{
- struct ifnet *ifp = sc->sc_ifp;
+ struct aue_softc *sc = usb2_ether_getsc(ue);
+ struct ifnet *ifp = usb2_ether_getifp(ue);
AUE_LOCK_ASSERT(sc, MA_OWNED);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
sc->sc_flags &= ~AUE_FLAG_LINK;
- usb2_callout_stop(&sc->sc_watchdog);
-
/*
* stop all the transfers, if not already stopped:
*/
@@ -1308,9 +1120,10 @@ static int
aue_shutdown(device_t dev)
{
struct aue_softc *sc = device_get_softc(dev);
+ struct usb2_ether *ue = &sc->sc_ue;
AUE_LOCK(sc);
- aue_stop(sc);
+ aue_stop(ue);
AUE_UNLOCK(sc);
return (0);
}
Modified: user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h
==============================================================================
--- user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h Sat Jan 31 20:46:01 2009 (r187964)
+++ user/thompsa/usb/sys/dev/usb2/ethernet/if_auereg.h Sat Jan 31 20:47:27 2009 (r187965)
@@ -186,8 +186,7 @@ enum {
#define AUE_RXSTAT_DRIBBLE 0x10
#define AUE_RXSTAT_MASK 0x1E
-#define GET_MII(sc) ((sc)->sc_miibus ? \
- device_get_softc((sc)->sc_miibus) : NULL)
+#define GET_MII(sc) usb2_ether_getmii(&(sc)->sc_ue)
struct aue_intrpkt {
uint8_t aue_txstat0;
@@ -202,26 +201,17 @@ struct aue_intrpkt {
struct aue_rxpkt {
uint16_t aue_pktlen;
uint8_t aue_rxstat;
+ uint8_t pad;
} __packed;
struct aue_softc {
- struct ifnet *sc_ifp;
- struct usb2_process sc_tq;
- struct usb2_callout sc_watchdog;
- struct mtx sc_mtx;
- struct aue_rxpkt sc_rxpkt;
-
- struct usb2_device *sc_udev;
- struct usb2_xfer *sc_xfer[AUE_N_TRANSFER];
- device_t sc_miibus;
- device_t sc_dev;
-
- struct usb2_task sc_media_task;
- struct usb2_task sc_multi_task;
- struct usb2_task sc_promisc_task;
- struct usb2_task sc_tick_task;
+ struct usb2_ether sc_ue;
+ struct mtx sc_mtx;
+ struct usb2_device *sc_udev;
+ struct usb2_xfer *sc_xfer[AUE_N_TRANSFER];
+ device_t sc_dev;
- uint16_t sc_flags;
+ int sc_flags;
#define AUE_FLAG_LSYS 0x0001 /* use Linksys reset */
#define AUE_FLAG_PNA 0x0002 /* has Home PNA */
#define AUE_FLAG_PII 0x0004 /* Pegasus II chip */
Modified: user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c
==============================================================================
--- user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c Sat Jan 31 20:46:01 2009 (r187964)
+++ user/thompsa/usb/sys/dev/usb2/ethernet/if_axe2.c Sat Jan 31 20:47:27 2009 (r187965)
@@ -164,21 +164,15 @@ static miibus_readreg_t axe_miibus_readr
static miibus_writereg_t axe_miibus_writereg;
static miibus_statchg_t axe_miibus_statchg;
-static usb2_task_fn_t axe_promisc_task;
-static usb2_task_fn_t axe_setmulti_task;
-static usb2_task_fn_t axe_ifmedia_task;
-static usb2_task_fn_t axe_tick_task;
-
-static int axe_ioctl(struct ifnet *, u_long, caddr_t);
-static void axe_init(void *);
-static void axe_init_locked(struct axe_softc *);
-static void axe_stop(struct axe_softc *);
-static int axe_cmd(struct axe_softc *, int, int, int, void *);
+static void axe_init(struct usb2_ether *);
+static void axe_stop(struct usb2_ether *);
+static void axe_start(struct usb2_ether *);
+static void axe_tick(struct usb2_ether *);
+static void axe_setmulti(struct usb2_ether *);
+static void axe_setpromisc(struct usb2_ether *);
static int axe_ifmedia_upd(struct ifnet *);
static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-static void axe_start(struct ifnet *);
-static void axe_start_transfers(struct axe_softc *);
-static void axe_watchdog(void *);
+static int axe_cmd(struct axe_softc *, int, int, int, void *);
static void axe_ax88178_init(struct axe_softc *);
static void axe_ax88772_init(struct axe_softc *);
static int axe_get_phyno(struct axe_softc *, int);
@@ -312,20 +306,14 @@ axe_miibus_readreg(device_t dev, int phy
{
struct axe_softc *sc = device_get_softc(dev);
uint16_t val;
- int do_unlock;
+ int locked;
- /* avoid recursive locking */
- if (mtx_owned(&sc->sc_mtx)) {
- do_unlock = 0;
- } else {
- AXE_LOCK(sc);
- do_unlock = 1;
- }
+ if (sc->sc_phyno != phy)
+ return (0);
- if (sc->sc_phyno != phy) {
- val = 0;
- goto done;
- }
+ locked = mtx_owned(&sc->sc_mtx);
+ if (!locked)
+ AXE_LOCK(sc);
axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val);
@@ -342,8 +330,7 @@ axe_miibus_readreg(device_t dev, int phy
val &= ~BMSR_EXTCAP;
}
-done:
- if (do_unlock)
+ if (!locked)
AXE_UNLOCK(sc);
return (val);
}
@@ -352,29 +339,23 @@ static int
axe_miibus_writereg(device_t dev, int phy, int reg, int val)
{
struct axe_softc *sc = device_get_softc(dev);
- int do_unlock;
+ int locked;
val = htole16(val);
- /* avoid recursive locking */
- if (mtx_owned(&sc->sc_mtx)) {
- do_unlock = 0;
- } else {
- AXE_LOCK(sc);
- do_unlock = 1;
- }
-
if (sc->sc_phyno != phy)
- goto done;
+ return (val);
+
+ locked = mtx_owned(&sc->sc_mtx);
+ if (!locked)
+ AXE_LOCK(sc);
axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val);
axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
-done:
- if (do_unlock) {
+ if (!locked)
AXE_UNLOCK(sc);
- }
return (0);
}
@@ -384,15 +365,11 @@ axe_miibus_statchg(device_t dev)
struct axe_softc *sc = device_get_softc(dev);
struct mii_data *mii = GET_MII(sc);
uint16_t val;
- int err, do_unlock;
+ int err, locked;
- /* avoid recursive locking */
- if (mtx_owned(&sc->sc_mtx)) {
- do_unlock = 0;
- } else {
+ locked = mtx_owned(&sc->sc_mtx);
+ if (!locked)
AXE_LOCK(sc);
- do_unlock = 1;
- }
val = (mii->mii_media_active & IFM_GMASK) == IFM_FDX ?
AXE_MEDIA_FULL_DUPLEX : 0;
@@ -415,7 +392,7 @@ axe_miibus_statchg(device_t dev)
if (err)
device_printf(dev, "media change failed, error %d\n", err);
- if (do_unlock)
+ if (!locked)
AXE_UNLOCK(sc);
}
@@ -426,17 +403,10 @@ static int
axe_ifmedia_upd(struct ifnet *ifp)
{
struct axe_softc *sc = ifp->if_softc;
-
- usb2_proc_enqueue(&sc->sc_tq, &sc->sc_media_task);
- return (0);
-}
-
-static void
-axe_ifmedia_task(void *context, struct usb2_task *task)
-{
- struct axe_softc *sc = context;
struct mii_data *mii = GET_MII(sc);
+ AXE_LOCK_ASSERT(sc, MA_OWNED);
+
sc->sc_flags &= ~AXE_FLAG_LINK;
if (mii->mii_instance) {
struct mii_softc *miisc;
@@ -445,6 +415,7 @@ axe_ifmedia_task(void *context, struct u
mii_phy_reset(miisc);
}
mii_mediachg(mii);
+ return (0);
}
/*
@@ -464,14 +435,17 @@ axe_ifmedia_sts(struct ifnet *ifp, struc
}
static void
-axe_setmulti(struct axe_softc *sc)
+axe_setmulti(struct usb2_ether *ue)
{
- struct ifnet *ifp = sc->sc_ifp;
+ struct axe_softc *sc = usb2_ether_getsc(ue);
+ struct ifnet *ifp = usb2_ether_getifp(ue);
struct ifmultiaddr *ifma;
uint32_t h = 0;
uint16_t rxmode;
uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ AXE_LOCK_ASSERT(sc, MA_OWNED);
+
axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode);
rxmode = le16toh(rxmode);
@@ -661,7 +635,7 @@ axe_attach(device_t dev)
{
struct usb2_attach_arg *uaa = device_get_ivars(dev);
struct axe_softc *sc = device_get_softc(dev);
- struct ifnet *ifp;
+ struct usb2_ether *ue = &sc->sc_ue;
uint8_t eaddr[ETHER_ADDR_LEN];
uint8_t iface_index;
int error;
@@ -673,27 +647,14 @@ axe_attach(device_t dev)
device_set_usb2_desc(dev);
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
- usb2_callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
-
- USB_TASK_INIT(&sc->sc_promisc_task, axe_promisc_task, sc, &sc->sc_mtx);
- USB_TASK_INIT(&sc->sc_multi_task, axe_setmulti_task, sc, &sc->sc_mtx);
- USB_TASK_INIT(&sc->sc_media_task, axe_ifmedia_task, sc, &sc->sc_mtx);
- USB_TASK_INIT(&sc->sc_tick_task, axe_tick_task, sc, &sc->sc_mtx);
iface_index = AXE_IFACE_IDX;
- error = usb2_transfer_setup(uaa->device, &iface_index,
- sc->sc_xfer, axe_config, AXE_N_TRANSFER,
- sc, &sc->sc_mtx);
+ error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
+ axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx);
if (error) {
device_printf(dev, "allocating USB transfers failed!\n");
goto detach;
}
- error = usb2_proc_create(&sc->sc_tq, USB_PRI_MED,
- device_get_nameunit(dev));
- if (error) {
- device_printf(dev, "could not setup config thread\n");
- goto detach;
- }
/*
* Load PHY indexes first. Needed by axe_xxx_init().
@@ -732,34 +693,23 @@ axe_attach(device_t dev)
axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs);
AXE_UNLOCK(sc);
- ifp = if_alloc(IFT_ETHER);
-
+ ue->ue_sc = sc;
+ ue->ue_dev = dev;
+ ue->ue_mtx = &sc->sc_mtx;
+ ue->ue_start = axe_start;
+ ue->ue_init = axe_init;
+ ue->ue_stop = axe_stop;
+ ue->ue_tick = axe_tick;
+ ue->ue_setmulti = axe_setmulti;
+ ue->ue_setpromisc = axe_setpromisc;
+ ue->ue_mii_upd = axe_ifmedia_upd;
+ ue->ue_mii_sts = axe_ifmedia_sts;
- if (ifp == NULL) {
- device_printf(dev, "could not if_alloc()\n");
- goto detach;
- }
- ifp->if_softc = sc;
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_ioctl = axe_ioctl;
- ifp->if_start = axe_start;
- ifp->if_init = axe_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
- ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
- IFQ_SET_READY(&ifp->if_snd);
- sc->sc_ifp = ifp;
-
- error = mii_phy_probe(dev, &sc->sc_miibus,
- axe_ifmedia_upd, axe_ifmedia_sts);
+ error = usb2_ether_ifattach(ue, eaddr);
if (error) {
- device_printf(dev, "MII without any PHY!\n");
+ device_printf(dev, "could not attach interface\n");
goto detach;
}
-
- ether_ifattach(ifp, eaddr);
-
return (0); /* success */
detach:
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-user
mailing list