summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authormrg <mrg@NetBSD.org>2019-08-06 00:19:57 +0000
committermrg <mrg@NetBSD.org>2019-08-06 00:19:57 +0000
commit89f00a81941b1157828db47a76cf4dadfcdd4aef (patch)
tree001cc27c148a589e3edae07354183e9ca25be004 /sys
parent70d0f72bf242571e784feb6cb29f03b514dd8416 (diff)
extend usbnet to cope with if_upl, if_smsc, and if_umb needs:
- usbnet_enqueue() can set mbuf flags and csum_data - usbnet_input() for non-ethernet based devices (upl, umb) - allow a complete override for ioctl() - remove converted list -- we have compiling and/or working patches for all the devices except for umb(4), will be merged as testing happens hopefully this is the last ABI change, though it may end up being extended for additional smsc(4) support. hello for real netbsd 9.99.3!
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/if_axe.c6
-rw-r--r--sys/dev/usb/if_axen.c10
-rw-r--r--sys/dev/usb/if_cdce.c16
-rw-r--r--sys/dev/usb/if_ure.c6
-rw-r--r--sys/dev/usb/usbnet.c69
-rw-r--r--sys/dev/usb/usbnet.h23
-rw-r--r--sys/sys/param.h4
7 files changed, 92 insertions, 42 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);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 53a4ef885d3..72d697947fa 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -1,4 +1,4 @@
-/* $NetBSD: param.h,v 1.601 2019/07/31 14:35:25 rin Exp $ */
+/* $NetBSD: param.h,v 1.602 2019/08/06 00:19:57 mrg Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@@ -67,7 +67,7 @@
* 2.99.9 (299000900)
*/
-#define __NetBSD_Version__ 999000200 /* NetBSD 9.99.2 */
+#define __NetBSD_Version__ 999000300 /* NetBSD 9.99.3 */
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)