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 <[email protected]>
* 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;
};