diff options
Diffstat (limited to 'sys/dev/usb')
| -rw-r--r-- | sys/dev/usb/if_axe.c | 6 | ||||
| -rw-r--r-- | sys/dev/usb/if_axen.c | 10 | ||||
| -rw-r--r-- | sys/dev/usb/if_cdce.c | 16 | ||||
| -rw-r--r-- | sys/dev/usb/if_ure.c | 6 | ||||
| -rw-r--r-- | sys/dev/usb/usbnet.c | 69 | ||||
| -rw-r--r-- | sys/dev/usb/usbnet.h | 23 |
6 files changed, 90 insertions, 40 deletions
diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c index 1665866b55c..4189e925da0 100644 --- a/sys/dev/usb/if_axe.c +++ b/sys/dev/usb/if_axe.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_axe.c,v 1.104 2019/08/04 09:03:46 mrg Exp $ */ +/* $NetBSD: if_axe.c,v 1.105 2019/08/06 00:19:57 mrg Exp $ */ /* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */ /* @@ -87,7 +87,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.104 2019/08/04 09:03:46 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.105 2019/08/06 00:19:57 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -1150,7 +1150,7 @@ axe_rx_loop_cb(struct usbnet * un, struct usbd_xfer *xfer, total_len = 0; } - usbnet_enqueue(un, buf, pktlen, flags); + usbnet_enqueue(un, buf, pktlen, flags, 0, 0); buf += rxlen; } while (total_len > 0); diff --git a/sys/dev/usb/if_axen.c b/sys/dev/usb/if_axen.c index a8ebba80d99..256cdbde16f 100644 --- a/sys/dev/usb/if_axen.c +++ b/sys/dev/usb/if_axen.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_axen.c,v 1.54 2019/08/05 07:03:55 skrll Exp $ */ +/* $NetBSD: if_axen.c,v 1.55 2019/08/06 00:19:57 mrg Exp $ */ /* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ /* @@ -23,7 +23,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.54 2019/08/05 07:03:55 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.55 2019/08/06 00:19:57 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -153,7 +153,7 @@ axen_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) } static void -axen_miibus_statchg(struct ifnet *ifp) +axen_mii_statchg(struct ifnet *ifp) { struct usbnet * const un = ifp->if_softc; struct axen_softc * const sc = usbnet_softc(un); @@ -623,7 +623,7 @@ axen_attach(device_t parent, device_t self, void *aux) un->un_ioctl_cb = axen_ioctl_cb; un->un_read_reg_cb = axen_mii_read_reg; un->un_write_reg_cb = axen_mii_write_reg; - un->un_statchg_cb = axen_miibus_statchg; + un->un_statchg_cb = axen_mii_statchg; un->un_tx_prepare_cb = axen_tx_prepare; un->un_rx_loop_cb = axen_rxeof_loop; un->un_init_cb = axen_init; @@ -857,7 +857,7 @@ axen_rxeof_loop(struct usbnet *un, struct usbd_xfer *xfer, } usbnet_enqueue(un, buf + 2, pkt_len - 6, - axen_csum_flags_rx(ifp, pkt_hdr)); + axen_csum_flags_rx(ifp, pkt_hdr), 0, 0); nextpkt: /* diff --git a/sys/dev/usb/if_cdce.c b/sys/dev/usb/if_cdce.c index 38ff9e8bc3b..12f5959d656 100644 --- a/sys/dev/usb/if_cdce.c +++ b/sys/dev/usb/if_cdce.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_cdce.c,v 1.56 2019/08/04 08:59:13 mrg Exp $ */ +/* $NetBSD: if_cdce.c,v 1.57 2019/08/06 00:19:57 mrg Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.56 2019/08/04 08:59:13 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.57 2019/08/06 00:19:57 mrg Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -81,8 +81,8 @@ static const struct cdce_type cdce_devs[] = { static int cdce_match(device_t, cfdata_t, void *); static void cdce_attach(device_t, device_t, void *); static int cdce_init(struct ifnet *); -static void cdce_rxeof_loop(struct usbnet *, struct usbd_xfer *, - struct usbnet_chain *, uint32_t); +static void cdce_rx_loop(struct usbnet *, struct usbd_xfer *, + struct usbnet_chain *, uint32_t); static unsigned cdce_tx_prepare(struct usbnet *, struct mbuf *, struct usbnet_chain *); @@ -136,7 +136,7 @@ cdce_attach(device_t parent, device_t self, void *aux) un->un_sc = sc; un->un_init_cb = cdce_init; un->un_tx_prepare_cb = cdce_tx_prepare; - un->un_rx_loop_cb = cdce_rxeof_loop; + un->un_rx_loop_cb = cdce_rx_loop; un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; un->un_cdata.uncd_rx_bufsz = CDCE_BUFSZ; @@ -278,8 +278,8 @@ cdce_init(struct ifnet *ifp) } static void -cdce_rxeof_loop(struct usbnet * un, struct usbd_xfer *xfer, - struct usbnet_chain *c, uint32_t total_len) +cdce_rx_loop(struct usbnet * un, struct usbd_xfer *xfer, + struct usbnet_chain *c, uint32_t total_len) { struct ifnet *ifp = usbnet_ifp(un); struct cdce_softc *sc = usbnet_softc(un); @@ -295,7 +295,7 @@ cdce_rxeof_loop(struct usbnet * un, struct usbd_xfer *xfer, return; } - usbnet_enqueue(un, c->unc_buf, total_len, 0); + usbnet_enqueue(un, c->unc_buf, total_len, 0, 0, 0); } static unsigned diff --git a/sys/dev/usb/if_ure.c b/sys/dev/usb/if_ure.c index d06691d2817..2cdeb66c69b 100644 --- a/sys/dev/usb/if_ure.c +++ b/sys/dev/usb/if_ure.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ure.c,v 1.16 2019/08/04 18:04:18 mrg Exp $ */ +/* $NetBSD: if_ure.c,v 1.17 2019/08/06 00:19:57 mrg Exp $ */ /* $OpenBSD: if_ure.c,v 1.10 2018/11/02 21:32:30 jcs Exp $ */ /*- @@ -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.16 2019/08/04 18:04:18 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ure.c,v 1.17 2019/08/06 00:19:57 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -1004,7 +1004,7 @@ ure_rxeof_loop(struct usbnet *un, struct usbd_xfer *xfer, buf += sizeof(rxhdr); usbnet_enqueue(un, buf, pkt_len - ETHER_CRC_LEN, - ure_rxcsum(ifp, &rxhdr)); + ure_rxcsum(ifp, &rxhdr), 0, 0); pkt_count++; diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c index 147bda6aed5..3dfda001c9a 100644 --- a/sys/dev/usb/usbnet.c +++ b/sys/dev/usb/usbnet.c @@ -1,4 +1,4 @@ -/* $NetBSD: usbnet.c,v 1.4 2019/08/04 08:59:13 mrg Exp $ */ +/* $NetBSD: usbnet.c,v 1.5 2019/08/06 00:19:57 mrg Exp $ */ /* * Copyright (c) 2019 Matthew R. Green @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.4 2019/08/04 08:59:13 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.5 2019/08/06 00:19:57 mrg Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -115,11 +115,12 @@ usbnet_newbuf(void) * usbnet_rxeof() is designed to be the done callback for rx completion. * it provides generic setup and finalisation, calls a different usbnet * rx_loop callback in the middle, which can use usbnet_enqueue() to - * enqueue a packet for higher levels. + * enqueue a packet for higher levels (or usbnet_input() if previously + * using if_input() path.) */ void usbnet_enqueue(struct usbnet * const un, uint8_t *buf, size_t buflen, - int flags) + int csum_flags, uint32_t csum_data, int mbuf_flags) { USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct ifnet *ifp = &un->un_ec.ec_if; @@ -135,13 +136,38 @@ usbnet_enqueue(struct usbnet * const un, uint8_t *buf, size_t buflen, m_set_rcvif(m, ifp); m->m_pkthdr.len = m->m_len = buflen; - m->m_pkthdr.csum_flags = flags; + m->m_pkthdr.csum_flags = csum_flags; + m->m_pkthdr.csum_data = csum_data; + m->m_flags |= mbuf_flags; memcpy(mtod(m, char *), buf, buflen); /* push the packet up */ if_percpuq_enqueue(ifp->if_percpuq, m); } +void +usbnet_input(struct usbnet * const un, uint8_t *buf, size_t buflen) +{ + USBNETHIST_FUNC(); USBNETHIST_CALLED(); + struct ifnet * const ifp = usbnet_ifp(un); + struct mbuf *m; + + KASSERT(mutex_owned(&un->un_rxlock)); + + m = usbnet_newbuf(); + if (m == NULL) { + ifp->if_ierrors++; + return; + } + + m_set_rcvif(m, ifp); + m->m_pkthdr.len = m->m_len = buflen; + memcpy(mtod(m, char *), buf, buflen); + + /* push the packet up */ + if_input(ifp, m); +} + /* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. @@ -152,7 +178,7 @@ usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) USBNETHIST_FUNC(); USBNETHIST_CALLED(); struct usbnet_chain *c = priv; struct usbnet * const un = c->unc_un; - struct ifnet *ifp = &un->un_ec.ec_if; + struct ifnet * const ifp = usbnet_ifp(un); uint32_t total_len; mutex_enter(&un->un_rxlock); @@ -787,6 +813,9 @@ usbnet_ioctl(struct ifnet *ifp, u_long cmd, void *data) struct usbnet * const un = ifp->if_softc; int error; + if (un->un_override_ioctl_cb) + return (*un->un_override_ioctl_cb)(ifp, cmd, data); + error = ether_ioctl(ifp, cmd, data); if (error == ENETRESET && un->un_ioctl_cb) error = (*un->un_ioctl_cb)(ifp, cmd, data); @@ -946,6 +975,14 @@ usbnet_init(struct ifnet *ifp) /* Autoconf management. */ +static bool +usbnet_empty_eaddr(struct usbnet *un) +{ + return (un->un_eaddr[0] == 0 && un->un_eaddr[1] == 0 && + un->un_eaddr[2] == 0 && un->un_eaddr[3] == 0 && + un->un_eaddr[4] == 0 && un->un_eaddr[5] == 0); +} + /* * usbnet_attach() and usbnet_attach_ifp() perform setup of the relevant * 'usbnet'. The first is enough to enable device access (eg, endpoints @@ -954,6 +991,9 @@ usbnet_init(struct ifnet *ifp) * * Always call usbnet_detach(), even if usbnet_attach_ifp() is skippped. * Also usable as driver detach directly. + * + * To skip ethernet configuration (eg, point-to-point), make sure that + * the un_eaddr[] is fully zero. */ void usbnet_attach(struct usbnet *un, @@ -1054,7 +1094,17 @@ usbnet_attach_ifp(struct usbnet *un, /* Attach the interface. */ if_attach(ifp); - ether_ifattach(ifp, un->un_eaddr); + + /* + * If ethernet address is all zero, skip ether_ifattach() and + * instead attach bpf here.. + */ + if (!usbnet_empty_eaddr(un)) { + ether_ifattach(ifp, un->un_eaddr); + } else { + if_alloc_sadl(ifp); + bpf_attach(ifp, DLT_RAW, 0); + } } int @@ -1101,7 +1151,10 @@ usbnet_detach(device_t self, int flags) ifmedia_delete_instance(&mii->mii_media, IFM_INST_ANY); } if (ifp->if_softc) { - ether_ifdetach(ifp); + if (!usbnet_empty_eaddr(un)) + ether_ifdetach(ifp); + else + bpf_detach(ifp); if_detach(ifp); } diff --git a/sys/dev/usb/usbnet.h b/sys/dev/usb/usbnet.h index bb02a0620f8..65206661b8a 100644 --- a/sys/dev/usb/usbnet.h +++ b/sys/dev/usb/usbnet.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbnet.h,v 1.4 2019/08/04 08:59:13 mrg Exp $ */ +/* $NetBSD: usbnet.h,v 1.5 2019/08/06 00:19:57 mrg Exp $ */ /* * Copyright (c) 2019 Matthew R. Green @@ -50,12 +50,15 @@ * can be stored in un_sc member) * - use MII bus lock / access methods * - usbnet_attach() to initialise and allocate rx/tx chains + * - usbnet_attach_ifp() to attach the interface, and either ether_ifattach() + * for ethernet devices, or if_alloc_sadl()/bpf_attach() pair otherwise. * - usbnet_detach() to clean them up * - usbnet_activate() for autoconf * - interface ioctl and start have direct frontends with callbacks for * device specific handling: - * - ioctl replies upon ether_ioctl() and a device-specific callback - * to handle setting multicast/offload/etc + * - ioctl can use either a device-specific override (useful for special + * cases), but provides a normal handler with callback to handle + * ENETRESET conditions that should be sufficient for most users * - start uses usbnet send callback * - interface init and stop have helper functions * - device specific init should use usbnet_init_rx_tx() to open pipes @@ -75,15 +78,6 @@ * completion function (internal to usbnet) */ -/* - * Converted drivers: if_axe if_axen if_cdce if_ure. - * - * Note: these drivers have slightly different mbuf handling that need to be - * adjusted to the common method (see if_cdce conversion): - * - * if_atu if_aue if_cue if_smsc if_udav if_upl if_url if_urndis. - */ - #include <sys/device.h> #include <sys/mbuf.h> #include <sys/rndsource.h> @@ -225,6 +219,7 @@ struct usbnet { usbnet_stop_cb un_stop_cb; usbnet_ioctl_cb un_ioctl_cb; + usbnet_ioctl_cb un_override_ioctl_cb; usbnet_init_cb un_init_cb; usbnet_mii_read_reg_cb un_read_reg_cb; usbnet_mii_write_reg_cb un_write_reg_cb; @@ -338,7 +333,9 @@ int usbnet_miibus_writereg(device_t, int, int, uint16_t); void usbnet_miibus_statchg(struct ifnet *); /* interrupt handling */ -void usbnet_enqueue(struct usbnet * const, uint8_t *, size_t, int); +void usbnet_enqueue(struct usbnet * const, uint8_t *, size_t, int, + uint32_t, int); +void usbnet_input(struct usbnet * const, uint8_t *, size_t); /* autoconf */ void usbnet_attach(struct usbnet *un, const char *, unsigned, unsigned); |
