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