Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb udav*, for ether w/ Davicom DM9601 chipset. Shi...
details: https://anonhg.NetBSD.org/src/rev/04fa442744f1
branches: trunk
changeset: 550815:04fa442744f1
user: itojun <itojun%NetBSD.org@localhost>
date: Fri Aug 22 05:13:29 2003 +0000
description:
udav*, for ether w/ Davicom DM9601 chipset. Shingo WATANABE
diffstat:
sys/dev/usb/files.usb | 7 +-
sys/dev/usb/if_udav.c | 1619 ++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/usb/if_udavreg.h | 208 +++++
3 files changed, 1833 insertions(+), 1 deletions(-)
diffs (truncated from 1856 to 300 lines):
diff -r 0beb01e9238c -r 04fa442744f1 sys/dev/usb/files.usb
--- a/sys/dev/usb/files.usb Fri Aug 22 05:07:26 2003 +0000
+++ b/sys/dev/usb/files.usb Fri Aug 22 05:13:29 2003 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.usb,v 1.50 2003/02/15 18:33:29 augustss Exp $
+# $NetBSD: files.usb,v 1.51 2003/08/22 05:13:29 itojun Exp $
#
# Config file and device description for machine-independent USB code.
# Included by ports that need it. Ports that use it must provide
@@ -173,6 +173,11 @@
attach uax at uhub
file dev/usb/if_uax.c uax
+# DAVICOM DM9601
+device udav: arp, ether, ifnet, mii, mii_phy
+attach udav at uhub
+file dev/usb/if_udav.c udav
+
# Serial drivers
# Modems
diff -r 0beb01e9238c -r 04fa442744f1 sys/dev/usb/if_udav.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/usb/if_udav.c Fri Aug 22 05:13:29 2003 +0000
@@ -0,0 +1,1619 @@
+/* $NetBSD: if_udav.c,v 1.1 2003/08/22 05:13:29 itojun Exp $ */
+/* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */
+/*
+ * Copyright (c) 2003
+ * Shingo WATANABE <nabe%nabechan.org@localhost>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Shingo WATANABE.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*
+ * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY)
+ * The spec can be found at the following url.
+ * http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf
+ */
+
+/*
+ * TODO:
+ * Interrupt Endpoint support
+ * External PHYs
+ * powerhook() support?
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.1 2003/08/22 05:13:29 itojun Exp $");
+
+#include "opt_inet.h"
+#include "opt_ns.h"
+#include "bpfilter.h"
+#include "rnd.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+
+#include <sys/device.h>
+#if NRND > 0
+#include <sys/rnd.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+#define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
+
+#include <net/if_ether.h>
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_inarp.h>
+#endif
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#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/usbdevs.h>
+
+#include <dev/usb/if_udavreg.h>
+
+
+/* Function declarations */
+USB_DECLARE_DRIVER(udav);
+
+Static int udav_openpipes(struct udav_softc *);
+Static int udav_rx_list_init(struct udav_softc *);
+Static int udav_tx_list_init(struct udav_softc *);
+Static int udav_newbuf(struct udav_softc *, struct udav_chain *, struct mbuf *);
+Static void udav_start(struct ifnet *);
+Static int udav_send(struct udav_softc *, struct mbuf *, int);
+Static void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
+Static void udav_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
+Static void udav_tick(void *);
+Static void udav_tick_task(void *);
+Static int udav_ioctl(struct ifnet *, u_long, caddr_t);
+Static void udav_stop_task(struct udav_softc *);
+Static void udav_stop(struct ifnet *, int);
+Static void udav_watchdog(struct ifnet *);
+Static int udav_ifmedia_change(struct ifnet *);
+Static void udav_ifmedia_status(struct ifnet *, struct ifmediareq *);
+Static void udav_lock_mii(struct udav_softc *);
+Static void udav_unlock_mii(struct udav_softc *);
+Static int udav_miibus_readreg(device_ptr_t, int, int);
+Static void udav_miibus_writereg(device_ptr_t, int, int, int);
+Static void udav_miibus_statchg(device_ptr_t);
+Static int udav_init(struct ifnet *);
+Static void udav_setmulti(struct udav_softc *);
+Static void udav_reset(struct udav_softc *);
+
+Static int udav_csr_read(struct udav_softc *, int, void *, int);
+Static int udav_csr_write(struct udav_softc *, int, void *, int);
+Static int udav_csr_read1(struct udav_softc *, int);
+Static int udav_csr_write1(struct udav_softc *, int, unsigned char);
+
+#if 0
+Static int udav_mem_read(struct udav_softc *, int, void *, int);
+Static int udav_mem_write(struct udav_softc *, int, void *, int);
+Static int udav_mem_write1(struct udav_softc *, int, unsigned char);
+#endif
+
+/* Macros */
+#ifdef UDAV_DEBUG
+#define DPRINTF(x) if (udavdebug) logprintf x
+#define DPRINTFN(n,x) if (udavdebug >= (n)) logprintf x
+int udavdebug = 0;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#endif
+
+#define UDAV_SETBIT(sc, reg, x) \
+ udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x))
+
+#define UDAV_CLRBIT(sc, reg, x) \
+ udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x))
+
+static const struct udav_type {
+ struct usb_devno udav_dev;
+ u_int16_t udav_flags;
+#define UDAV_EXT_PHY 0x0001
+} udav_devs [] = {
+ /* Corega USB-TXC */
+ {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0},
+#if 0
+ /* DAVICOM DM9601 Generic? */
+ /* XXX: The following ids was obtained from the data sheet. */
+ {{ 0x0a46, 0x9601 }, 0},
+#endif
+};
+#define udav_lookup(v, p) ((struct udav_type *)usb_lookup(udav_devs, v, p))
+
+
+/* Probe */
+USB_MATCH(udav)
+{
+ USB_MATCH_START(udav, uaa);
+
+ if (uaa->iface != NULL)
+ return (UMATCH_NONE);
+
+ return (udav_lookup(uaa->vendor, uaa->product) != NULL ?
+ UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
+}
+
+/* Attach */
+USB_ATTACH(udav)
+{
+ USB_ATTACH_START(udav, sc, uaa);
+ usbd_device_handle dev = uaa->device;
+ usbd_interface_handle iface;
+ usbd_status err;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ char devinfo[1024];
+ char *devname = USBDEVNAME(sc->sc_dev);
+ struct ifnet *ifp;
+ struct mii_data *mii;
+ u_char eaddr[ETHER_ADDR_LEN];
+ int i, s;
+
+ usbd_devinfo(dev, 0, devinfo);
+ USB_ATTACH_SETUP;
+ printf("%s: %s\n", devname, devinfo);
+
+ /* Move the device into the configured state. */
+ err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1);
+ if (err) {
+ printf("%s: setting config no failed\n", devname);
+ goto bad;
+ }
+
+ usb_init_task(&sc->sc_tick_task, udav_tick_task, sc);
+ lockinit(&sc->sc_mii_lock, PZERO, "udavmii", 0, 0);
+ usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc);
+
+ /* get control interface */
+ err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface);
+ if (err) {
+ printf("%s: failed to get interface, err=%s\n", devname,
+ usbd_errstr(err));
+ goto bad;
+ }
+
+ sc->sc_udev = dev;
+ sc->sc_ctl_iface = iface;
+ sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags;
+
+ /* get interface descriptor */
+ id = usbd_get_interface_descriptor(sc->sc_ctl_iface);
+
+ /* find endpoints */
+ sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1;
+ for (i = 0; i < id->bNumEndpoints; i++) {
+ ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i);
+ if (ed == NULL) {
+ printf("%s: couldn't get endpoint %d\n", devname, i);
+ goto bad;
+ }
+ if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
+ UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
+ sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */
+ else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK &&
+ UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
+ sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */
+ else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT &&
+ UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
+ sc->sc_intrin_no = ed->bEndpointAddress; /* Status */
+ }
+
+ if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 ||
+ sc->sc_intrin_no == -1) {
+ printf("%s: missing endpoint\n", devname);
+ goto bad;
+ }
+
+ s = splnet();
+
+ /* reset the adapter */
+ udav_reset(sc);
+
+ /* Get Ethernet Address */
+ err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN);
+ if (err) {
+ printf("%s: read MAC address failed\n", devname);
+ splx(s);
+ goto bad;
+ }
+
+ /* Print Ethernet Address */
+ printf("%s: Ethernet address %s\n", devname, ether_sprintf(eaddr));
+
+ /* initialize interface infomation */
+ ifp = GET_IFP(sc);
+ ifp->if_softc = sc;
+ ifp->if_mtu = ETHERMTU;
+ strncpy(ifp->if_xname, devname, IFNAMSIZ);
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
Home |
Main Index |
Thread Index |
Old Index