Module Name: src Committed By: mrg Date: Sun Aug 4 09:03:46 UTC 2019
Modified Files: src/sys/dev/usb: if_axe.c if_ure.c if_urevar.h Log Message: convert axe(4) and ure(4) to usbnet. axe loses 838 lines (37%) and ure loses 716 lines (36%). To generate a diff of this commit: cvs rdiff -u -r1.103 -r1.104 src/sys/dev/usb/if_axe.c cvs rdiff -u -r1.14 -r1.15 src/sys/dev/usb/if_ure.c cvs rdiff -u -r1.3 -r1.4 src/sys/dev/usb/if_urevar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/if_axe.c diff -u src/sys/dev/usb/if_axe.c:1.103 src/sys/dev/usb/if_axe.c:1.104 --- src/sys/dev/usb/if_axe.c:1.103 Thu Aug 1 01:19:21 2019 +++ src/sys/dev/usb/if_axe.c Sun Aug 4 09:03:46 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_axe.c,v 1.103 2019/08/01 01:19:21 mrg Exp $ */ +/* $NetBSD: if_axe.c,v 1.104 2019/08/04 09:03:46 mrg Exp $ */ /* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */ /* @@ -87,44 +87,22 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.103 2019/08/01 01:19:21 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.104 2019/08/04 09:03:46 mrg Exp $"); #ifdef _KERNEL_OPT -#include "opt_inet.h" #include "opt_usb.h" #include "opt_net_mpsafe.h" #endif #include <sys/param.h> -#include <sys/bus.h> -#include <sys/device.h> #include <sys/kernel.h> -#include <sys/mbuf.h> #include <sys/module.h> -#include <sys/mutex.h> #include <sys/socket.h> #include <sys/sockio.h> #include <sys/systm.h> -#include <sys/rndsource.h> - -#include <net/if.h> -#include <net/if_dl.h> -#include <net/if_ether.h> -#include <net/if_media.h> - -#include <net/bpf.h> - -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/usb/usb.h> +#include <dev/usb/usbnet.h> #include <dev/usb/usbhist.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usbdevs.h> - #include <dev/usb/if_axereg.h> struct axe_type { @@ -132,32 +110,9 @@ struct axe_type { uint16_t axe_flags; }; -struct axe_softc; - -struct axe_chain { - struct axe_softc *axe_sc; - struct usbd_xfer *axe_xfer; - uint8_t *axe_buf; -}; - -struct axe_cdata { - struct axe_chain axe_tx_chain[AXE_TX_LIST_CNT]; - struct axe_chain axe_rx_chain[AXE_RX_LIST_CNT]; - int axe_tx_prod; - int axe_tx_cnt; -}; - struct axe_softc { - device_t axe_dev; - struct ethercom axe_ec; - struct mii_data axe_mii; - krndsource_t rnd_source; - struct usbd_device * axe_udev; - struct usbd_interface * axe_iface; - - uint16_t axe_vendor; - uint16_t axe_product; - uint16_t axe_timer; + struct usbnet axe_un; + uint32_t axe_flags; /* copied from axe_type */ #define AX178 __BIT(0) /* AX88178 */ #define AX772 __BIT(1) /* AX88772 */ @@ -166,40 +121,11 @@ struct axe_softc { #define AXSTD_FRAME __BIT(12) #define AXCSUM_FRAME __BIT(13) - int axe_ed[AXE_ENDPT_MAX]; - struct usbd_pipe * axe_ep[AXE_ENDPT_MAX]; - int axe_if_flags; - int axe_phyno; - struct axe_cdata axe_cdata; - struct callout axe_stat_ch; - - uint8_t axe_enaddr[ETHER_ADDR_LEN]; - - int axe_refcnt; - bool axe_dying; - bool axe_stopping; - bool axe_attached; - - struct usb_task axe_tick_task; - - kmutex_t axe_lock; - kmutex_t axe_mii_lock; - kmutex_t axe_rxlock; - kmutex_t axe_txlock; - kcondvar_t axe_detachcv; - - int axe_link; - uint8_t axe_ipgs[3]; uint8_t axe_phyaddrs[2]; uint16_t sc_pwrcfg; uint16_t sc_lenmask; - struct timeval axe_rx_notice; - struct timeval axe_tx_notice; - int axe_bufsz; - -#define sc_if axe_ec.ec_if }; #define AXE_IS_178_FAMILY(sc) \ @@ -331,97 +257,34 @@ static const struct ax88772b_mfb ax88772 int axe_match(device_t, cfdata_t, void *); void axe_attach(device_t, device_t, void *); -int axe_detach(device_t, int); -int axe_activate(device_t, devact_t); CFATTACH_DECL_NEW(axe, sizeof(struct axe_softc), - axe_match, axe_attach, axe_detach, axe_activate); + axe_match, axe_attach, usbnet_detach, usbnet_activate); -static int axe_tx_list_init(struct axe_softc *); -static int axe_rx_list_init(struct axe_softc *); -static int axe_encap(struct axe_softc *, struct mbuf *, int); -static void axe_rxeof(struct usbd_xfer *, void *, usbd_status); -static void axe_txeof(struct usbd_xfer *, void *, usbd_status); -static void axe_tick(void *); -static void axe_tick_task(void *); -static void axe_start(struct ifnet *); -static void axe_start_locked(struct ifnet *); -static int axe_ioctl(struct ifnet *, u_long, void *); +static void axe_rx_loop_cb(struct usbnet *, struct usbd_xfer *, + struct usbnet_chain *, uint32_t); +static unsigned axe_tx_prepare_cb(struct usbnet *, struct mbuf *, + struct usbnet_chain *); static int axe_init(struct ifnet *); -static int axe_init_locked(struct ifnet *); -static void axe_stop(struct ifnet *, int); -static void axe_stop_locked(struct ifnet *, int); -static void axe_watchdog(struct ifnet *); -static int axe_miibus_readreg(device_t, int, int, uint16_t *); -static int axe_miibus_readreg_locked(device_t, int, int, uint16_t *); -static int axe_miibus_writereg(device_t, int, int, uint16_t); -static int axe_miibus_writereg_locked(device_t, int, int, uint16_t); -static void axe_miibus_statchg(struct ifnet *); -static int axe_cmd(struct axe_softc *, int, int, int, void *); -static void axe_reset(struct axe_softc *); - -static void axe_setmulti(struct axe_softc *); -static void axe_setmulti_locked(struct axe_softc *); -static void axe_lock_mii(struct axe_softc *); -static void axe_unlock_mii(struct axe_softc *); +static void axe_stop_cb(struct ifnet *, int); +static int axe_ioctl_cb(struct ifnet *, u_long, void *); static void axe_ax88178_init(struct axe_softc *); static void axe_ax88772_init(struct axe_softc *); static void axe_ax88772a_init(struct axe_softc *); static void axe_ax88772b_init(struct axe_softc *); -/* Get exclusive access to the MII registers */ -static void -axe_lock_mii(struct axe_softc *sc) -{ - - mutex_enter(&sc->axe_lock); - sc->axe_refcnt++; - mutex_exit(&sc->axe_lock); - - mutex_enter(&sc->axe_mii_lock); -} - -static void -axe_lock_mii_sc_locked(struct axe_softc *sc) -{ - KASSERT(mutex_owned(&sc->axe_lock)); - - sc->axe_refcnt++; - mutex_enter(&sc->axe_mii_lock); -} - -static void -axe_unlock_mii(struct axe_softc *sc) -{ - - mutex_exit(&sc->axe_mii_lock); - mutex_enter(&sc->axe_lock); - if (--sc->axe_refcnt < 0) - cv_broadcast(&sc->axe_detachcv); - mutex_exit(&sc->axe_lock); -} - -static void -axe_unlock_mii_sc_locked(struct axe_softc *sc) -{ - KASSERT(mutex_owned(&sc->axe_lock)); - - mutex_exit(&sc->axe_mii_lock); - if (--sc->axe_refcnt < 0) - cv_broadcast(&sc->axe_detachcv); -} - -static int +static usbd_status axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) { AXEHIST_FUNC(); AXEHIST_CALLED(); + struct usbnet * const un = &sc->axe_un; usb_device_request_t req; usbd_status err; - KASSERT(mutex_owned(&sc->axe_mii_lock)); + usbnet_isowned_mii(un); - if (sc->axe_dying) + if (un->un_dying) return -1; DPRINTFN(20, "cmd %#jx index %#jx val %#jx", cmd, index, val, 0); @@ -435,30 +298,21 @@ axe_cmd(struct axe_softc *sc, int cmd, i USETW(req.wIndex, index); USETW(req.wLength, AXE_CMD_LEN(cmd)); - err = usbd_do_request(sc->axe_udev, &req, buf); - - if (err) { + err = usbd_do_request(un->un_udev, &req, buf); + if (err) DPRINTF("cmd %jd err %jd", cmd, err, 0, 0); - return -1; - } - return 0; + + return err; } -static int -axe_miibus_readreg_locked(device_t dev, int phy, int reg, uint16_t *val) +static usbd_status +axe_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) { AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_softc *sc = device_private(dev); + struct axe_softc * const sc = usbnet_softc(un); usbd_status err; uint16_t data; - mutex_enter(&sc->axe_lock); - if (sc->axe_dying || sc->axe_phyno != phy) { - mutex_exit(&sc->axe_lock); - return -1; - } - mutex_exit(&sc->axe_lock); - DPRINTFN(30, "phy 0x%jx reg 0x%jx\n", phy, reg, 0, 0); axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); @@ -467,7 +321,7 @@ axe_miibus_readreg_locked(device_t dev, axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); if (err) { - aprint_error_dev(sc->axe_dev, "read PHY failed\n"); + aprint_error_dev(un->un_dev, "read PHY failed\n"); return err; } @@ -484,83 +338,40 @@ axe_miibus_readreg_locked(device_t dev, DPRINTFN(30, "phy 0x%jx reg 0x%jx val %#jx", phy, reg, *val, 0); - return 0; -} - -static int -axe_miibus_readreg(device_t dev, int phy, int reg, uint16_t *val) -{ - struct axe_softc *sc = device_private(dev); - int rv; - - mutex_enter(&sc->axe_lock); - if (sc->axe_dying || sc->axe_phyno != phy) { - mutex_exit(&sc->axe_lock); - return -1; - } - mutex_exit(&sc->axe_lock); - - axe_lock_mii(sc); - rv = axe_miibus_readreg_locked(dev, phy, reg, val); - axe_unlock_mii(sc); - - return rv; + return USBD_NORMAL_COMPLETION; } -static int -axe_miibus_writereg_locked(device_t dev, int phy, int reg, uint16_t aval) +static usbd_status +axe_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) { - struct axe_softc *sc = device_private(dev); + struct axe_softc * const sc = usbnet_softc(un); usbd_status err; - uint16_t val; + uint16_t aval; - val = htole16(aval); + aval = htole16(val); axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); - err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val); + err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &aval); axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); - if (err) { - aprint_error_dev(sc->axe_dev, "write PHY failed\n"); - return err; - } - - return 0; -} - -static int -axe_miibus_writereg(device_t dev, int phy, int reg, uint16_t aval) -{ - struct axe_softc *sc = device_private(dev); - int rv; - - mutex_enter(&sc->axe_lock); - if (sc->axe_dying || sc->axe_phyno != phy) { - mutex_exit(&sc->axe_lock); - return -1; - } - mutex_exit(&sc->axe_lock); - - axe_lock_mii(sc); - rv = axe_miibus_writereg_locked(dev, phy, reg, aval); - axe_unlock_mii(sc); - - return rv; + return err; } static void -axe_miibus_statchg(struct ifnet *ifp) +axe_mii_statchg_cb(struct ifnet *ifp) { AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_softc * const sc = ifp->if_softc; - struct mii_data *mii = &sc->axe_mii; + struct usbnet * const un = ifp->if_softc; + struct axe_softc * const sc = usbnet_softc(un); + struct mii_data *mii = &un->un_mii; int val, err; - if (sc->axe_dying) + if (un->un_dying) return; val = 0; + un->un_link = false; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { val |= AXE_MEDIA_FULL_DUPLEX; if (AXE_IS_178_FAMILY(sc)) { @@ -579,45 +390,46 @@ axe_miibus_statchg(struct ifnet *ifp) switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_1000_T: val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; + un->un_link = true; break; case IFM_100_TX: val |= AXE_178_MEDIA_100TX; + un->un_link = true; break; case IFM_10_T: - /* doesn't need to be handled */ + un->un_link = true; break; } } DPRINTF("val=0x%jx", val, 0, 0, 0); - axe_lock_mii(sc); + usbnet_lock_mii(un); err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); - axe_unlock_mii(sc); - if (err) { - aprint_error_dev(sc->axe_dev, "media change failed\n"); - return; - } + usbnet_unlock_mii(un); + if (err) + aprint_error_dev(un->un_dev, "media change failed\n"); } static void -axe_setmulti_locked(struct axe_softc *sc) +axe_setiff_locked(struct usbnet *un) { AXEHIST_FUNC(); AXEHIST_CALLED(); - struct ethercom *ec = &sc->axe_ec; - struct ifnet *ifp = &sc->sc_if; + struct axe_softc * const sc = usbnet_softc(un); + struct ifnet * const ifp = usbnet_ifp(un); + struct ethercom *ec = usbnet_ec(un); struct ether_multi *enm; struct ether_multistep step; uint32_t h = 0; uint16_t rxmode; uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - KASSERT(mutex_owned(&sc->axe_mii_lock)); + usbnet_isowned_mii(un); - if (sc->axe_dying) + if (un->un_dying) return; if (axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode)) { - aprint_error_dev(sc->axe_dev, "can't read rxmode"); + aprint_error_dev(un->un_dev, "can't read rxmode"); return; } rxmode = le16toh(rxmode); @@ -664,16 +476,18 @@ axe_setmulti_locked(struct axe_softc *sc } static void -axe_setmulti(struct axe_softc *sc) +axe_setiff(struct usbnet *un) { - axe_lock_mii(sc); - axe_setmulti_locked(sc); - axe_unlock_mii(sc); + usbnet_lock_mii(un); + axe_setiff_locked(un); + usbnet_unlock_mii(un); } static void -axe_ax_init(struct axe_softc *sc) +axe_ax_init(struct usbnet *un) { + struct axe_softc * const sc = usbnet_softc(un); + int cmd = AXE_178_CMD_READ_NODEID; if (sc->axe_flags & AX178) { @@ -689,18 +503,20 @@ axe_ax_init(struct axe_softc *sc) cmd = AXE_172_CMD_READ_NODEID; } - if (axe_cmd(sc, cmd, 0, 0, sc->axe_enaddr)) { - aprint_error_dev(sc->axe_dev, + if (axe_cmd(sc, cmd, 0, 0, un->un_eaddr)) { + aprint_error_dev(un->un_dev, "failed to read ethernet address\n"); } } static void -axe_reset(struct axe_softc *sc) +axe_reset(struct usbnet *un) { - if (sc->axe_dying) + usbnet_isowned_mii(un); + + if (un->un_dying) return; /* @@ -708,7 +524,7 @@ axe_reset(struct axe_softc *sc) * if_addr_init -> if_init. This doesn't mix well with the * usbd_delay_ms calls in the init routines as things like nd6_slowtimo * can fire during the wait and attempt to take softnet_lock and then - * block the softclk thread meaing the wait never ends. + * block the softclk thread meaning the wait never ends. */ #ifndef NET_MPSAFE /* XXX What to reset? */ @@ -716,11 +532,7 @@ axe_reset(struct axe_softc *sc) /* Wait a little while for the chip to get its brains in order. */ DELAY(1000); #else - axe_lock_mii_sc_locked(sc); - - axe_ax_init(sc); - - axe_unlock_mii_sc_locked(sc); + axe_ax_init(un); #endif } @@ -751,13 +563,14 @@ axe_get_phyno(struct axe_softc *sc, int #define AXE_GPIO_WRITE(x, y) do { \ axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL); \ - usbd_delay_ms(sc->axe_udev, hztoms(y)); \ + usbd_delay_ms(sc->axe_un.un_udev, hztoms(y)); \ } while (0) static void axe_ax88178_init(struct axe_softc *sc) { AXEHIST_FUNC(); AXEHIST_CALLED(); + struct usbnet * const un = &sc->axe_un; int gpio0, ledmode, phymode; uint16_t eeprom, val; @@ -841,16 +654,11 @@ axe_ax88178_init(struct axe_softc *sc) AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4); AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); if (phymode == AXE_PHY_MODE_REALTEK_8211CL) { - axe_miibus_writereg_locked(sc->axe_dev, - sc->axe_phyno, 0x1F, 0x0005); - axe_miibus_writereg_locked(sc->axe_dev, - sc->axe_phyno, 0x0C, 0x0000); - axe_miibus_readreg_locked(sc->axe_dev, - sc->axe_phyno, 0x0001, &val); - axe_miibus_writereg_locked(sc->axe_dev, - sc->axe_phyno, 0x01, val | 0x0080); - axe_miibus_writereg_locked(sc->axe_dev, - sc->axe_phyno, 0x1F, 0x0000); + axe_mii_write_reg(un, un->un_phyno, 0x1F, 0x0005); + axe_mii_write_reg(un, un->un_phyno, 0x0C, 0x0000); + axe_mii_read_reg(un, un->un_phyno, 0x0001, &val); + axe_mii_write_reg(un, un->un_phyno, 0x01, val | 0x0080); + axe_mii_write_reg(un, un->un_phyno, 0x1F, 0x0000); } break; default: @@ -860,13 +668,13 @@ axe_ax88178_init(struct axe_softc *sc) /* soft reset */ axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); - usbd_delay_ms(sc->axe_udev, 150); + usbd_delay_ms(un->un_udev, 150); axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); - usbd_delay_ms(sc->axe_udev, 150); + usbd_delay_ms(un->un_udev, 150); /* Enable MII/GMII/RGMII interface to work with external PHY. */ axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL); - usbd_delay_ms(sc->axe_udev, 10); + usbd_delay_ms(un->un_udev, 10); axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); } @@ -874,24 +682,25 @@ static void axe_ax88772_init(struct axe_softc *sc) { AXEHIST_FUNC(); AXEHIST_CALLED(); + struct usbnet * const un = &sc->axe_un; axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); - usbd_delay_ms(sc->axe_udev, 40); + usbd_delay_ms(un->un_udev, 40); - if (sc->axe_phyno == AXE_772_PHY_NO_EPHY) { + if (un->un_phyno == AXE_772_PHY_NO_EPHY) { /* ask for the embedded PHY */ axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_EMBEDDED, NULL); - usbd_delay_ms(sc->axe_udev, 10); + usbd_delay_ms(un->un_udev, 10); /* power down and reset state, pin reset state */ axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); - usbd_delay_ms(sc->axe_udev, 60); + usbd_delay_ms(un->un_udev, 60); /* power down/reset state, pin operating state */ axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); - usbd_delay_ms(sc->axe_udev, 150); + usbd_delay_ms(un->un_udev, 150); /* power up, reset */ axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL); @@ -903,14 +712,14 @@ axe_ax88772_init(struct axe_softc *sc) /* ask for external PHY */ axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_EXT, NULL); - usbd_delay_ms(sc->axe_udev, 10); + usbd_delay_ms(un->un_udev, 10); /* power down internal PHY */ axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); } - usbd_delay_ms(sc->axe_udev, 150); + usbd_delay_ms(un->un_udev, 150); axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); } @@ -918,12 +727,13 @@ static void axe_ax88772_phywake(struct axe_softc *sc) { AXEHIST_FUNC(); AXEHIST_CALLED(); + struct usbnet * const un = &sc->axe_un; - if (sc->axe_phyno == AXE_772_PHY_NO_EPHY) { + if (un->un_phyno == AXE_772_PHY_NO_EPHY) { /* Manually select internal(embedded) PHY - MAC mode. */ axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_EMBEDDED, NULL); - usbd_delay_ms(sc->axe_udev, hztoms(hz / 32)); + usbd_delay_ms(un->un_udev, hztoms(hz / 32)); } else { /* * Manually select external PHY - MAC mode. @@ -931,31 +741,31 @@ axe_ax88772_phywake(struct axe_softc *sc */ axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB | AXE_SW_PHY_SELECT_EXT | AXE_SW_PHY_SELECT_SS_MII, NULL); - usbd_delay_ms(sc->axe_udev, hztoms(hz / 32)); + usbd_delay_ms(un->un_udev, hztoms(hz / 32)); } axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD | AXE_SW_RESET_IPRL, NULL); /* T1 = min 500ns everywhere */ - usbd_delay_ms(sc->axe_udev, 150); + usbd_delay_ms(un->un_udev, 150); /* Take PHY out of power down. */ - if (sc->axe_phyno == AXE_772_PHY_NO_EPHY) { + if (un->un_phyno == AXE_772_PHY_NO_EPHY) { axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL); } else { axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRTE, NULL); } /* 772 T2 is 60ms. 772A T2 is 160ms, 772B T2 is 600ms */ - usbd_delay_ms(sc->axe_udev, 600); + usbd_delay_ms(un->un_udev, 600); axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); /* T3 = 500ns everywhere */ - usbd_delay_ms(sc->axe_udev, hztoms(hz / 32)); + usbd_delay_ms(un->un_udev, hztoms(hz / 32)); axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL); - usbd_delay_ms(sc->axe_udev, hztoms(hz / 32)); + usbd_delay_ms(un->un_udev, hztoms(hz / 32)); } static void @@ -974,6 +784,7 @@ static void axe_ax88772b_init(struct axe_softc *sc) { AXEHIST_FUNC(); AXEHIST_CALLED(); + struct usbnet * const un = &sc->axe_un; uint16_t eeprom; int i; @@ -986,7 +797,7 @@ axe_ax88772b_init(struct axe_softc *sc) */ if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_PHY_PWRCFG, &eeprom)) { - aprint_error_dev(sc->axe_dev, "failed to read eeprom\n"); + aprint_error_dev(un->un_dev, "failed to read eeprom\n"); return; } @@ -997,11 +808,11 @@ axe_ax88772b_init(struct axe_softc *sc) * 00:00:00:00:00:00 such that an explicit access to EEPROM * is required to get real station address. */ - uint8_t *eaddr = sc->axe_enaddr; + uint8_t *eaddr = un->un_eaddr; for (i = 0; i < ETHER_ADDR_LEN / 2; i++) { if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_NODE_ID + i, &eeprom)) { - aprint_error_dev(sc->axe_dev, + aprint_error_dev(un->un_dev, "failed to read eeprom\n"); eeprom = 0; } @@ -1038,27 +849,39 @@ axe_attach(device_t parent, device_t sel { AXEHIST_FUNC(); AXEHIST_CALLED(); struct axe_softc *sc = device_private(self); + struct usbnet * const un = &sc->axe_un; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->uaa_device; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; - struct mii_data *mii; char *devinfop; - const char *devname = device_xname(self); - struct ifnet *ifp; + unsigned bufsz; int i; + /* Switch to usbnet for device_private() */ + self->dv_private = un; + aprint_naive("\n"); aprint_normal("\n"); - - sc->axe_dev = self; - sc->axe_udev = dev; - devinfop = usbd_devinfo_alloc(dev, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); + un->un_dev = self; + un->un_udev = dev; + un->un_sc = sc; + un->un_stop_cb = axe_stop_cb; + un->un_ioctl_cb = axe_ioctl_cb; + un->un_read_reg_cb = axe_mii_read_reg; + un->un_write_reg_cb = axe_mii_write_reg; + un->un_statchg_cb = axe_mii_statchg_cb; + un->un_tx_prepare_cb = axe_tx_prepare_cb; + un->un_rx_loop_cb = axe_rx_loop_cb; + un->un_init_cb = axe_init; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; + err = usbd_set_config_no(dev, AXE_CONFIG_NO, 1); if (err) { aprint_error_dev(self, "failed to set configuration" @@ -1068,33 +891,30 @@ axe_attach(device_t parent, device_t sel sc->axe_flags = axe_lookup(uaa->uaa_vendor, uaa->uaa_product)->axe_flags; - usb_init_task(&sc->axe_tick_task, axe_tick_task, sc, USB_TASKQ_MPSAFE); - - err = usbd_device2interface_handle(dev, AXE_IFACE_IDX, &sc->axe_iface); + err = usbd_device2interface_handle(dev, AXE_IFACE_IDX, &un->un_iface); if (err) { aprint_error_dev(self, "getting interface handle failed\n"); return; } - sc->axe_product = uaa->uaa_product; - sc->axe_vendor = uaa->uaa_vendor; - - id = usbd_get_interface_descriptor(sc->axe_iface); + id = usbd_get_interface_descriptor(un->un_iface); /* decide on what our bufsize will be */ if (AXE_IS_178_FAMILY(sc)) - sc->axe_bufsz = (sc->axe_udev->ud_speed == USB_SPEED_HIGH) ? + bufsz = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? AXE_178_MAX_BUFSZ : AXE_178_MIN_BUFSZ; else - sc->axe_bufsz = AXE_172_BUFSZ; - - sc->axe_ed[AXE_ENDPT_RX] = -1; - sc->axe_ed[AXE_ENDPT_TX] = -1; - sc->axe_ed[AXE_ENDPT_INTR] = -1; + bufsz = AXE_172_BUFSZ; + un->un_cdata.uncd_rx_bufsz = bufsz; + un->un_cdata.uncd_tx_bufsz = bufsz; + + un->un_ed[USBNET_ENDPT_RX] = 0; + un->un_ed[USBNET_ENDPT_TX] = 0; + un->un_ed[USBNET_ENDPT_INTR] = 0; /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->axe_iface, i); + ed = usbd_interface2endpoint_descriptor(un->un_iface, i); if (ed == NULL) { aprint_error_dev(self, "couldn't get ep %d\n", i); return; @@ -1103,51 +923,41 @@ axe_attach(device_t parent, device_t sel const uint8_t dir = UE_GET_DIR(ed->bEndpointAddress); if (dir == UE_DIR_IN && xt == UE_BULK && - sc->axe_ed[AXE_ENDPT_RX] == -1) { - sc->axe_ed[AXE_ENDPT_RX] = ed->bEndpointAddress; + un->un_ed[USBNET_ENDPT_RX] == 0) { + un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; } else if (dir == UE_DIR_OUT && xt == UE_BULK && - sc->axe_ed[AXE_ENDPT_TX] == -1) { - sc->axe_ed[AXE_ENDPT_TX] = ed->bEndpointAddress; + un->un_ed[USBNET_ENDPT_TX] == 0) { + un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; } else if (dir == UE_DIR_IN && xt == UE_INTERRUPT) { - sc->axe_ed[AXE_ENDPT_INTR] = ed->bEndpointAddress; + un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; } } /* Set these up now for axe_cmd(). */ - mutex_init(&sc->axe_mii_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&sc->axe_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&sc->axe_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&sc->axe_lock, MUTEX_DEFAULT, IPL_NONE); - cv_init(&sc->axe_detachcv, "axedet"); + usbnet_attach(un, "axedet", AXE_RX_LIST_CNT, AXE_TX_LIST_CNT); /* We need the PHYID for init dance in some cases */ - axe_lock_mii(sc); + usbnet_lock_mii(un); if (axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, &sc->axe_phyaddrs)) { aprint_error_dev(self, "failed to read phyaddrs\n"); - cv_destroy(&sc->axe_detachcv); - mutex_destroy(&sc->axe_lock); - mutex_destroy(&sc->axe_rxlock); - mutex_destroy(&sc->axe_txlock); - mutex_destroy(&sc->axe_mii_lock); - return; } DPRINTF(" phyaddrs[0]: %jx phyaddrs[1]: %jx", sc->axe_phyaddrs[0], sc->axe_phyaddrs[1], 0, 0); - sc->axe_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); - if (sc->axe_phyno == -1) - sc->axe_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); - if (sc->axe_phyno == -1) { + un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); + if (un->un_phyno == -1) + un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); + if (un->un_phyno == -1) { DPRINTF(" no valid PHY address found, assuming PHY address 0", 0, 0, 0, 0); - sc->axe_phyno = 0; + un->un_phyno = 0; } /* Initialize controller and get station address. */ - axe_ax_init(sc); + axe_ax_init(un); /* * Fetch IPG values. @@ -1160,42 +970,24 @@ axe_attach(device_t parent, device_t sel } else { if (axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->axe_ipgs)) { aprint_error_dev(self, "failed to read ipg\n"); - - cv_destroy(&sc->axe_detachcv); - mutex_destroy(&sc->axe_lock); - mutex_destroy(&sc->axe_rxlock); - mutex_destroy(&sc->axe_txlock); - mutex_destroy(&sc->axe_mii_lock); - + usbnet_unlock_mii(un); return; } } - axe_unlock_mii(sc); + usbnet_unlock_mii(un); /* * An ASIX chip was detected. Inform the world. */ aprint_normal_dev(self, "Ethernet address %s\n", - ether_sprintf(sc->axe_enaddr)); - - /* Initialize interface info.*/ - ifp = &sc->sc_if; - ifp->if_softc = sc; - strlcpy(ifp->if_xname, devname, IFNAMSIZ); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_extflags = IFEF_MPSAFE; - ifp->if_ioctl = axe_ioctl; - ifp->if_start = axe_start; - ifp->if_init = axe_init; - ifp->if_stop = axe_stop; - ifp->if_watchdog = axe_watchdog; - - IFQ_SET_READY(&ifp->if_snd); + ether_sprintf(un->un_eaddr)); if (AXE_IS_178_FAMILY(sc)) - sc->axe_ec.ec_capabilities = ETHERCAP_VLAN_MTU; + usbnet_ec(un)->ec_capabilities = ETHERCAP_VLAN_MTU; if (sc->axe_flags & AX772B) { + struct ifnet *ifp = usbnet_ifp(un); + ifp->if_capabilities = IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | @@ -1217,230 +1009,30 @@ axe_attach(device_t parent, device_t sel adv_pause = 0; adv_pause = 0; - /* Initialize MII/media info. */ - mii = &sc->axe_mii; - mii->mii_ifp = ifp; - mii->mii_readreg = axe_miibus_readreg; - mii->mii_writereg = axe_miibus_writereg; - mii->mii_statchg = axe_miibus_statchg; - mii->mii_flags = MIIF_AUTOTSLEEP; - - sc->axe_ec.ec_mii = mii; - ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus); - - mii_attach(sc->axe_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, - adv_pause); - - if (LIST_EMPTY(&mii->mii_phys)) { - ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); - ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); - } else - ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); - - /* Attach the interface. */ - if_attach(ifp); - ether_ifattach(ifp, sc->axe_enaddr); - rnd_attach_source(&sc->rnd_source, device_xname(sc->axe_dev), - RND_TYPE_NET, RND_FLAG_DEFAULT); - - callout_init(&sc->axe_stat_ch, CALLOUT_MPSAFE); - callout_setfunc(&sc->axe_stat_ch, axe_tick, sc); - - sc->axe_attached = true; - - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->axe_udev, sc->axe_dev); - - if (!pmf_device_register(self, NULL, NULL)) - aprint_error_dev(self, "couldn't establish power handler\n"); -} - -int -axe_detach(device_t self, int flags) -{ - AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_softc *sc = device_private(self); - struct ifnet *ifp = &sc->sc_if; - - mutex_enter(&sc->axe_lock); - sc->axe_dying = true; - mutex_exit(&sc->axe_lock); - - /* Detached before attached finished, so just bail out. */ - if (!sc->axe_attached) - return 0; - - pmf_device_deregister(self); - - callout_halt(&sc->axe_stat_ch, NULL); - usb_rem_task_wait(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER, - NULL); - - if (ifp->if_flags & IFF_RUNNING) { - IFNET_LOCK(ifp); - axe_stop(ifp, 1); - IFNET_UNLOCK(ifp); - } - - mutex_enter(&sc->axe_lock); - sc->axe_refcnt--; - while (sc->axe_refcnt > 0) { - /* Wait for processes to go away */ - cv_wait(&sc->axe_detachcv, &sc->axe_lock); - } - -#ifdef DIAGNOSTIC - if (sc->axe_ep[AXE_ENDPT_TX] != NULL || - sc->axe_ep[AXE_ENDPT_RX] != NULL || - sc->axe_ep[AXE_ENDPT_INTR] != NULL) - aprint_debug_dev(self, "detach has active endpoints\n"); -#endif - - mutex_exit(&sc->axe_lock); - - callout_destroy(&sc->axe_stat_ch); - rnd_detach_source(&sc->rnd_source); - mii_detach(&sc->axe_mii, MII_PHY_ANY, MII_OFFSET_ANY); - ifmedia_delete_instance(&sc->axe_mii.mii_media, IFM_INST_ANY); - ether_ifdetach(ifp); - if_detach(ifp); - - sc->axe_attached = false; - - usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->axe_udev, sc->axe_dev); - - cv_destroy(&sc->axe_detachcv); - mutex_destroy(&sc->axe_lock); - mutex_destroy(&sc->axe_rxlock); - mutex_destroy(&sc->axe_txlock); - mutex_destroy(&sc->axe_mii_lock); - - return 0; -} - -int -axe_activate(device_t self, devact_t act) -{ - AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_softc *sc = device_private(self); - - switch (act) { - case DVACT_DEACTIVATE: - if_deactivate(&sc->axe_ec.ec_if); - - mutex_enter(&sc->axe_lock); - sc->axe_dying = true; - mutex_exit(&sc->axe_lock); - - mutex_enter(&sc->axe_rxlock); - mutex_enter(&sc->axe_txlock); - sc->axe_stopping = true; - mutex_exit(&sc->axe_txlock); - mutex_exit(&sc->axe_rxlock); - - return 0; - default: - return EOPNOTSUPP; - } + usbnet_attach_ifp(un, true, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, + 0, adv_pause); } -static int -axe_rx_list_init(struct axe_softc *sc) -{ - AXEHIST_FUNC(); AXEHIST_CALLED(); - - struct axe_cdata *cd; - struct axe_chain *c; - int i; - - cd = &sc->axe_cdata; - for (i = 0; i < AXE_RX_LIST_CNT; i++) { - c = &cd->axe_rx_chain[i]; - c->axe_sc = sc; - if (c->axe_xfer == NULL) { - int err = usbd_create_xfer(sc->axe_ep[AXE_ENDPT_RX], - sc->axe_bufsz, 0, 0, &c->axe_xfer); - if (err) - return err; - c->axe_buf = usbd_get_buffer(c->axe_xfer); - } - } - - return 0; -} - -static int -axe_tx_list_init(struct axe_softc *sc) -{ - AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_cdata *cd; - struct axe_chain *c; - int i; - - cd = &sc->axe_cdata; - for (i = 0; i < AXE_TX_LIST_CNT; i++) { - c = &cd->axe_tx_chain[i]; - c->axe_sc = sc; - if (c->axe_xfer == NULL) { - int err = usbd_create_xfer(sc->axe_ep[AXE_ENDPT_TX], - sc->axe_bufsz, USBD_FORCE_SHORT_XFER, 0, - &c->axe_xfer); - if (err) - return err; - c->axe_buf = usbd_get_buffer(c->axe_xfer); - } - } - - cd->axe_tx_cnt = 0; - - return 0; -} - -/* - * A frame has been uploaded: pass the resulting mbuf chain up to - * the higher level protocols. - */ static void -axe_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) +axe_rx_loop_cb(struct usbnet * un, struct usbd_xfer *xfer, + struct usbnet_chain *c, uint32_t total_len) { AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_chain *c = (struct axe_chain *)priv; - struct axe_softc * const sc = c->axe_sc; - struct ifnet *ifp = &sc->sc_if; - uint8_t *buf = c->axe_buf; - uint32_t total_len; - struct mbuf *m; - - mutex_enter(&sc->axe_rxlock); - - if (sc->axe_dying || sc->axe_stopping || - status == USBD_INVAL || status == USBD_NOT_STARTED || - status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) { - mutex_exit(&sc->axe_rxlock); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (usbd_ratecheck(&sc->axe_rx_notice)) { - aprint_error_dev(sc->axe_dev, "usb errors on rx: %s\n", - usbd_errstr(status)); - } - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->axe_ep[AXE_ENDPT_RX]); - goto done; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); + struct axe_softc * const sc = usbnet_softc(un); + struct ifnet *ifp = usbnet_ifp(un); + uint8_t *buf = c->unc_buf; do { u_int pktlen = 0; u_int rxlen = 0; int flags = 0; + if ((sc->axe_flags & AXSTD_FRAME) != 0) { struct axe_sframe_hdr hdr; if (total_len < sizeof(hdr)) { ifp->if_ierrors++; - goto done; + break; } #if !defined(__NO_STRICT_ALIGNMENT) && __GNUC_PREREQ__(6, 1) @@ -1468,7 +1060,7 @@ axe_rxeof(struct usbd_xfer *xfer, void * (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK)) != AXE_RH1M_RXLEN_MASK) { ifp->if_ierrors++; - goto done; + break; } rxlen = le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK; @@ -1484,9 +1076,9 @@ axe_rxeof(struct usbd_xfer *xfer, void * } else if ((sc->axe_flags & AXCSUM_FRAME) != 0) { struct axe_csum_hdr csum_hdr; - if (total_len < sizeof(csum_hdr)) { + if (total_len < sizeof(csum_hdr)) { ifp->if_ierrors++; - goto done; + break; } memcpy(&csum_hdr, buf, sizeof(csum_hdr)); @@ -1509,7 +1101,7 @@ axe_rxeof(struct usbd_xfer *xfer, void * AXE_CSUM_RXBYTES(csum_hdr.len), AXE_CSUM_RXBYTES(csum_hdr.ilen), sc->sc_lenmask, 0); - goto done; + break; } /* * Get total transferred frame length including @@ -1524,7 +1116,7 @@ axe_rxeof(struct usbd_xfer *xfer, void * total_len, len, 0, 0); /* invalid length */ ifp->if_ierrors++; - goto done; + break; } buf += sizeof(csum_hdr); @@ -1558,190 +1150,22 @@ axe_rxeof(struct usbd_xfer *xfer, void * total_len = 0; } - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - ifp->if_ierrors++; - goto done; - } - - if (pktlen > MHLEN - ETHER_ALIGN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - m_freem(m); - ifp->if_ierrors++; - goto done; - } - } - m->m_data += ETHER_ALIGN; - - m_set_rcvif(m, ifp); - m->m_pkthdr.len = m->m_len = pktlen; - m->m_pkthdr.csum_flags = flags; - - memcpy(mtod(m, uint8_t *), buf, pktlen); + usbnet_enqueue(un, buf, pktlen, flags); buf += rxlen; - DPRINTFN(10, "deliver %jd (%#jx)", m->m_len, m->m_len, 0, 0); - - mutex_exit(&sc->axe_rxlock); - - if_percpuq_enqueue((ifp)->if_percpuq, (m)); - - mutex_enter(&sc->axe_rxlock); - if (sc->axe_dying || sc->axe_stopping) { - mutex_exit(&sc->axe_rxlock); - return; - } - } while (total_len > 0); - done: - - if (sc->axe_dying || sc->axe_stopping) { - mutex_exit(&sc->axe_rxlock); - return; - } - - mutex_exit(&sc->axe_rxlock); - - /* Setup new transfer. */ - usbd_setup_xfer(xfer, c, c->axe_buf, sc->axe_bufsz, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof); - usbd_transfer(xfer); - DPRINTFN(10, "start rx", 0, 0, 0, 0); } -/* - * A frame was downloaded to the chip. It's safe for us to clean up - * the list buffers. - */ - -static void -axe_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) -{ - AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_chain *c = priv; - struct axe_softc *sc = c->axe_sc; - struct axe_cdata *cd = &sc->axe_cdata; - struct ifnet *ifp = &sc->sc_if; - - mutex_enter(&sc->axe_txlock); - if (sc->axe_stopping || sc->axe_dying) { - mutex_exit(&sc->axe_txlock); - return; - } - - KASSERT(cd->axe_tx_cnt == 1); - cd->axe_tx_cnt--; - - sc->axe_timer = 0; - - switch (status) { - case USBD_NOT_STARTED: - case USBD_CANCELLED: - break; - - case USBD_NORMAL_COMPLETION: - ifp->if_opackets++; - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - axe_start_locked(ifp); - break; - - default: - - ifp->if_oerrors++; - if (usbd_ratecheck(&sc->axe_tx_notice)) - aprint_error_dev(sc->axe_dev, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->axe_ep[AXE_ENDPT_TX]); - break; - } - - mutex_exit(&sc->axe_txlock); -} - -static void -axe_tick(void *xsc) -{ - AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_softc *sc = xsc; - - if (sc == NULL) - return; - - mutex_enter(&sc->axe_lock); - if (!sc->axe_stopping && !sc->axe_dying) { - /* Perform periodic stuff in process context */ - usb_add_task(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER); - } - mutex_exit(&sc->axe_lock); - -} - -static void -axe_tick_task(void *xsc) +static unsigned +axe_tx_prepare_cb(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) { AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_softc *sc = xsc; - struct ifnet *ifp; - struct mii_data *mii; - - if (sc == NULL) - return; - - mutex_enter(&sc->axe_lock); - if (sc->axe_stopping || sc->axe_dying) { - mutex_exit(&sc->axe_lock); - return; - } - - ifp = &sc->sc_if; - mii = &sc->axe_mii; - - if (mii == NULL) { - mutex_exit(&sc->axe_lock); - return; - } - - sc->axe_refcnt++; - mutex_exit(&sc->axe_lock); - - if (sc->axe_timer != 0 && --sc->axe_timer == 0) - axe_watchdog(ifp); - - mii_tick(mii); - - if (sc->axe_link == 0 && - (mii->mii_media_status & IFM_ACTIVE) != 0 && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - DPRINTF("got link", 0, 0, 0, 0); - sc->axe_link++; - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - axe_start(ifp); - } - - - mutex_enter(&sc->axe_lock); - if (--sc->axe_refcnt < 0) - cv_broadcast(&sc->axe_detachcv); - if (!sc->axe_stopping && !sc->axe_dying) - callout_schedule(&sc->axe_stat_ch, hz); - mutex_exit(&sc->axe_lock); -} - -static int -axe_encap(struct axe_softc *sc, struct mbuf *m, int idx) -{ - struct ifnet *ifp = &sc->sc_if; - struct axe_chain *c; - usbd_status err; + struct axe_softc * const sc = usbnet_softc(un); int length, boundary; - KASSERT(mutex_owned(&sc->axe_txlock)); - - c = &sc->axe_cdata.axe_tx_chain[idx]; + usbnet_isowned_tx(un); /* * Copy the mbuf data into a contiguous buffer, leaving two @@ -1750,49 +1174,40 @@ axe_encap(struct axe_softc *sc, struct m if (AXE_IS_178_FAMILY(sc)) { struct axe_sframe_hdr hdr; - boundary = (sc->axe_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64; + boundary = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64; hdr.len = htole16(m->m_pkthdr.len); hdr.ilen = ~hdr.len; - memcpy(c->axe_buf, &hdr, sizeof(hdr)); + memcpy(c->unc_buf, &hdr, sizeof(hdr)); length = sizeof(hdr); - m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf + length); + m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + length); length += m->m_pkthdr.len; if ((length % boundary) == 0) { hdr.len = 0x0000; hdr.ilen = 0xffff; - memcpy(c->axe_buf + length, &hdr, sizeof(hdr)); + memcpy(c->unc_buf + length, &hdr, sizeof(hdr)); length += sizeof(hdr); } + DPRINTFN(20, "length %jx m_pkthdr.len %jx hdrsize %#jx", + length, m->m_pkthdr.len, sizeof(hdr), 0); } else { - m_copydata(m, 0, m->m_pkthdr.len, c->axe_buf); + m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf); length = m->m_pkthdr.len; + DPRINTFN(20, "length %jx", length, 0, 0, 0); } - usbd_setup_xfer(c->axe_xfer, c, c->axe_buf, length, - USBD_FORCE_SHORT_XFER, 10000, axe_txeof); - /* Transmit */ - err = usbd_transfer(c->axe_xfer); - if (err != USBD_IN_PROGRESS) { - /* XXXSMP IFNET_LOCK */ - axe_stop(ifp, 0); - return EIO; - } - - sc->axe_cdata.axe_tx_cnt++; - - return 0; + return length; } - static void axe_csum_cfg(struct axe_softc *sc) { - struct ifnet *ifp = &sc->sc_if; + struct usbnet * const un = &sc->axe_un; + struct ifnet * const ifp = usbnet_ifp(un); uint16_t csum1, csum2; if ((sc->axe_flags & AX772B) != 0) { @@ -1826,79 +1241,26 @@ axe_csum_cfg(struct axe_softc *sc) } } -static void -axe_start_locked(struct ifnet *ifp) -{ - struct axe_softc *sc = ifp->if_softc; - struct mbuf *m; - struct axe_cdata *cd = &sc->axe_cdata; - - KASSERT(mutex_owned(&sc->axe_txlock)); - - if (cd->axe_tx_cnt != 0) - return; - - if (sc->axe_link == 0 || (ifp->if_flags & IFF_RUNNING) == 0) - return; - - IFQ_POLL(&ifp->if_snd, m); - if (m == NULL) { - return; - } - - if (axe_encap(sc, m, 0)) { - return; - } - IFQ_DEQUEUE(&ifp->if_snd, m); - - /* - * If there's a BPF listener, bounce a copy of this frame - * to him. - */ - bpf_mtap(ifp, m, BPF_D_OUT); - m_freem(m); - - /* - * Set a timeout in case the chip goes out to lunch. - */ - sc->axe_timer = 5; - - return; -} - -static void -axe_start(struct ifnet *ifp) -{ - struct axe_softc * const sc = ifp->if_softc; - - mutex_enter(&sc->axe_txlock); - if (!sc->axe_stopping) - axe_start_locked(ifp); - mutex_exit(&sc->axe_txlock); -} - static int axe_init_locked(struct ifnet *ifp) { AXEHIST_FUNC(); AXEHIST_CALLED(); - struct axe_softc *sc = ifp->if_softc; - struct axe_chain *c; - usbd_status err; + struct usbnet * const un = ifp->if_softc; + struct axe_softc * const sc = usbnet_softc(un); int rxmode; - int i; - KASSERT(mutex_owned(&sc->axe_lock)); + usbnet_isowned(un); - if (sc->axe_dying) + if (un->un_dying) return EIO; /* Cancel pending I/O */ - axe_stop_locked(ifp, 0); + usbnet_stop(un, ifp, 1); - /* Reset the ethernet interface. */ - axe_reset(sc); + usbnet_lock_mii_un_locked(un); - axe_lock_mii_sc_locked(sc); + /* Reset the ethernet interface. */ + axe_reset(un); #if 0 ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | @@ -1906,11 +1268,11 @@ axe_init_locked(struct ifnet *ifp) #endif /* Set MAC address and transmitter IPG values. */ if (AXE_IS_178_FAMILY(sc)) { - axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, sc->axe_enaddr); + axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, un->un_eaddr); axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2], (sc->axe_ipgs[1] << 8) | (sc->axe_ipgs[0]), NULL); } else { - axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, sc->axe_enaddr); + axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, un->un_eaddr); axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL); axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL); axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL); @@ -1959,7 +1321,7 @@ axe_init_locked(struct ifnet *ifp) * maximum performance. */ #if 0 - if (sc->axe_udev->ud_speed == USB_SPEED_HIGH) { + if (un->un_udev->ud_speed == USB_SPEED_HIGH) { /* Largest possible USB buffer size for AX88178 */ } #endif @@ -1982,253 +1344,53 @@ axe_init_locked(struct ifnet *ifp) axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); /* Load the multicast filter. */ - axe_setmulti_locked(sc); - - axe_unlock_mii_sc_locked(sc); - - /* Open RX and TX pipes. */ - err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_RX], - USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->axe_ep[AXE_ENDPT_RX]); - if (err) { - aprint_error_dev(sc->axe_dev, "open rx pipe failed: %s\n", - usbd_errstr(err)); - return EIO; - } + axe_setiff_locked(un); - err = usbd_open_pipe(sc->axe_iface, sc->axe_ed[AXE_ENDPT_TX], - USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->axe_ep[AXE_ENDPT_TX]); - if (err) { - aprint_error_dev(sc->axe_dev, "open tx pipe failed: %s\n", - usbd_errstr(err)); - return EIO; - } + usbnet_unlock_mii_un_locked(un); - /* Init RX ring. */ - if (axe_rx_list_init(sc) != 0) { - aprint_error_dev(sc->axe_dev, "rx list init failed\n"); - return ENOBUFS; - } - - /* Init TX ring. */ - if (axe_tx_list_init(sc) != 0) { - aprint_error_dev(sc->axe_dev, "tx list init failed\n"); - return ENOBUFS; - } - - mutex_enter(&sc->axe_rxlock); - mutex_enter(&sc->axe_txlock); - sc->axe_stopping = false; - - /* Start up the receive pipe. */ - for (i = 0; i < AXE_RX_LIST_CNT; i++) { - c = &sc->axe_cdata.axe_rx_chain[i]; - usbd_setup_xfer(c->axe_xfer, c, c->axe_buf, sc->axe_bufsz, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof); - usbd_transfer(c->axe_xfer); - } - - mutex_exit(&sc->axe_txlock); - mutex_exit(&sc->axe_rxlock); - - /* Indicate we are up and running. */ - KASSERT(IFNET_LOCKED(ifp)); - ifp->if_flags |= IFF_RUNNING; - - callout_schedule(&sc->axe_stat_ch, hz); - return 0; + return usbnet_init_rx_tx(un, 0, USBD_FORCE_SHORT_XFER); } static int axe_init(struct ifnet *ifp) { - struct axe_softc * const sc = ifp->if_softc; + struct usbnet * const un = ifp->if_softc; - mutex_enter(&sc->axe_lock); + usbnet_lock(un); int ret = axe_init_locked(ifp); - mutex_exit(&sc->axe_lock); + usbnet_unlock(un); return ret; } static int -axe_ioctl(struct ifnet *ifp, u_long cmd, void *data) +axe_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data) { - struct axe_softc *sc = ifp->if_softc; - int error = 0; + struct usbnet * const un = ifp->if_softc; switch (cmd) { - case SIOCSIFFLAGS: - if ((error = ifioctl_common(ifp, cmd, data)) != 0) - break; - - switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { - case IFF_RUNNING: - axe_stop(ifp, 1); - break; - case IFF_UP: - axe_init(ifp); - break; - case IFF_UP | IFF_RUNNING: - if ((ifp->if_flags ^ sc->axe_if_flags) == IFF_PROMISC) - axe_setmulti(sc); - else - axe_init(ifp); - break; - } - mutex_enter(&sc->axe_rxlock); - mutex_enter(&sc->axe_txlock); - sc->axe_if_flags = ifp->if_flags; - mutex_exit(&sc->axe_txlock); - mutex_exit(&sc->axe_rxlock); + case SIOCADDMULTI: + case SIOCDELMULTI: + axe_setiff(un); break; - default: - if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET) - break; - - error = 0; - - if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) - axe_setmulti(sc); - - } - - return error; -} - -static void -axe_watchdog(struct ifnet *ifp) -{ - struct axe_softc * const sc = ifp->if_softc; - struct axe_chain *c; - usbd_status stat; - - ifp->if_oerrors++; - aprint_error_dev(sc->axe_dev, "watchdog timeout\n"); - - c = &sc->axe_cdata.axe_tx_chain[0]; - usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &stat); - axe_txeof(c->axe_xfer, c, stat); - - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - axe_start(ifp); -} - -/* - * Stop the adapter and free any mbufs allocated to the - * RX and TX lists. - */ -static void -axe_stop_locked(struct ifnet *ifp, int disable) -{ - struct axe_softc * const sc = ifp->if_softc; - usbd_status err; - int i; - - KASSERT(mutex_owned(&sc->axe_lock)); - - mutex_enter(&sc->axe_rxlock); - mutex_enter(&sc->axe_txlock); - sc->axe_stopping = true; - mutex_exit(&sc->axe_txlock); - mutex_exit(&sc->axe_rxlock); - - /* - * XXXSMP Would like to - * KASSERT(IFNET_LOCKED(ifp)) - * here but the locking order is: - * ifnet -> sc lock -> rxlock -> txlock - * and sc lock is already held. - */ - ifp->if_flags &= ~IFF_RUNNING; - sc->axe_timer = 0; - - callout_stop(&sc->axe_stat_ch); - sc->axe_link = 0; - - /* Stop transfers. */ - if (sc->axe_ep[AXE_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_RX]); - if (err) { - aprint_error_dev(sc->axe_dev, - "abort rx pipe failed: %s\n", usbd_errstr(err)); - } - } - - if (sc->axe_ep[AXE_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_TX]); - if (err) { - aprint_error_dev(sc->axe_dev, - "abort tx pipe failed: %s\n", usbd_errstr(err)); - } - } - - if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) { - err = usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]); - if (err) { - aprint_error_dev(sc->axe_dev, - "abort intr pipe failed: %s\n", usbd_errstr(err)); - } - } - - axe_reset(sc); - - /* Free RX resources. */ - for (i = 0; i < AXE_RX_LIST_CNT; i++) { - if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) { - usbd_destroy_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer); - sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL; - } - } - - /* Free TX resources. */ - for (i = 0; i < AXE_TX_LIST_CNT; i++) { - if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) { - usbd_destroy_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer); - sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL; - } - } - - /* Close pipes. */ - if (sc->axe_ep[AXE_ENDPT_RX] != NULL) { - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]); - if (err) { - aprint_error_dev(sc->axe_dev, - "close rx pipe failed: %s\n", usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_RX] = NULL; - } - - if (sc->axe_ep[AXE_ENDPT_TX] != NULL) { - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]); - if (err) { - aprint_error_dev(sc->axe_dev, - "close tx pipe failed: %s\n", usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_TX] = NULL; + break; } - if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) { - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]); - if (err) { - aprint_error_dev(sc->axe_dev, - "close intr pipe failed: %s\n", usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_INTR] = NULL; - } + return 0; } static void -axe_stop(struct ifnet *ifp, int disable) +axe_stop_cb(struct ifnet *ifp, int disable) { - struct axe_softc * const sc = ifp->if_softc; + struct usbnet * const un = ifp->if_softc; - mutex_enter(&sc->axe_lock); - axe_stop_locked(ifp, disable); - mutex_exit(&sc->axe_lock); + usbnet_lock_mii_un_locked(un); + axe_reset(un); + usbnet_unlock_mii_un_locked(un); } -MODULE(MODULE_CLASS_DRIVER, if_axe, NULL); +MODULE(MODULE_CLASS_DRIVER, if_axe, "usbnet"); #ifdef _MODULE #include "ioconf.c" Index: src/sys/dev/usb/if_ure.c diff -u src/sys/dev/usb/if_ure.c:1.14 src/sys/dev/usb/if_ure.c:1.15 --- src/sys/dev/usb/if_ure.c:1.14 Fri Jul 19 04:17:34 2019 +++ src/sys/dev/usb/if_ure.c Sun Aug 4 09:03:46 2019 @@ -1,6 +1,6 @@ -/* $NetBSD: if_ure.c,v 1.14 2019/07/19 04:17:34 mrg Exp $ */ - +/* $NetBSD: if_ure.c,v 1.15 2019/08/04 09:03:46 mrg Exp $ */ /* $OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $ */ + /*- * Copyright (c) 2015-2016 Kevin Lo <ke...@freebsd.org> * All rights reserved. @@ -30,7 +30,7 @@ /* RealTek RTL8152/RTL8153 10/100/Gigabit USB Ethernet device */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.14 2019/07/19 04:17:34 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.15 2019/08/04 09:03:46 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -38,46 +38,24 @@ __KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1 #endif #include <sys/param.h> -#include <sys/bus.h> #include <sys/systm.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/mutex.h> #include <sys/kernel.h> -#include <sys/socket.h> -#include <sys/device.h> - -#include <sys/rndsource.h> - -#include <net/if.h> -#include <net/if_dl.h> -#include <net/if_ether.h> -#include <net/if_media.h> -#include <net/bpf.h> - -#include <netinet/in.h> +#include <net/route.h> #include <netinet/in_offload.h> /* XXX for in_undefer_cksum() */ #ifdef INET6 #include <netinet6/in6_offload.h> /* XXX for in6_undefer_cksum() */ #endif -#include <dev/mii/mii.h> -#include <dev/mii/miivar.h> - -#include <dev/usb/usb.h> -#include <dev/usb/usbdi.h> -#include <dev/usb/usbdi_util.h> -#include <dev/usb/usbdivar.h> -#include <dev/usb/usbdevs.h> +#include <dev/usb/usbnet.h> #include <dev/ic/rtl81x9reg.h> /* XXX for RTK_GMEDIASTAT */ #include <dev/usb/if_urereg.h> #include <dev/usb/if_urevar.h> -#define URE_PRINTF(sc, fmt, args...) \ - device_printf((sc)->ure_dev, "%s: " fmt, __func__, ##args); +#define URE_PRINTF(un, fmt, args...) \ + device_printf((un)->un_dev, "%s: " fmt, __func__, ##args); #define URE_DEBUG #ifdef URE_DEBUG @@ -96,65 +74,31 @@ static const struct usb_devno ure_devs[] static int ure_match(device_t, cfdata_t, void *); static void ure_attach(device_t, device_t, void *); -static int ure_detach(device_t, int); -static int ure_activate(device_t, enum devact); - -static int ure_ctl(struct ure_softc *, uint8_t, uint16_t, uint16_t, - void *, int); -static int ure_read_mem(struct ure_softc *, uint16_t, uint16_t, void *, - int); -static int ure_write_mem(struct ure_softc *, uint16_t, uint16_t, void *, - int); -static uint8_t ure_read_1(struct ure_softc *, uint16_t, uint16_t); -static uint16_t ure_read_2(struct ure_softc *, uint16_t, uint16_t); -static uint32_t ure_read_4(struct ure_softc *, uint16_t, uint16_t); -static int ure_write_1(struct ure_softc *, uint16_t, uint16_t, uint32_t); -static int ure_write_2(struct ure_softc *, uint16_t, uint16_t, uint32_t); -static int ure_write_4(struct ure_softc *, uint16_t, uint16_t, uint32_t); -static uint16_t ure_ocp_reg_read(struct ure_softc *, uint16_t); -static void ure_ocp_reg_write(struct ure_softc *, uint16_t, uint16_t); - static int ure_init(struct ifnet *); -static void ure_stop(struct ifnet *, int); -static void ure_stop_locked(struct ifnet *, int); -static void ure_start(struct ifnet *); -static void ure_reset(struct ure_softc *); +static void ure_reset(struct usbnet *); static void ure_miibus_statchg(struct ifnet *); -static int ure_miibus_readreg(device_t, int, int, uint16_t *); -static int ure_miibus_writereg(device_t, int, int, uint16_t); -static void ure_lock_mii(struct ure_softc *); -static void ure_unlock_mii(struct ure_softc *); - -static int ure_encap(struct ure_softc *, struct mbuf *, int); static uint32_t ure_txcsum(struct mbuf *); -static void ure_rxeof(struct usbd_xfer *, void *, usbd_status); static int ure_rxcsum(struct ifnet *, struct ure_rxpkt *); -static void ure_txeof(struct usbd_xfer *, void *, usbd_status); -static int ure_rx_list_init(struct ure_softc *); -static int ure_tx_list_init(struct ure_softc *); - -static void ure_tick_task(void *); -static void ure_tick(void *); - -static int ure_ifmedia_upd(struct ifnet *); -static void ure_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static int ure_ioctl(struct ifnet *, u_long, void *); +static unsigned ure_tx_prepare(struct usbnet *, struct mbuf *, + struct usbnet_chain *); +static void ure_rxeof_loop(struct usbnet *, struct usbd_xfer *, + struct usbnet_chain *, uint32_t); static void ure_rtl8152_init(struct ure_softc *); static void ure_rtl8153_init(struct ure_softc *); static void ure_disable_teredo(struct ure_softc *); static void ure_init_fifo(struct ure_softc *); CFATTACH_DECL_NEW(ure, sizeof(struct ure_softc), ure_match, ure_attach, - ure_detach, ure_activate); + usbnet_detach, usbnet_activate); static int -ure_ctl(struct ure_softc *sc, uint8_t rw, uint16_t val, uint16_t index, +ure_ctl(struct usbnet *un, uint8_t rw, uint16_t val, uint16_t index, void *buf, int len) { usb_device_request_t req; usbd_status err; - if (sc->ure_dying) + if (un->un_dying) return 0; if (rw == URE_CTL_WRITE) @@ -168,7 +112,7 @@ ure_ctl(struct ure_softc *sc, uint8_t rw DPRINTFN(5, ("ure_ctl: rw %d, val 0x%04hu, index 0x%04hu, len %d\n", rw, val, index, len)); - err = usbd_do_request(sc->ure_udev, &req, buf); + err = usbd_do_request(un->un_udev, &req, buf); if (err) { DPRINTF(("ure_ctl: error %d\n", err)); return -1; @@ -178,23 +122,21 @@ ure_ctl(struct ure_softc *sc, uint8_t rw } static int -ure_read_mem(struct ure_softc *sc, uint16_t addr, uint16_t index, +ure_read_mem(struct usbnet *un, uint16_t addr, uint16_t index, void *buf, int len) { - - return ure_ctl(sc, URE_CTL_READ, addr, index, buf, len); + return ure_ctl(un, URE_CTL_READ, addr, index, buf, len); } static int -ure_write_mem(struct ure_softc *sc, uint16_t addr, uint16_t index, +ure_write_mem(struct usbnet *un, uint16_t addr, uint16_t index, void *buf, int len) { - - return ure_ctl(sc, URE_CTL_WRITE, addr, index, buf, len); + return ure_ctl(un, URE_CTL_WRITE, addr, index, buf, len); } static uint8_t -ure_read_1(struct ure_softc *sc, uint16_t reg, uint16_t index) +ure_read_1(struct usbnet *un, uint16_t reg, uint16_t index) { uint32_t val; uint8_t temp[4]; @@ -203,7 +145,7 @@ ure_read_1(struct ure_softc *sc, uint16_ shift = (reg & 3) << 3; reg &= ~3; - ure_read_mem(sc, reg, index, &temp, 4); + ure_read_mem(un, reg, index, &temp, 4); val = UGETDW(temp); val >>= shift; @@ -211,7 +153,7 @@ ure_read_1(struct ure_softc *sc, uint16_ } static uint16_t -ure_read_2(struct ure_softc *sc, uint16_t reg, uint16_t index) +ure_read_2(struct usbnet *un, uint16_t reg, uint16_t index) { uint32_t val; uint8_t temp[4]; @@ -220,7 +162,7 @@ ure_read_2(struct ure_softc *sc, uint16_ shift = (reg & 2) << 3; reg &= ~3; - ure_read_mem(sc, reg, index, &temp, 4); + ure_read_mem(un, reg, index, &temp, 4); val = UGETDW(temp); val >>= shift; @@ -228,16 +170,16 @@ ure_read_2(struct ure_softc *sc, uint16_ } static uint32_t -ure_read_4(struct ure_softc *sc, uint16_t reg, uint16_t index) +ure_read_4(struct usbnet *un, uint16_t reg, uint16_t index) { uint8_t temp[4]; - ure_read_mem(sc, reg, index, &temp, 4); + ure_read_mem(un, reg, index, &temp, 4); return UGETDW(temp); } static int -ure_write_1(struct ure_softc *sc, uint16_t reg, uint16_t index, uint32_t val) +ure_write_1(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val) { uint16_t byen; uint8_t temp[4]; @@ -254,11 +196,11 @@ ure_write_1(struct ure_softc *sc, uint16 } USETDW(temp, val); - return ure_write_mem(sc, reg, index | byen, &temp, 4); + return ure_write_mem(un, reg, index | byen, &temp, 4); } static int -ure_write_2(struct ure_softc *sc, uint16_t reg, uint16_t index, uint32_t val) +ure_write_2(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val) { uint16_t byen; uint8_t temp[4]; @@ -275,111 +217,84 @@ ure_write_2(struct ure_softc *sc, uint16 } USETDW(temp, val); - return ure_write_mem(sc, reg, index | byen, &temp, 4); + return ure_write_mem(un, reg, index | byen, &temp, 4); } static int -ure_write_4(struct ure_softc *sc, uint16_t reg, uint16_t index, uint32_t val) +ure_write_4(struct usbnet *un, uint16_t reg, uint16_t index, uint32_t val) { uint8_t temp[4]; USETDW(temp, val); - return ure_write_mem(sc, reg, index | URE_BYTE_EN_DWORD, &temp, 4); + return ure_write_mem(un, reg, index | URE_BYTE_EN_DWORD, &temp, 4); } static uint16_t -ure_ocp_reg_read(struct ure_softc *sc, uint16_t addr) +ure_ocp_reg_read(struct usbnet *un, uint16_t addr) { uint16_t reg; - ure_write_2(sc, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000); + ure_write_2(un, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000); reg = (addr & 0x0fff) | 0xb000; - return ure_read_2(sc, reg, URE_MCU_TYPE_PLA); + return ure_read_2(un, reg, URE_MCU_TYPE_PLA); } static void -ure_ocp_reg_write(struct ure_softc *sc, uint16_t addr, uint16_t data) +ure_ocp_reg_write(struct usbnet *un, uint16_t addr, uint16_t data) { uint16_t reg; - ure_write_2(sc, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000); + ure_write_2(un, URE_PLA_OCP_GPHY_BASE, URE_MCU_TYPE_PLA, addr & 0xf000); reg = (addr & 0x0fff) | 0xb000; - ure_write_2(sc, reg, URE_MCU_TYPE_PLA, data); + ure_write_2(un, reg, URE_MCU_TYPE_PLA, data); } -static int -ure_miibus_readreg(device_t dev, int phy, int reg, uint16_t *val) +static usbd_status +ure_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) { - struct ure_softc *sc = device_private(dev); - - mutex_enter(&sc->ure_lock); - if (sc->ure_dying || sc->ure_phyno != phy) { - mutex_exit(&sc->ure_lock); - return -1; - } - mutex_exit(&sc->ure_lock); - /* Let the rgephy driver read the URE_PLA_PHYSTATUS register. */ if (reg == RTK_GMEDIASTAT) { - *val = ure_read_1(sc, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA); - return 0; + *val = ure_read_1(un, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA); + return USBD_NORMAL_COMPLETION; } - ure_lock_mii(sc); - *val = ure_ocp_reg_read(sc, URE_OCP_BASE_MII + reg * 2); - ure_unlock_mii(sc); + *val = ure_ocp_reg_read(un, URE_OCP_BASE_MII + reg * 2); - return 0; + return USBD_NORMAL_COMPLETION; } -static int -ure_miibus_writereg(device_t dev, int phy, int reg, uint16_t val) +static usbd_status +ure_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) { - struct ure_softc *sc = device_private(dev); - - mutex_enter(&sc->ure_lock); - if (sc->ure_dying || sc->ure_phyno != phy) { - mutex_exit(&sc->ure_lock); - return -1; - } - mutex_exit(&sc->ure_lock); + ure_ocp_reg_write(un, URE_OCP_BASE_MII + reg * 2, val); - ure_lock_mii(sc); - ure_ocp_reg_write(sc, URE_OCP_BASE_MII + reg * 2, val); - ure_unlock_mii(sc); - - return 0; + return USBD_NORMAL_COMPLETION; } static void ure_miibus_statchg(struct ifnet *ifp) { - struct ure_softc *sc; - struct mii_data *mii; + struct usbnet * const un = ifp->if_softc; + struct ure_softc * const sc = usbnet_softc(un); + struct mii_data * const mii = usbnet_mii(un); - if (ifp == NULL || (ifp->if_flags & IFF_RUNNING) == 0) + if (un->un_dying) return; - sc = ifp->if_softc; - mii = GET_MII(sc); - - if (mii == NULL) - return; - - sc->ure_flags &= ~URE_FLAG_LINK; + un->un_link = false; if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_10_T: case IFM_100_TX: - sc->ure_flags |= URE_FLAG_LINK; + un->un_link = true; break; case IFM_1000_T: if ((sc->ure_flags & URE_FLAG_8152) != 0) break; - sc->ure_flags |= URE_FLAG_LINK; + un->un_link = true; break; default: break; @@ -387,55 +302,23 @@ ure_miibus_statchg(struct ifnet *ifp) } } -static int -ure_ifmedia_upd(struct ifnet *ifp) -{ - struct ure_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - int err; - - sc->ure_flags &= ~URE_FLAG_LINK; - if (mii->mii_instance) { - struct mii_softc *miisc; - LIST_FOREACH(miisc, &mii->mii_phys, mii_list) - mii_phy_reset(miisc); - } - - err = mii_mediachg(mii); - if (err == ENXIO) - return 0; /* XXX */ - else - return err; -} - static void -ure_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +ure_setiff_locked(struct usbnet *un) { - struct ure_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); - - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; -} - -static void -ure_iff_locked(struct ure_softc *sc) -{ - struct ethercom *ec = &sc->ure_ec; - struct ifnet *ifp = GET_IFP(sc); + struct ethercom *ec = usbnet_ec(un); + struct ifnet *ifp = usbnet_ifp(un); struct ether_multi *enm; struct ether_multistep step; uint32_t hashes[2] = { 0, 0 }; uint32_t hash; uint32_t rxmode; - KASSERT(mutex_owned(&sc->ure_lock)); + usbnet_isowned(un); - if (sc->ure_dying) + if (un->un_dying) return; - rxmode = ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA); + rxmode = ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA); rxmode &= ~URE_RCR_ACPT_ALL; /* @@ -482,659 +365,445 @@ allmulti: hashes[1] = hash; } - ure_write_4(sc, URE_PLA_MAR0, URE_MCU_TYPE_PLA, hashes[0]); - ure_write_4(sc, URE_PLA_MAR4, URE_MCU_TYPE_PLA, hashes[1]); - ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode); + ure_write_4(un, URE_PLA_MAR0, URE_MCU_TYPE_PLA, hashes[0]); + ure_write_4(un, URE_PLA_MAR4, URE_MCU_TYPE_PLA, hashes[1]); + ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode); } static void -ure_iff(struct ure_softc *sc) +ure_setiff(struct usbnet *un) { - mutex_enter(&sc->ure_lock); - ure_iff_locked(sc); - mutex_exit(&sc->ure_lock); + usbnet_lock(un); + ure_setiff_locked(un); + usbnet_unlock(un); } static void -ure_reset(struct ure_softc *sc) +ure_reset(struct usbnet *un) { int i; - KASSERT(mutex_owned(&sc->ure_lock)); + usbnet_isowned(un); - ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RST); + ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RST); for (i = 0; i < URE_TIMEOUT; i++) { - if (!(ure_read_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA) & + if (!(ure_read_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA) & URE_CR_RST)) break; - usbd_delay_ms(sc->ure_udev, 10); + usbd_delay_ms(un->un_udev, 10); } if (i == URE_TIMEOUT) - URE_PRINTF(sc, "reset never completed\n"); + URE_PRINTF(un, "reset never completed\n"); } static int ure_init_locked(struct ifnet *ifp) { - struct ure_softc * const sc = ifp->if_softc; - struct ure_chain *c; - usbd_status err; - int i; + struct usbnet * const un = ifp->if_softc; uint8_t eaddr[8]; - KASSERT(mutex_owned(&sc->ure_lock)); + usbnet_isowned(un); - if (sc->ure_dying) + if (un->un_dying) return EIO; /* Cancel pending I/O. */ if (ifp->if_flags & IFF_RUNNING) - ure_stop_locked(ifp, 1); + usbnet_stop(un, ifp, 1); /* Set MAC address. */ memset(eaddr, 0, sizeof(eaddr)); memcpy(eaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN); - ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG); - ure_write_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA | URE_BYTE_EN_SIX_BYTES, + ure_write_1(un, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG); + ure_write_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA | URE_BYTE_EN_SIX_BYTES, eaddr, 8); - ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); + ure_write_1(un, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); /* Reset the packet filter. */ - ure_write_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA) & + ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) & ~URE_FMC_FCR_MCU_EN); - ure_write_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA) | + ure_write_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_FMC, URE_MCU_TYPE_PLA) | URE_FMC_FCR_MCU_EN); /* Enable transmit and receive. */ - ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, - ure_read_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA) | URE_CR_RE | + ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, + ure_read_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA) | URE_CR_RE | URE_CR_TE); - ure_write_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) & + ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) & ~URE_RXDY_GATED_EN); /* Load the multicast filter. */ - ure_iff_locked(sc); - - /* Open RX and TX pipes. */ - err = usbd_open_pipe(sc->ure_iface, sc->ure_ed[URE_ENDPT_RX], - USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->ure_ep[URE_ENDPT_RX]); - if (err) { - URE_PRINTF(sc, "open rx pipe failed: %s\n", usbd_errstr(err)); - return EIO; - } - - err = usbd_open_pipe(sc->ure_iface, sc->ure_ed[URE_ENDPT_TX], - USBD_EXCLUSIVE_USE | USBD_MPSAFE, &sc->ure_ep[URE_ENDPT_TX]); - if (err) { - URE_PRINTF(sc, "open tx pipe failed: %s\n", usbd_errstr(err)); - return EIO; - } + ure_setiff_locked(un); - if (ure_rx_list_init(sc)) { - URE_PRINTF(sc, "rx list init failed\n"); - return ENOBUFS; - } - - if (ure_tx_list_init(sc)) { - URE_PRINTF(sc, "tx list init failed\n"); - return ENOBUFS; - } - - mutex_enter(&sc->ure_rxlock); - mutex_enter(&sc->ure_txlock); - sc->ure_stopping = false; - - /* Start up the receive pipe. */ - for (i = 0; i < URE_RX_LIST_CNT; i++) { - c = &sc->ure_cdata.rx_chain[i]; - usbd_setup_xfer(c->uc_xfer, c, c->uc_buf, sc->ure_bufsz, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ure_rxeof); - usbd_transfer(c->uc_xfer); - } - - mutex_exit(&sc->ure_txlock); - mutex_exit(&sc->ure_rxlock); - - /* Indicate we are up and running. */ - KASSERT(IFNET_LOCKED(ifp)); - ifp->if_flags |= IFF_RUNNING; - - callout_reset(&sc->ure_stat_ch, hz, ure_tick, sc); - - return 0; + return usbnet_init_rx_tx(un, 0, 0); } static int ure_init(struct ifnet *ifp) { - struct ure_softc * const sc = ifp->if_softc; + struct usbnet * const un = ifp->if_softc; - mutex_enter(&sc->ure_lock); + usbnet_lock(un); int ret = ure_init_locked(ifp); - mutex_exit(&sc->ure_lock); + usbnet_unlock(un); return ret; } static void -ure_start_locked(struct ifnet *ifp) -{ - struct ure_softc *sc = ifp->if_softc; - struct mbuf *m; - struct ure_cdata *cd = &sc->ure_cdata; - int idx; - - KASSERT(cd->tx_cnt <= URE_TX_LIST_CNT); - - if (sc->ure_dying || sc->ure_stopping || - (sc->ure_flags & URE_FLAG_LINK) == 0 || - (ifp->if_flags & IFF_RUNNING) == 0 || - cd->tx_cnt == URE_TX_LIST_CNT) { - return; - } - - idx = cd->tx_prod; - while (cd->tx_cnt < URE_TX_LIST_CNT) { - IFQ_POLL(&ifp->if_snd, m); - if (m == NULL) - break; - - if (ure_encap(sc, m, idx)) { - ifp->if_oerrors++; - break; - } - IFQ_DEQUEUE(&ifp->if_snd, m); - - bpf_mtap(ifp, m, BPF_D_OUT); - m_freem(m); - - idx = (idx + 1) % URE_TX_LIST_CNT; - cd->tx_cnt++; - } - cd->tx_prod = idx; -} - -static void -ure_start(struct ifnet *ifp) -{ - struct ure_softc * const sc = ifp->if_softc; - - mutex_enter(&sc->ure_txlock); - ure_start_locked(ifp); - mutex_exit(&sc->ure_txlock); -} - -static void -ure_tick(void *xsc) +ure_stop_cb(struct ifnet *ifp, int disable __unused) { - struct ure_softc *sc = xsc; - - if (sc == NULL) - return; + struct usbnet * const un = ifp->if_softc; - mutex_enter(&sc->ure_lock); - if (!sc->ure_stopping && !sc->ure_dying) { - /* Perform periodic stuff in process context */ - usb_add_task(sc->ure_udev, &sc->ure_tick_task, USB_TASKQ_DRIVER); - } - mutex_exit(&sc->ure_lock); -} - -static void -ure_stop_locked(struct ifnet *ifp, int disable __unused) -{ - struct ure_softc *sc = ifp->if_softc; - struct ure_chain *c; - usbd_status err; - int i; - - KASSERT(mutex_owned(&sc->ure_lock)); - mutex_enter(&sc->ure_rxlock); - mutex_enter(&sc->ure_txlock); - sc->ure_stopping = true; - mutex_exit(&sc->ure_txlock); - mutex_exit(&sc->ure_rxlock); - - ure_reset(sc); - - /* - * XXXSMP Would like to - * KASSERT(IFNET_LOCKED(ifp)) - * here but the locking order is: - * ifnet -> sc lock -> rxlock -> txlock - * and sc lock is already held. - */ - ifp->if_flags &= ~IFF_RUNNING; - - callout_stop(&sc->ure_stat_ch); - - sc->ure_flags &= ~URE_FLAG_LINK; /* XXX */ - - if (sc->ure_ep[URE_ENDPT_RX] != NULL) { - err = usbd_abort_pipe(sc->ure_ep[URE_ENDPT_RX]); - if (err) - URE_PRINTF(sc, "abort rx pipe failed: %s\n", - usbd_errstr(err)); - } - - if (sc->ure_ep[URE_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->ure_ep[URE_ENDPT_TX]); - if (err) - URE_PRINTF(sc, "abort tx pipe failed: %s\n", - usbd_errstr(err)); - } - - for (i = 0; i < URE_RX_LIST_CNT; i++) { - c = &sc->ure_cdata.rx_chain[i]; - if (c->uc_xfer != NULL) { - usbd_destroy_xfer(c->uc_xfer); - c->uc_xfer = NULL; - } - } - - for (i = 0; i < URE_TX_LIST_CNT; i++) { - c = &sc->ure_cdata.tx_chain[i]; - if (c->uc_xfer != NULL) { - usbd_destroy_xfer(c->uc_xfer); - c->uc_xfer = NULL; - } - } - - if (sc->ure_ep[URE_ENDPT_RX] != NULL) { - err = usbd_close_pipe(sc->ure_ep[URE_ENDPT_RX]); - if (err) - URE_PRINTF(sc, "close rx pipe failed: %s\n", - usbd_errstr(err)); - sc->ure_ep[URE_ENDPT_RX] = NULL; - } - - if (sc->ure_ep[URE_ENDPT_TX] != NULL) { - err = usbd_close_pipe(sc->ure_ep[URE_ENDPT_TX]); - if (err) - URE_PRINTF(sc, "close tx pipe failed: %s\n", - usbd_errstr(err)); - sc->ure_ep[URE_ENDPT_TX] = NULL; - } -} - -static void -ure_stop(struct ifnet *ifp, int disable __unused) -{ - struct ure_softc * const sc = ifp->if_softc; - - mutex_enter(&sc->ure_lock); - ure_stop_locked(ifp, disable); - mutex_exit(&sc->ure_lock); + ure_reset(un); } static void ure_rtl8152_init(struct ure_softc *sc) { + struct usbnet * const un = &sc->ure_un; uint32_t pwrctrl; /* Disable ALDPS. */ - ure_ocp_reg_write(sc, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | + ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | URE_DIS_SDSAVE); - usbd_delay_ms(sc->ure_udev, 20); + usbd_delay_ms(un->un_udev, 20); if (sc->ure_chip & URE_CHIP_VER_4C00) { - ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & + ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & ~URE_LED_MODE_MASK); } - ure_write_2(sc, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) & ~URE_POWER_CUT); - ure_write_2(sc, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) & ~URE_RESUME_INDICATE); - ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | + ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH); - pwrctrl = ure_read_4(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA); + pwrctrl = ure_read_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA); pwrctrl &= ~URE_MCU_CLK_RATIO_MASK; pwrctrl |= URE_MCU_CLK_RATIO | URE_D3_CLK_GATED_EN; - ure_write_4(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, pwrctrl); - ure_write_2(sc, URE_PLA_GPHY_INTR_IMR, URE_MCU_TYPE_PLA, + ure_write_4(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, pwrctrl); + ure_write_2(un, URE_PLA_GPHY_INTR_IMR, URE_MCU_TYPE_PLA, URE_GPHY_STS_MSK | URE_SPEED_DOWN_MSK | URE_SPDWN_RXDV_MSK | URE_SPDWN_LINKCHG_MSK); /* Enable Rx aggregation. */ - ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & ~URE_RX_AGG_DISABLE); /* Disable ALDPS. */ - ure_ocp_reg_write(sc, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | + ure_ocp_reg_write(un, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | URE_DIS_SDSAVE); - usbd_delay_ms(sc->ure_udev, 20); + usbd_delay_ms(un->un_udev, 20); ure_init_fifo(sc); - ure_write_1(sc, URE_USB_TX_AGG, URE_MCU_TYPE_USB, + ure_write_1(un, URE_USB_TX_AGG, URE_MCU_TYPE_USB, URE_TX_AGG_MAX_THRESHOLD); - ure_write_4(sc, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_HIGH); - ure_write_4(sc, URE_USB_TX_DMA, URE_MCU_TYPE_USB, + ure_write_4(un, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_HIGH); + ure_write_4(un, URE_USB_TX_DMA, URE_MCU_TYPE_USB, URE_TEST_MODE_DISABLE | URE_TX_SIZE_ADJUST1); } static void ure_rtl8153_init(struct ure_softc *sc) { + struct usbnet * const un = &sc->ure_un; uint16_t val; uint8_t u1u2[8]; int i; /* Disable ALDPS. */ - ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); - usbd_delay_ms(sc->ure_udev, 20); + ure_ocp_reg_write(un, URE_OCP_POWER_CFG, + ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); + usbd_delay_ms(un->un_udev, 20); memset(u1u2, 0x00, sizeof(u1u2)); - ure_write_mem(sc, URE_USB_TOLERANCE, + ure_write_mem(un, URE_USB_TOLERANCE, URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); for (i = 0; i < URE_TIMEOUT; i++) { - if (ure_read_2(sc, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) & + if (ure_read_2(un, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) & URE_AUTOLOAD_DONE) break; - usbd_delay_ms(sc->ure_udev, 10); + usbd_delay_ms(un->un_udev, 10); } if (i == URE_TIMEOUT) - URE_PRINTF(sc, "timeout waiting for chip autoload\n"); + URE_PRINTF(un, "timeout waiting for chip autoload\n"); for (i = 0; i < URE_TIMEOUT; i++) { - val = ure_ocp_reg_read(sc, URE_OCP_PHY_STATUS) & + val = ure_ocp_reg_read(un, URE_OCP_PHY_STATUS) & URE_PHY_STAT_MASK; if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN) break; - usbd_delay_ms(sc->ure_udev, 10); + usbd_delay_ms(un->un_udev, 10); } if (i == URE_TIMEOUT) - URE_PRINTF(sc, "timeout waiting for phy to stabilize\n"); + URE_PRINTF(un, "timeout waiting for phy to stabilize\n"); - ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) & ~URE_U2P3_ENABLE); if (sc->ure_chip & URE_CHIP_VER_5C10) { - val = ure_read_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB); + val = ure_read_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB); val &= ~URE_PWD_DN_SCALE_MASK; val |= URE_PWD_DN_SCALE(96); - ure_write_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val); + ure_write_2(un, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val); - ure_write_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB, - ure_read_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB) | + ure_write_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB, + ure_read_1(un, URE_USB_USB2PHY, URE_MCU_TYPE_USB) | URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND); } else if (sc->ure_chip & URE_CHIP_VER_5C20) { - ure_write_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA, - ure_read_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) & + ure_write_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA, + ure_read_1(un, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) & ~URE_ECM_ALDPS); } if (sc->ure_chip & (URE_CHIP_VER_5C20 | URE_CHIP_VER_5C30)) { - val = ure_read_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB); - if (ure_read_2(sc, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) == + val = ure_read_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB); + if (ure_read_2(un, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) == 0) val &= ~URE_DYNAMIC_BURST; else val |= URE_DYNAMIC_BURST; - ure_write_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val); + ure_write_1(un, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val); } - ure_write_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB, - ure_read_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) | + ure_write_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB, + ure_read_1(un, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) | URE_EP4_FULL_FC); - ure_write_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) & ~URE_TIMER11_EN); - ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & + ure_write_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & ~URE_LED_MODE_MASK); if ((sc->ure_chip & URE_CHIP_VER_5C10) && - sc->ure_udev->ud_speed != USB_SPEED_SUPER) + un->un_udev->ud_speed != USB_SPEED_SUPER) val = URE_LPM_TIMER_500MS; else val = URE_LPM_TIMER_500US; - ure_write_1(sc, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB, + ure_write_1(un, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB, val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM); - val = ure_read_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB); + val = ure_read_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB); val &= ~URE_SEN_VAL_MASK; val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE; - ure_write_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val); + ure_write_2(un, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val); - ure_write_2(sc, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001); + ure_write_2(un, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001); - ure_write_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) & ~(URE_PWR_EN | URE_PHASE2_EN)); - ure_write_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_MISC_0, URE_MCU_TYPE_USB) & ~URE_PCUT_STATUS); memset(u1u2, 0xff, sizeof(u1u2)); - ure_write_mem(sc, URE_USB_TOLERANCE, + ure_write_mem(un, URE_USB_TOLERANCE, URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); - ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, + ure_write_2(un, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, URE_ALDPS_SPDWN_RATIO); - ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA, + ure_write_2(un, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA, URE_EEE_SPDWN_RATIO); - ure_write_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, + ure_write_2(un, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN | URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN); - ure_write_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, + ure_write_2(un, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN | URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN | URE_EEE_SPDWN_EN); - val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); + val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); if (!(sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10))) val |= URE_U2P3_ENABLE; else val &= ~URE_U2P3_ENABLE; - ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); + ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); memset(u1u2, 0x00, sizeof(u1u2)); - ure_write_mem(sc, URE_USB_TOLERANCE, + ure_write_mem(un, URE_USB_TOLERANCE, URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); /* Disable ALDPS. */ - ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); - usbd_delay_ms(sc->ure_udev, 20); + ure_ocp_reg_write(un, URE_OCP_POWER_CFG, + ure_ocp_reg_read(un, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); + usbd_delay_ms(un->un_udev, 20); ure_init_fifo(sc); /* Enable Rx aggregation. */ - ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & + ure_write_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, + ure_read_2(un, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & ~URE_RX_AGG_DISABLE); - val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); + val = ure_read_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); if (!(sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10))) val |= URE_U2P3_ENABLE; else val &= ~URE_U2P3_ENABLE; - ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); + ure_write_2(un, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); memset(u1u2, 0xff, sizeof(u1u2)); - ure_write_mem(sc, URE_USB_TOLERANCE, + ure_write_mem(un, URE_USB_TOLERANCE, URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); } static void ure_disable_teredo(struct ure_softc *sc) { + struct usbnet * const un = &sc->ure_un; - ure_write_4(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA, - ure_read_4(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) & + ure_write_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA, + ure_read_4(un, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) & ~(URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN)); - ure_write_2(sc, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA, + ure_write_2(un, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA, URE_WDT6_SET_MODE); - ure_write_2(sc, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0); - ure_write_4(sc, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0); + ure_write_2(un, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0); + ure_write_4(un, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0); } static void ure_init_fifo(struct ure_softc *sc) { + struct usbnet * const un = &sc->ure_un; uint32_t rx_fifo1, rx_fifo2; int i; - ure_write_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) | + ure_write_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) | URE_RXDY_GATED_EN); ure_disable_teredo(sc); - ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, - ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA) & + ure_write_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA, + ure_read_4(un, URE_PLA_RCR, URE_MCU_TYPE_PLA) & ~URE_RCR_ACPT_ALL); if (!(sc->ure_flags & URE_FLAG_8152)) { if (sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10 | URE_CHIP_VER_5C20)) - ure_ocp_reg_write(sc, URE_OCP_ADC_CFG, + ure_ocp_reg_write(un, URE_OCP_ADC_CFG, URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L); if (sc->ure_chip & URE_CHIP_VER_5C00) - ure_ocp_reg_write(sc, URE_OCP_EEE_CFG, - ure_ocp_reg_read(sc, URE_OCP_EEE_CFG) & + ure_ocp_reg_write(un, URE_OCP_EEE_CFG, + ure_ocp_reg_read(un, URE_OCP_EEE_CFG) & ~URE_CTAP_SHORT_EN); - ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | + ure_ocp_reg_write(un, URE_OCP_POWER_CFG, + ure_ocp_reg_read(un, URE_OCP_POWER_CFG) | URE_EEE_CLKDIV_EN); - ure_ocp_reg_write(sc, URE_OCP_DOWN_SPEED, - ure_ocp_reg_read(sc, URE_OCP_DOWN_SPEED) | + ure_ocp_reg_write(un, URE_OCP_DOWN_SPEED, + ure_ocp_reg_read(un, URE_OCP_DOWN_SPEED) | URE_EN_10M_BGOFF); - ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | + ure_ocp_reg_write(un, URE_OCP_POWER_CFG, + ure_ocp_reg_read(un, URE_OCP_POWER_CFG) | URE_EN_10M_PLLOFF); - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0b13); - ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | + ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE); + ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0b13); + ure_write_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | URE_PFM_PWM_SWITCH); /* Enable LPF corner auto tune. */ - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0xf70f); + ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG); + ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0xf70f); /* Adjust 10M amplitude. */ - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x00af); - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0208); + ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1); + ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x00af); + ure_ocp_reg_write(un, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2); + ure_ocp_reg_write(un, URE_OCP_SRAM_DATA, 0x0208); } - ure_reset(sc); + ure_reset(un); - ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, 0); + ure_write_1(un, URE_PLA_CR, URE_MCU_TYPE_PLA, 0); - ure_write_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA, - ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & + ure_write_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA, + ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & ~URE_NOW_IS_OOB); - ure_write_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) & + ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) & ~URE_MCU_BORW_EN); for (i = 0; i < URE_TIMEOUT; i++) { - if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & + if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & URE_LINK_LIST_READY) break; - usbd_delay_ms(sc->ure_udev, 10); + usbd_delay_ms(un->un_udev, 10); } if (i == URE_TIMEOUT) - URE_PRINTF(sc, "timeout waiting for OOB control\n"); - ure_write_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) | + URE_PRINTF(un, "timeout waiting for OOB control\n"); + ure_write_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) | URE_RE_INIT_LL); for (i = 0; i < URE_TIMEOUT; i++) { - if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & + if (ure_read_1(un, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & URE_LINK_LIST_READY) break; - usbd_delay_ms(sc->ure_udev, 10); + usbd_delay_ms(un->un_udev, 10); } if (i == URE_TIMEOUT) - URE_PRINTF(sc, "timeout waiting for OOB control\n"); + URE_PRINTF(un, "timeout waiting for OOB control\n"); - ure_write_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA) & + ure_write_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_CPCR, URE_MCU_TYPE_PLA) & ~URE_CPCR_RX_VLAN); - ure_write_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA) | + ure_write_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA, + ure_read_2(un, URE_PLA_TCR0, URE_MCU_TYPE_PLA) | URE_TCR0_AUTO_FIFO); /* Configure Rx FIFO threshold and coalescing. */ - ure_write_4(sc, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA, + ure_write_4(un, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA, URE_RXFIFO_THR1_NORMAL); - if (sc->ure_udev->ud_speed == USB_SPEED_FULL) { + if (un->un_udev->ud_speed == USB_SPEED_FULL) { rx_fifo1 = URE_RXFIFO_THR2_FULL; rx_fifo2 = URE_RXFIFO_THR3_FULL; } else { rx_fifo1 = URE_RXFIFO_THR2_HIGH; rx_fifo2 = URE_RXFIFO_THR3_HIGH; } - ure_write_4(sc, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, rx_fifo1); - ure_write_4(sc, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, rx_fifo2); + ure_write_4(un, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, rx_fifo1); + ure_write_4(un, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, rx_fifo2); /* Configure Tx FIFO threshold. */ - ure_write_4(sc, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA, + ure_write_4(un, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA, URE_TXFIFO_THR_NORMAL); } -int -ure_ioctl(struct ifnet *ifp, u_long cmd, void *data) +static int +ure_ioctl_cb(struct ifnet *ifp, u_long cmd, void *data) { - struct ure_softc *sc = ifp->if_softc; - int error = 0, oflags = ifp->if_flags; + struct usbnet * const un = ifp->if_softc; switch (cmd) { - case SIOCSIFFLAGS: - if ((error = ifioctl_common(ifp, cmd, data)) != 0) - break; - switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { - case IFF_RUNNING: - ure_stop(ifp, 1); - break; - case IFF_UP: - ure_init(ifp); - break; - case IFF_UP | IFF_RUNNING: - if ((ifp->if_flags ^ oflags) == IFF_PROMISC) - ure_iff(sc); - else - ure_init(ifp); - } + case SIOCADDMULTI: + case SIOCDELMULTI: + ure_setiff(un); break; default: - if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET) - break; - error = 0; - if ((ifp->if_flags & IFF_RUNNING) == 0) - break; - switch (cmd) { - case SIOCADDMULTI: - case SIOCDELMULTI: - ure_iff(sc); - break; - default: - break; - } + break; } - return error; + return 0; } static int @@ -1150,41 +819,38 @@ static void ure_attach(device_t parent, device_t self, void *aux) { struct ure_softc *sc = device_private(self); + struct usbnet * const un = &sc->ure_un; struct usb_attach_arg *uaa = aux; struct usbd_device *dev = uaa->uaa_device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; - struct ifnet *ifp; - struct mii_data *mii; int error, i; uint16_t ver; uint8_t eaddr[8]; /* 2byte padded */ char *devinfop; + /* Switch to usbnet for device_private() */ + self->dv_private = un; + aprint_naive("\n"); aprint_normal("\n"); - - sc->ure_dev = self; - sc->ure_udev = dev; - - devinfop = usbd_devinfo_alloc(sc->ure_udev, 0); + devinfop = usbd_devinfo_alloc(dev, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - callout_init(&sc->ure_stat_ch, CALLOUT_MPSAFE); - usb_init_task(&sc->ure_tick_task, ure_tick_task, sc, USB_TASKQ_MPSAFE); - mutex_init(&sc->ure_mii_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&sc->ure_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&sc->ure_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&sc->ure_lock, MUTEX_DEFAULT, IPL_NONE); - cv_init(&sc->ure_detachcv, "uredet"); - - /* - * ure_phyno is set to 0 below when configuration has succeeded. - * if it is still -1 in detach, then ifmedia/mii/etc was not - * setup and should not be torn down. - */ - sc->ure_phyno = -1; + un->un_dev = self; + un->un_udev = dev; + un->un_sc = sc; + un->un_stop_cb = ure_stop_cb; + un->un_ioctl_cb = ure_ioctl_cb; + un->un_read_reg_cb = ure_mii_read_reg; + un->un_write_reg_cb = ure_mii_write_reg; + un->un_statchg_cb = ure_miibus_statchg; + un->un_tx_prepare_cb = ure_tx_prepare; + un->un_rx_loop_cb = ure_rxeof_loop; + un->un_init_cb = ure_init; + un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; + un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; #define URE_CONFIG_NO 1 /* XXX */ error = usbd_set_config_no(dev, URE_CONFIG_NO, 1); @@ -1198,34 +864,37 @@ ure_attach(device_t parent, device_t sel sc->ure_flags |= URE_FLAG_8152; #define URE_IFACE_IDX 0 /* XXX */ - error = usbd_device2interface_handle(dev, URE_IFACE_IDX, &sc->ure_iface); + error = usbd_device2interface_handle(dev, URE_IFACE_IDX, &un->un_iface); if (error) { aprint_error_dev(self, "failed to get interface handle: %s\n", usbd_errstr(error)); return; /* XXX */ } - sc->ure_bufsz = 16 * 1024; + un->un_cdata.uncd_rx_bufsz = un->un_cdata.uncd_tx_bufsz = 16 * 1024; - id = usbd_get_interface_descriptor(sc->ure_iface); + id = usbd_get_interface_descriptor(un->un_iface); for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->ure_iface, i); + ed = usbd_interface2endpoint_descriptor(un->un_iface, i); if (ed == NULL) { aprint_error_dev(self, "couldn't get ep %d\n", i); return; /* XXX */ } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->ure_ed[URE_ENDPT_RX] = ed->bEndpointAddress; + un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - sc->ure_ed[URE_ENDPT_TX] = ed->bEndpointAddress; + un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; } } - sc->ure_phyno = 0; + /* Set these up now for ure_ctl(). */ + usbnet_attach(un, "uredet", URE_RX_LIST_CNT, URE_TX_LIST_CNT); - ver = ure_read_2(sc, URE_PLA_TCR1, URE_MCU_TYPE_PLA) & URE_VERSION_MASK; + un->un_phyno = 0; + + ver = ure_read_2(un, URE_PLA_TCR1, URE_MCU_TYPE_PLA) & URE_VERSION_MASK; switch (ver) { case 0x4c00: sc->ure_chip |= URE_CHIP_VER_4C00; @@ -1254,31 +923,25 @@ ure_attach(device_t parent, device_t sel (sc->ure_chip != 0) ? "" : "unknown ", ver); - mutex_enter(&sc->ure_lock); + usbnet_lock(un); if (sc->ure_flags & URE_FLAG_8152) ure_rtl8152_init(sc); else ure_rtl8153_init(sc); if (sc->ure_chip & URE_CHIP_VER_4C00) - ure_read_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr, + ure_read_mem(un, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr, sizeof(eaddr)); else - ure_read_mem(sc, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr, + ure_read_mem(un, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr, sizeof(eaddr)); - mutex_exit(&sc->ure_lock); + usbnet_unlock(un); + memcpy(un->un_eaddr, eaddr, sizeof un->un_eaddr); - aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr)); + aprint_normal_dev(self, "Ethernet address %s\n", + ether_sprintf(un->un_eaddr)); - ifp = GET_IFP(sc); - ifp->if_softc = sc; - strlcpy(ifp->if_xname, device_xname(sc->ure_dev), IFNAMSIZ); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_extflags = IFEF_MPSAFE; - ifp->if_init = ure_init; - ifp->if_ioctl = ure_ioctl; - ifp->if_start = ure_start; - ifp->if_stop = ure_stop; + struct ifnet *ifp = usbnet_ifp(un); /* * We don't support TSOv4 and v6 for now, that are required to @@ -1294,280 +957,60 @@ ure_attach(device_t parent, device_t sel IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx; } - sc->ure_ec.ec_capabilities = ETHERCAP_VLAN_MTU; + struct ethercom *ec = usbnet_ec(un); + ec->ec_capabilities = ETHERCAP_VLAN_MTU; #ifdef notyet - sc->ure_ec.ec_capabilities |= ETHERCAP_JUMBO_MTU; + ec->ec_capabilities |= ETHERCAP_JUMBO_MTU; #endif - IFQ_SET_READY(&ifp->if_snd); - - mii = GET_MII(sc); - mii->mii_ifp = ifp; - mii->mii_readreg = ure_miibus_readreg; - mii->mii_writereg = ure_miibus_writereg; - mii->mii_statchg = ure_miibus_statchg; - mii->mii_flags = MIIF_AUTOTSLEEP; - - sc->ure_ec.ec_mii = mii; - ifmedia_init(&mii->mii_media, 0, ure_ifmedia_upd, ure_ifmedia_sts); - mii_attach(self, mii, 0xffffffff, sc->ure_phyno, MII_OFFSET_ANY, 0); - - if (LIST_FIRST(&mii->mii_phys) == NULL) { - ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); - ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); - } else - ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); - - if_attach(ifp); - ether_ifattach(ifp, eaddr); - - rnd_attach_source(&sc->ure_rnd_source, device_xname(sc->ure_dev), - RND_TYPE_NET, RND_FLAG_DEFAULT); - - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->ure_udev, sc->ure_dev); - - if (!pmf_device_register(self, NULL, NULL)) - aprint_error_dev(self, "couldn't establish power handler\n"); -} - -static int -ure_detach(device_t self, int flags) -{ - struct ure_softc *sc = device_private(self); - struct ifnet *ifp = GET_IFP(sc); - - pmf_device_deregister(self); - - mutex_enter(&sc->ure_lock); - sc->ure_dying = true; - mutex_exit(&sc->ure_lock); - - callout_halt(&sc->ure_stat_ch, NULL); - - usb_rem_task_wait(sc->ure_udev, &sc->ure_tick_task, USB_TASKQ_DRIVER, - NULL); - - if (sc->ure_ep[URE_ENDPT_TX] != NULL) - usbd_abort_pipe(sc->ure_ep[URE_ENDPT_TX]); - if (sc->ure_ep[URE_ENDPT_RX] != NULL) - usbd_abort_pipe(sc->ure_ep[URE_ENDPT_RX]); - - mutex_enter(&sc->ure_lock); - sc->ure_refcnt--; - while (sc->ure_refcnt > 0) { - /* Wait for processes to go away */ - cv_wait(&sc->ure_detachcv, &sc->ure_lock); - } - mutex_exit(&sc->ure_lock); - - /* partial-attach, below items weren't configured. */ - if (sc->ure_phyno != -1) { - if (ifp->if_flags & IFF_RUNNING) { - IFNET_LOCK(ifp); - ure_stop(ifp, 1); - IFNET_UNLOCK(ifp); - } - - rnd_detach_source(&sc->ure_rnd_source); - mii_detach(&sc->ure_mii, MII_PHY_ANY, MII_OFFSET_ANY); - ifmedia_delete_instance(&sc->ure_mii.mii_media, IFM_INST_ANY); - if (ifp->if_softc != NULL) { - ether_ifdetach(ifp); - if_detach(ifp); - } - } - - usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->ure_udev, sc->ure_dev); - - callout_destroy(&sc->ure_stat_ch); - cv_destroy(&sc->ure_detachcv); - mutex_destroy(&sc->ure_lock); - mutex_destroy(&sc->ure_rxlock); - mutex_destroy(&sc->ure_txlock); - mutex_destroy(&sc->ure_mii_lock); - - return 0; -} - -static int -ure_activate(device_t self, enum devact act) -{ - struct ure_softc *sc = device_private(self); - struct ifnet *ifp = GET_IFP(sc); - - switch (act) { - case DVACT_DEACTIVATE: - if_deactivate(ifp); - - mutex_enter(&sc->ure_lock); - sc->ure_dying = true; - mutex_exit(&sc->ure_lock); - - mutex_enter(&sc->ure_rxlock); - mutex_enter(&sc->ure_txlock); - sc->ure_stopping = true; - mutex_exit(&sc->ure_txlock); - mutex_exit(&sc->ure_rxlock); - - return 0; - default: - return EOPNOTSUPP; - } - return 0; -} - -static void -ure_tick_task(void *xsc) -{ - struct ure_softc *sc = xsc; - struct ifnet *ifp; - struct mii_data *mii; - - if (sc == NULL) - return; - - mutex_enter(&sc->ure_lock); - if (sc->ure_stopping || sc->ure_dying) { - mutex_exit(&sc->ure_lock); - return; - } - - ifp = GET_IFP(sc); - mii = GET_MII(sc); - if (mii == NULL) { - mutex_exit(&sc->ure_lock); - return; - } - - sc->ure_refcnt++; - mutex_exit(&sc->ure_lock); - - mii_tick(mii); - - if ((sc->ure_flags & URE_FLAG_LINK) == 0) - ure_miibus_statchg(ifp); - - mutex_enter(&sc->ure_lock); - if (--sc->ure_refcnt < 0) - cv_broadcast(&sc->ure_detachcv); - if (!sc->ure_stopping && !sc->ure_dying) - callout_schedule(&sc->ure_stat_ch, hz); - mutex_exit(&sc->ure_lock); -} - -static void -ure_lock_mii(struct ure_softc *sc) -{ - - mutex_enter(&sc->ure_lock); - sc->ure_refcnt++; - mutex_exit(&sc->ure_lock); - - mutex_enter(&sc->ure_mii_lock); -} - -static void -ure_unlock_mii(struct ure_softc *sc) -{ - - mutex_exit(&sc->ure_mii_lock); - mutex_enter(&sc->ure_lock); - if (--sc->ure_refcnt < 0) - cv_broadcast(&sc->ure_detachcv); - mutex_exit(&sc->ure_lock); + usbnet_attach_ifp(un, true, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, + 0, 0); } static void -ure_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) +ure_rxeof_loop(struct usbnet *un, struct usbd_xfer *xfer, + struct usbnet_chain *c, uint32_t total_len) { - struct ure_chain *c = (struct ure_chain *)priv; - struct ure_softc *sc = c->uc_sc; - struct ifnet *ifp = GET_IFP(sc); - uint8_t *buf = c->uc_buf; - uint32_t total_len; - uint16_t pktlen = 0; - struct mbuf *m; + struct ifnet *ifp = usbnet_ifp(un); + uint8_t *buf = c->unc_buf; + uint16_t pkt_len = 0; + uint16_t pkt_count = 0; struct ure_rxpkt rxhdr; - mutex_enter(&sc->ure_rxlock); - - if (sc->ure_dying || sc->ure_stopping || - status == USBD_INVAL || status == USBD_NOT_STARTED || - status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) { - mutex_exit(&sc->ure_rxlock); - return; - } - - if (status != USBD_NORMAL_COMPLETION) { - if (usbd_ratecheck(&sc->ure_rx_notice)) - URE_PRINTF(sc, "usb errors on rx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async( - sc->ure_ep[URE_ENDPT_RX]); - goto done; - } - - usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); - DPRINTFN(3, ("received %d bytes\n", total_len)); - - KASSERTMSG(total_len <= sc->ure_bufsz, "%u vs %u", - total_len, sc->ure_bufsz); + usbnet_isowned_rx(un); do { if (total_len < sizeof(rxhdr)) { DPRINTF(("too few bytes left for a packet header\n")); ifp->if_ierrors++; - goto done; + return; } - buf += roundup(pktlen, 8); + buf += roundup(pkt_len, 8); memcpy(&rxhdr, buf, sizeof(rxhdr)); total_len -= sizeof(rxhdr); - pktlen = le32toh(rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK; - DPRINTFN(4, ("next packet is %d bytes\n", pktlen)); - if (pktlen > total_len) { + pkt_len = le32toh(rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK; + DPRINTFN(4, ("next packet is %d bytes\n", pkt_len)); + if (pkt_len > total_len) { DPRINTF(("not enough bytes left for next packet\n")); ifp->if_ierrors++; - goto done; + return; } - total_len -= roundup(pktlen, 8); + total_len -= roundup(pkt_len, 8); buf += sizeof(rxhdr); - m = m_devget(buf, pktlen - ETHER_CRC_LEN, 0, ifp); - if (m == NULL) { - DPRINTF(("unable to allocate mbuf for next packet\n")); - ifp->if_ierrors++; - goto done; - } - - m->m_pkthdr.csum_flags = ure_rxcsum(ifp, &rxhdr); - - mutex_exit(&sc->ure_rxlock); - if_percpuq_enqueue(ifp->if_percpuq, m); - mutex_enter(&sc->ure_rxlock); + usbnet_enqueue(un, buf, pkt_len - ETHER_CRC_LEN, + ure_rxcsum(ifp, &rxhdr)); - if (sc->ure_dying || sc->ure_stopping) { - mutex_exit(&sc->ure_rxlock); - return; - } + pkt_count++; } while (total_len > 0); -done: - if (sc->ure_dying || sc->ure_stopping) { - mutex_exit(&sc->ure_rxlock); - return; - } - mutex_exit(&sc->ure_rxlock); - - /* Setup new transfer. */ - usbd_setup_xfer(xfer, c, c->uc_buf, sc->ure_bufsz, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ure_rxeof); - usbd_transfer(xfer); + if (pkt_count) + rnd_add_uint32(&un->un_rndsrc, pkt_count); } static int @@ -1609,113 +1052,14 @@ ure_rxcsum(struct ifnet *ifp, struct ure return flags; } -static void -ure_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) +static unsigned +ure_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) { - struct ure_chain *c = priv; - struct ure_softc *sc = c->uc_sc; - struct ure_cdata *cd = &sc->ure_cdata; - struct ifnet *ifp = GET_IFP(sc); - - mutex_enter(&sc->ure_txlock); - if (sc->ure_stopping || sc->ure_dying) { - mutex_exit(&sc->ure_txlock); - return; - } - - DPRINTFN(2, ("tx completion\n")); - - KASSERT(cd->tx_cnt > 0); - cd->tx_cnt--; - - switch (status) { - case USBD_NOT_STARTED: - case USBD_CANCELLED: - break; - - case USBD_NORMAL_COMPLETION: - ifp->if_opackets++; - - if (!IFQ_IS_EMPTY(&ifp->if_snd)) { - ure_start_locked(ifp); - } - break; - - default: - ifp->if_oerrors++; - if (usbd_ratecheck(&sc->ure_tx_notice)) - URE_PRINTF(sc, "usb error on tx: %s\n", - usbd_errstr(status)); - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async( - sc->ure_ep[URE_ENDPT_TX]); - break; - } - - mutex_exit(&sc->ure_txlock); -} - -static int -ure_tx_list_init(struct ure_softc *sc) -{ - struct ure_cdata *cd; - struct ure_chain *c; - int i, error; - - cd = &sc->ure_cdata; - for (i = 0; i < URE_TX_LIST_CNT; i++) { - c = &cd->tx_chain[i]; - c->uc_sc = sc; - if (c->uc_xfer == NULL) { - error = usbd_create_xfer(sc->ure_ep[URE_ENDPT_TX], - sc->ure_bufsz, USBD_FORCE_SHORT_XFER, 0, - &c->uc_xfer); - if (error) - return error; - c->uc_buf = usbd_get_buffer(c->uc_xfer); - } - } - - cd->tx_prod = cd->tx_cnt = 0; - - return 0; -} - -static int -ure_rx_list_init(struct ure_softc *sc) -{ - struct ure_cdata *cd; - struct ure_chain *c; - int i, error; - - cd = &sc->ure_cdata; - for (i = 0; i < URE_RX_LIST_CNT; i++) { - c = &cd->rx_chain[i]; - c->uc_sc = sc; - error = usbd_create_xfer(sc->ure_ep[URE_ENDPT_RX], - sc->ure_bufsz, 0, 0, &c->uc_xfer); - if (error) - return error; - c->uc_buf = usbd_get_buffer(c->uc_xfer); - } - - return 0; -} - -static int -ure_encap(struct ure_softc *sc, struct mbuf *m, int idx) -{ - struct ifnet *ifp = GET_IFP(sc); - struct ure_chain *c; - usbd_status err; struct ure_txpkt txhdr; uint32_t frm_len = 0; - uint8_t *buf; + uint8_t *buf = c->unc_buf; - KASSERT(mutex_owned(&sc->ure_txlock)); - - c = &sc->ure_cdata.tx_chain[idx]; - buf = c->uc_buf; + usbnet_isowned_tx(un); /* header */ txhdr.ure_pktlen = htole32(m->m_pkthdr.len | URE_TXPKT_TX_FS | @@ -1729,21 +1073,12 @@ ure_encap(struct ure_softc *sc, struct m m_copydata(m, 0, m->m_pkthdr.len, buf); frm_len += m->m_pkthdr.len; - if (__predict_false(c->uc_xfer == NULL)) + if (__predict_false(c->unc_xfer == NULL)) return EIO; /* XXX plugged out or down */ DPRINTFN(2, ("tx %d bytes\n", frm_len)); - usbd_setup_xfer(c->uc_xfer, c, c->uc_buf, frm_len, - USBD_FORCE_SHORT_XFER, 10000, ure_txeof); - err = usbd_transfer(c->uc_xfer); - if (err != USBD_IN_PROGRESS) { - /* XXXSMP IFNET_LOCK */ - ure_stop(ifp, 0); - return EIO; - } - - return 0; + return frm_len; } /* Index: src/sys/dev/usb/if_urevar.h diff -u src/sys/dev/usb/if_urevar.h:1.3 src/sys/dev/usb/if_urevar.h:1.4 --- src/sys/dev/usb/if_urevar.h:1.3 Sun Jun 23 02:14:14 2019 +++ src/sys/dev/usb/if_urevar.h Sun Aug 4 09:03:46 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_urevar.h,v 1.3 2019/06/23 02:14:14 mrg Exp $ */ +/* $NetBSD: if_urevar.h,v 1.4 2019/08/04 09:03:46 mrg Exp $ */ /* $OpenBSD: if_urereg.h,v 1.5 2018/11/02 21:32:30 jcs Exp $ */ /*- @@ -72,10 +72,6 @@ struct ure_txpkt { #define URE_TXPKT_UDP_CS __BIT(31) } __packed; -#define URE_ENDPT_RX 0 -#define URE_ENDPT_TX 1 -#define URE_ENDPT_MAX 2 - #ifndef URE_TX_LIST_CNT #define URE_TX_LIST_CNT 4 #endif @@ -83,50 +79,8 @@ struct ure_txpkt { #define URE_RX_LIST_CNT 4 #endif -struct ure_chain { - struct ure_softc *uc_sc; - struct usbd_xfer *uc_xfer; - char *uc_buf; -}; - -struct ure_cdata { - struct ure_chain tx_chain[URE_TX_LIST_CNT]; - struct ure_chain rx_chain[URE_RX_LIST_CNT]; - int tx_prod; - int tx_cnt; -}; - struct ure_softc { - device_t ure_dev; - struct usbd_device *ure_udev; - - /* usb */ - struct usbd_interface *ure_iface; - struct usb_task ure_tick_task; - int ure_ed[URE_ENDPT_MAX]; - struct usbd_pipe *ure_ep[URE_ENDPT_MAX]; - - /* ethernet */ - struct ethercom ure_ec; -#define GET_IFP(sc) (&(sc)->ure_ec.ec_if) - struct mii_data ure_mii; -#define GET_MII(sc) (&(sc)->ure_mii) - - kmutex_t ure_mii_lock; - kmutex_t ure_lock; - kmutex_t ure_rxlock; - kmutex_t ure_txlock; - kcondvar_t ure_detachcv; - int ure_refcnt; - - struct ure_cdata ure_cdata; - callout_t ure_stat_ch; - - struct timeval ure_rx_notice; - struct timeval ure_tx_notice; - u_int ure_bufsz; - - int ure_phyno; + struct usbnet ure_un; u_int ure_flags; #define URE_FLAG_LINK 0x0001 @@ -140,9 +94,4 @@ struct ure_softc { #define URE_CHIP_VER_5C20 0x10 #define URE_CHIP_VER_5C30 0x20 - krndsource_t ure_rnd_source; - - bool ure_dying; - bool ure_stopping; - bool ure_attached; };