Home | History | Annotate | Line # | Download | only in usb
if_upl.c revision 1.1
      1 /*	$NetBSD: if_upl.c,v 1.1 2000/04/09 18:23:23 augustss Exp $	*/
      2 /*
      3  * Copyright (c) 2000 The NetBSD Foundation, Inc.
      4  * All rights reserved.
      5  *
      6  * This code is derived from software contributed to The NetBSD Foundation
      7  * by Lennart Augustsson (augustss (at) carlstedt.se) at
      8  * Carlstedt Research & Technology.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 /*
     40  * Prolific PL2301/PL2302 driver
     41  */
     42 
     43 #include "opt_inet.h"
     44 #include "opt_ns.h"
     45 #include "bpfilter.h"
     46 #include "rnd.h"
     47 
     48 #include <sys/param.h>
     49 #include <sys/systm.h>
     50 #include <sys/callout.h>
     51 #include <sys/sockio.h>
     52 #include <sys/mbuf.h>
     53 #include <sys/malloc.h>
     54 #include <sys/kernel.h>
     55 #include <sys/socket.h>
     56 
     57 #include <sys/device.h>
     58 #if NRND > 0
     59 #include <sys/rnd.h>
     60 #endif
     61 
     62 #include <net/if.h>
     63 #include <net/if_types.h>
     64 #include <net/if_dl.h>
     65 #include <net/netisr.h>
     66 
     67 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
     68 
     69 #if NBPFILTER > 0
     70 #include <net/bpf.h>
     71 #endif
     72 
     73 #ifdef INET
     74 #include <netinet/in.h>
     75 #include <netinet/in_var.h>
     76 #include <netinet/if_inarp.h>
     77 #endif
     78 #ifdef INET6
     79 #include <netinet6/in6_ifattach.h>
     80 #endif
     81 
     82 #ifdef NS
     83 #include <netns/ns.h>
     84 #include <netns/ns_if.h>
     85 #endif
     86 
     87 #include <dev/usb/usb.h>
     88 #include <dev/usb/usbdi.h>
     89 #include <dev/usb/usbdi_util.h>
     90 #include <dev/usb/usbdevs.h>
     91 
     92 /*
     93  * 7  6  5  4  3  2  1  0
     94  *  tx rx 1  0
     95  * 1110 0000 rxdata
     96  * 1010 0000 idle
     97  * 0010 0000 tx over
     98  * 0110      tx over + rxd
     99  */
    100 
    101 #define UPL_RXDATA		0x40
    102 #define UPL_TXOK		0x80
    103 
    104 #define UPL_INTR_PKTLEN		1
    105 
    106 #define UPL_CONFIG_NO		1
    107 #define UPL_IFACE_IDX		0
    108 
    109 /***/
    110 
    111 #define UPL_INTR_INTERVAL	20
    112 
    113 #define UPL_BUFSZ		1024
    114 
    115 #define UPL_RX_FRAMES		1
    116 #define UPL_TX_FRAMES		1
    117 
    118 #define UPL_RX_LIST_CNT		1
    119 #define UPL_TX_LIST_CNT		1
    120 
    121 #define UPL_ENDPT_RX		0x0
    122 #define UPL_ENDPT_TX		0x1
    123 #define UPL_ENDPT_INTR		0x2
    124 #define UPL_ENDPT_MAX		0x3
    125 
    126 struct upl_type {
    127 	u_int16_t		upl_vid;
    128 	u_int16_t		upl_did;
    129 };
    130 
    131 struct upl_softc;
    132 
    133 struct upl_chain {
    134 	struct upl_softc	*upl_sc;
    135 	usbd_xfer_handle	upl_xfer;
    136 	char			*upl_buf;
    137 	struct mbuf		*upl_mbuf;
    138 	int			upl_idx;
    139 };
    140 
    141 struct upl_cdata {
    142 	struct upl_chain	upl_tx_chain[UPL_TX_LIST_CNT];
    143 	struct upl_chain	upl_rx_chain[UPL_RX_LIST_CNT];
    144 	int			upl_tx_prod;
    145 	int			upl_tx_cons;
    146 	int			upl_tx_cnt;
    147 	int			upl_rx_prod;
    148 };
    149 
    150 struct upl_softc {
    151 	USBBASEDEVICE		sc_dev;
    152 
    153 	struct ifnet		sc_if;
    154 #if NRND > 0
    155 	rndsource_element_t	sc_rnd_source;
    156 #endif
    157 
    158 	usb_callout_t		sc_stat_ch;
    159 
    160 	usbd_device_handle	sc_udev;
    161 	usbd_interface_handle	sc_iface;
    162 	u_int16_t		sc_vendor;
    163 	u_int16_t		sc_product;
    164 	int			sc_ed[UPL_ENDPT_MAX];
    165 	usbd_pipe_handle	sc_ep[UPL_ENDPT_MAX];
    166 	struct upl_cdata	sc_cdata;
    167 
    168 	uByte			sc_ibuf;
    169 
    170 	char			sc_dying;
    171 	char			sc_attached;
    172 	u_int			sc_rx_errs;
    173 	struct timeval		sc_rx_notice;
    174 	u_int			sc_intr_errs;
    175 };
    176 
    177 #ifdef UPL_DEBUG
    178 #define DPRINTF(x)	if (upldebug) logprintf x
    179 #define DPRINTFN(n,x)	if (upldebug >= (n)) logprintf x
    180 int	upldebug = 0;
    181 #else
    182 #define DPRINTF(x)
    183 #define DPRINTFN(n,x)
    184 #endif
    185 
    186 /*
    187  * Various supported device vendors/products.
    188  */
    189 Static struct upl_type sc_devs[] = {
    190 	{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 },
    191 	{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 },
    192 	{ 0, 0 }
    193 };
    194 
    195 USB_DECLARE_DRIVER(upl);
    196 
    197 Static int upl_openpipes	__P((struct upl_softc *));
    198 Static int upl_tx_list_init	__P((struct upl_softc *));
    199 Static int upl_rx_list_init	__P((struct upl_softc *));
    200 Static int upl_newbuf		__P((struct upl_softc *, struct upl_chain *,
    201 				    struct mbuf *));
    202 Static int upl_send		__P((struct upl_softc *, struct mbuf *, int));
    203 Static void upl_intr		__P((usbd_xfer_handle,
    204 				    usbd_private_handle, usbd_status));
    205 Static void upl_rxeof		__P((usbd_xfer_handle,
    206 				    usbd_private_handle, usbd_status));
    207 Static void upl_txeof		__P((usbd_xfer_handle,
    208 				    usbd_private_handle, usbd_status));
    209 Static void upl_start		__P((struct ifnet *));
    210 Static int upl_ioctl		__P((struct ifnet *, u_long, caddr_t));
    211 Static void upl_init		__P((void *));
    212 Static void upl_stop		__P((struct upl_softc *));
    213 Static void upl_watchdog		__P((struct ifnet *));
    214 
    215 Static int upl_output __P((struct ifnet *, struct mbuf *, struct sockaddr *,
    216 			   struct rtentry *));
    217 Static void upl_input __P((struct ifnet *, struct mbuf *));
    218 
    219 /*
    220  * Probe for a Prolific chip.
    221  */
    222 USB_MATCH(upl)
    223 {
    224 	USB_MATCH_START(upl, uaa);
    225 	struct upl_type			*t;
    226 
    227 	if (uaa->iface != NULL)
    228 		return (UMATCH_NONE);
    229 
    230 	for (t = sc_devs; t->upl_vid != 0; t++)
    231 		if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did)
    232 			return (UMATCH_VENDOR_PRODUCT);
    233 
    234 	return (UMATCH_NONE);
    235 }
    236 
    237 USB_ATTACH(upl)
    238 {
    239 	USB_ATTACH_START(upl, sc, uaa);
    240 	char			devinfo[1024];
    241 	int			s;
    242 	usbd_device_handle	dev = uaa->device;
    243 	usbd_interface_handle	iface;
    244 	usbd_status		err;
    245 	struct ifnet		*ifp;
    246 	usb_interface_descriptor_t	*id;
    247 	usb_endpoint_descriptor_t	*ed;
    248 	int			i;
    249 
    250 	DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev));
    251 
    252 	usbd_devinfo(dev, 0, devinfo);
    253 	USB_ATTACH_SETUP;
    254 	printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
    255 
    256 	err = usbd_set_config_no(dev, UPL_CONFIG_NO, 0);
    257 	if (err) {
    258 		printf("%s: setting config no failed\n",
    259 		    USBDEVNAME(sc->sc_dev));
    260 		USB_ATTACH_ERROR_RETURN;
    261 	}
    262 
    263 	sc->sc_udev = dev;
    264 	sc->sc_product = uaa->product;
    265 	sc->sc_vendor = uaa->vendor;
    266 
    267 	err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface);
    268 	if (err) {
    269 		printf("%s: getting interface handle failed\n",
    270 		    USBDEVNAME(sc->sc_dev));
    271 		USB_ATTACH_ERROR_RETURN;
    272 	}
    273 
    274 	sc->sc_iface = iface;
    275 	id = usbd_get_interface_descriptor(iface);
    276 
    277 	/* Find endpoints. */
    278 	for (i = 0; i < id->bNumEndpoints; i++) {
    279 		ed = usbd_interface2endpoint_descriptor(iface, i);
    280 		if (ed == NULL) {
    281 			printf("%s: couldn't get ep %d\n",
    282 			    USBDEVNAME(sc->sc_dev), i);
    283 			USB_ATTACH_ERROR_RETURN;
    284 		}
    285 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    286 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    287 			sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress;
    288 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
    289 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    290 			sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress;
    291 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    292 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
    293 			sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress;
    294 		}
    295 	}
    296 
    297 	if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 ||
    298 	    sc->sc_ed[UPL_ENDPT_INTR] == 0) {
    299 		printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev));
    300 		USB_ATTACH_ERROR_RETURN;
    301 	}
    302 
    303 	s = splimp();
    304 
    305 	/* Initialize interface info.*/
    306 	ifp = &sc->sc_if;
    307 	ifp->if_softc = sc;
    308 	ifp->if_mtu = UPL_BUFSZ;
    309 	ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX;
    310 	ifp->if_ioctl = upl_ioctl;
    311 	ifp->if_start = upl_start;
    312 	ifp->if_watchdog = upl_watchdog;
    313 	strncpy(ifp->if_xname, USBDEVNAME(sc->sc_dev), IFNAMSIZ);
    314 
    315 	ifp->if_type = IFT_OTHER;
    316 	ifp->if_addrlen = 0;
    317 	ifp->if_hdrlen = 0;
    318 	ifp->if_output = upl_output;
    319 	ifp->if_input = upl_input;
    320 	ifp->if_baudrate = 12000000;
    321 #ifdef INET6
    322 	in6_ifattach_getifid(ifp);
    323 #endif
    324 
    325 	/* Attach the interface. */
    326 	if_attach(ifp);
    327 
    328 #if NBPFILTER > 0
    329 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, 0);
    330 #endif
    331 #if NRND > 0
    332 	rnd_attach_source(&sc->sc_rnd_source, USBDEVNAME(sc->sc_dev),
    333 	    RND_TYPE_NET, 0);
    334 #endif
    335 
    336 	sc->sc_attached = 1;
    337 	splx(s);
    338 
    339 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
    340 	    USBDEV(sc->sc_dev));
    341 
    342 	USB_ATTACH_SUCCESS_RETURN;
    343 }
    344 
    345 USB_DETACH(upl)
    346 {
    347 	USB_DETACH_START(upl, sc);
    348 	struct ifnet		*ifp = &sc->sc_if;
    349 	int			s;
    350 
    351 	DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
    352 
    353 	s = splusb();
    354 
    355 	if (!sc->sc_attached) {
    356 		/* Detached before attached finished, so just bail out. */
    357 		splx(s);
    358 		return (0);
    359 	}
    360 
    361 	if (ifp->if_flags & IFF_RUNNING)
    362 		upl_stop(sc);
    363 
    364 #if NRND > 0
    365 	rnd_detach_source(&sc->sc_rnd_source);
    366 #endif
    367 #if NBPFILTER > 0
    368 	bpfdetach(ifp);
    369 #endif
    370 	ether_ifdetach(ifp);
    371 
    372 	if_detach(ifp);
    373 
    374 #ifdef DIAGNOSTIC
    375 	if (sc->sc_ep[UPL_ENDPT_TX] != NULL ||
    376 	    sc->sc_ep[UPL_ENDPT_RX] != NULL ||
    377 	    sc->sc_ep[UPL_ENDPT_INTR] != NULL)
    378 		printf("%s: detach has active endpoints\n",
    379 		       USBDEVNAME(sc->sc_dev));
    380 #endif
    381 
    382 	sc->sc_attached = 0;
    383 	splx(s);
    384 
    385 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
    386 	    USBDEV(sc->sc_dev));
    387 
    388 	return (0);
    389 }
    390 
    391 int
    392 upl_activate(self, act)
    393 	device_ptr_t self;
    394 	enum devact act;
    395 {
    396 	struct upl_softc *sc = (struct upl_softc *)self;
    397 
    398 	DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
    399 
    400 	switch (act) {
    401 	case DVACT_ACTIVATE:
    402 		return (EOPNOTSUPP);
    403 		break;
    404 
    405 	case DVACT_DEACTIVATE:
    406 		/* Deactivate the interface. */
    407 		if_deactivate(&sc->sc_if);
    408 		sc->sc_dying = 1;
    409 		break;
    410 	}
    411 	return (0);
    412 }
    413 
    414 /*
    415  * Initialize an RX descriptor and attach an MBUF cluster.
    416  */
    417 Static int
    418 upl_newbuf(sc, c, m)
    419 	struct upl_softc	*sc;
    420 	struct upl_chain	*c;
    421 	struct mbuf		*m;
    422 {
    423 	struct mbuf		*m_new = NULL;
    424 
    425 	DPRINTFN(8,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
    426 
    427 	if (m == NULL) {
    428 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
    429 		if (m_new == NULL) {
    430 			printf("%s: no memory for rx list "
    431 			    "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
    432 			return (ENOBUFS);
    433 		}
    434 
    435 		MCLGET(m_new, M_DONTWAIT);
    436 		if (!(m_new->m_flags & M_EXT)) {
    437 			printf("%s: no memory for rx list "
    438 			    "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
    439 			m_freem(m_new);
    440 			return (ENOBUFS);
    441 		}
    442 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
    443 	} else {
    444 		m_new = m;
    445 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
    446 		m_new->m_data = m_new->m_ext.ext_buf;
    447 	}
    448 
    449 	c->upl_mbuf = m_new;
    450 
    451 	return (0);
    452 }
    453 
    454 Static int
    455 upl_rx_list_init(sc)
    456 	struct upl_softc	*sc;
    457 {
    458 	struct upl_cdata	*cd;
    459 	struct upl_chain	*c;
    460 	int			i;
    461 
    462 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
    463 
    464 	cd = &sc->sc_cdata;
    465 	for (i = 0; i < UPL_RX_LIST_CNT; i++) {
    466 		c = &cd->upl_rx_chain[i];
    467 		c->upl_sc = sc;
    468 		c->upl_idx = i;
    469 		if (upl_newbuf(sc, c, NULL) == ENOBUFS)
    470 			return (ENOBUFS);
    471 		if (c->upl_xfer == NULL) {
    472 			c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
    473 			if (c->upl_xfer == NULL)
    474 				return (ENOBUFS);
    475 			c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
    476 			if (c->upl_buf == NULL) {
    477 				usbd_free_xfer(c->upl_xfer);
    478 				return (ENOBUFS);
    479 			}
    480 		}
    481 	}
    482 
    483 	return (0);
    484 }
    485 
    486 Static int
    487 upl_tx_list_init(sc)
    488 	struct upl_softc	*sc;
    489 {
    490 	struct upl_cdata	*cd;
    491 	struct upl_chain	*c;
    492 	int			i;
    493 
    494 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
    495 
    496 	cd = &sc->sc_cdata;
    497 	for (i = 0; i < UPL_TX_LIST_CNT; i++) {
    498 		c = &cd->upl_tx_chain[i];
    499 		c->upl_sc = sc;
    500 		c->upl_idx = i;
    501 		c->upl_mbuf = NULL;
    502 		if (c->upl_xfer == NULL) {
    503 			c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
    504 			if (c->upl_xfer == NULL)
    505 				return (ENOBUFS);
    506 			c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
    507 			if (c->upl_buf == NULL) {
    508 				usbd_free_xfer(c->upl_xfer);
    509 				return (ENOBUFS);
    510 			}
    511 		}
    512 	}
    513 
    514 	return (0);
    515 }
    516 
    517 /*
    518  * A frame has been uploaded: pass the resulting mbuf chain up to
    519  * the higher level protocols.
    520  */
    521 Static void
    522 upl_rxeof(xfer, priv, status)
    523 	usbd_xfer_handle	xfer;
    524 	usbd_private_handle	priv;
    525 	usbd_status		status;
    526 {
    527 	struct upl_chain	*c = priv;
    528 	struct upl_softc	*sc = c->upl_sc;
    529 	struct ifnet		*ifp = &sc->sc_if;
    530 	struct mbuf		*m;
    531 	int			total_len = 0;
    532 	int			s;
    533 
    534 	if (sc->sc_dying)
    535 		return;
    536 
    537 	if (!(ifp->if_flags & IFF_RUNNING))
    538 		return;
    539 
    540 	if (status != USBD_NORMAL_COMPLETION) {
    541 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
    542 			return;
    543 		sc->sc_rx_errs++;
    544 		if (usbd_ratecheck(&sc->sc_rx_notice)) {
    545 			printf("%s: %u usb errors on rx: %s\n",
    546 			    USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
    547 			    usbd_errstr(status));
    548 			sc->sc_rx_errs = 0;
    549 		}
    550 		if (status == USBD_STALLED)
    551 			usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
    552 		goto done;
    553 	}
    554 
    555 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
    556 
    557 	DPRINTFN(9,("%s: %s: enter status=%d length=%d\n",
    558 		    USBDEVNAME(sc->sc_dev), __FUNCTION__, status, total_len));
    559 
    560 	m = c->upl_mbuf;
    561 	memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len);
    562 
    563 	ifp->if_ipackets++;
    564 	m->m_pkthdr.len = m->m_len = total_len;
    565 
    566 	m->m_pkthdr.rcvif = ifp;
    567 
    568 	s = splimp();
    569 
    570 	/* XXX ugly */
    571 	if (upl_newbuf(sc, c, NULL) == ENOBUFS) {
    572 		ifp->if_ierrors++;
    573 		goto done1;
    574 	}
    575 
    576 #if NBPFILTER > 0
    577 	/*
    578 	 * Handle BPF listeners. Let the BPF user see the packet, but
    579 	 * don't pass it up to the ether_input() layer unless it's
    580 	 * a broadcast packet, multicast packet, matches our ethernet
    581 	 * address or the interface is in promiscuous mode.
    582 	 */
    583 	if (ifp->if_bpf) {
    584 		BPF_MTAP(ifp, m);
    585 	}
    586 #endif
    587 
    588 	DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
    589 		    __FUNCTION__, m->m_len));
    590 
    591 	IF_INPUT(ifp, m);
    592 
    593  done1:
    594 	splx(s);
    595 
    596  done:
    597 #if 1
    598 	/* Setup new transfer. */
    599 	usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
    600 	    c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
    601 	    USBD_NO_TIMEOUT, upl_rxeof);
    602 	usbd_transfer(c->upl_xfer);
    603 
    604 	DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev),
    605 		    __FUNCTION__));
    606 #endif
    607 }
    608 
    609 /*
    610  * A frame was downloaded to the chip. It's safe for us to clean up
    611  * the list buffers.
    612  */
    613 Static void
    614 upl_txeof(xfer, priv, status)
    615 	usbd_xfer_handle	xfer;
    616 	usbd_private_handle	priv;
    617 	usbd_status		status;
    618 {
    619 	struct upl_chain	*c = priv;
    620 	struct upl_softc	*sc = c->upl_sc;
    621 	struct ifnet		*ifp = &sc->sc_if;
    622 	int			s;
    623 
    624 	if (sc->sc_dying)
    625 		return;
    626 
    627 	s = splimp();
    628 
    629 	DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->sc_dev),
    630 		    __FUNCTION__, status));
    631 
    632 	ifp->if_timer = 0;
    633 	ifp->if_flags &= ~IFF_OACTIVE;
    634 
    635 	if (status != USBD_NORMAL_COMPLETION) {
    636 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
    637 			splx(s);
    638 			return;
    639 		}
    640 		ifp->if_oerrors++;
    641 		printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
    642 		    usbd_errstr(status));
    643 		if (status == USBD_STALLED)
    644 			usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_TX]);
    645 		splx(s);
    646 		return;
    647 	}
    648 
    649 	ifp->if_opackets++;
    650 
    651 	m_freem(c->upl_mbuf);
    652 	c->upl_mbuf = NULL;
    653 
    654 	if (ifp->if_snd.ifq_head != NULL)
    655 		upl_start(ifp);
    656 
    657 	splx(s);
    658 }
    659 
    660 Static int
    661 upl_send(sc, m, idx)
    662 	struct upl_softc	*sc;
    663 	struct mbuf		*m;
    664 	int			idx;
    665 {
    666 	int			total_len;
    667 	struct upl_chain	*c;
    668 	usbd_status		err;
    669 
    670 	c = &sc->sc_cdata.upl_tx_chain[idx];
    671 
    672 	/*
    673 	 * Copy the mbuf data into a contiguous buffer, leaving two
    674 	 * bytes at the beginning to hold the frame length.
    675 	 */
    676 	m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf);
    677 	c->upl_mbuf = m;
    678 
    679 	total_len = m->m_pkthdr.len;
    680 
    681 	DPRINTFN(10,("%s: %s: total_len=%d\n",
    682 		     USBDEVNAME(sc->sc_dev), __FUNCTION__, total_len));
    683 
    684 	usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX],
    685 	    c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT,
    686 	    upl_txeof);
    687 
    688 	/* Transmit */
    689 	err = usbd_transfer(c->upl_xfer);
    690 	if (err != USBD_IN_PROGRESS) {
    691 		printf("%s: upl_send error=%s\n", USBDEVNAME(sc->sc_dev),
    692 		       usbd_errstr(err));
    693 		upl_stop(sc);
    694 		return (EIO);
    695 	}
    696 
    697 	sc->sc_cdata.upl_tx_cnt++;
    698 
    699 	return (0);
    700 }
    701 
    702 Static void
    703 upl_start(ifp)
    704 	struct ifnet		*ifp;
    705 {
    706 	struct upl_softc	*sc = ifp->if_softc;
    707 	struct mbuf		*m_head = NULL;
    708 
    709 	if (sc->sc_dying)
    710 		return;
    711 
    712 	DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
    713 
    714 	if (ifp->if_flags & IFF_OACTIVE)
    715 		return;
    716 
    717 	IF_DEQUEUE(&ifp->if_snd, m_head);
    718 	if (m_head == NULL)
    719 		return;
    720 
    721 	if (upl_send(sc, m_head, 0)) {
    722 		IF_PREPEND(&ifp->if_snd, m_head);
    723 		ifp->if_flags |= IFF_OACTIVE;
    724 		return;
    725 	}
    726 
    727 #if NBPFILTER > 0
    728 	/*
    729 	 * If there's a BPF listener, bounce a copy of this frame
    730 	 * to him.
    731 	 */
    732 	if (ifp->if_bpf)
    733 		BPF_MTAP(ifp, m_head);
    734 #endif
    735 
    736 	ifp->if_flags |= IFF_OACTIVE;
    737 
    738 	/*
    739 	 * Set a timeout in case the chip goes out to lunch.
    740 	 */
    741 	ifp->if_timer = 5;
    742 }
    743 
    744 Static void
    745 upl_init(xsc)
    746 	void			*xsc;
    747 {
    748 	struct upl_softc	*sc = xsc;
    749 	struct ifnet		*ifp = &sc->sc_if;
    750 	int			s;
    751 
    752 	if (sc->sc_dying)
    753 		return;
    754 
    755 	DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
    756 
    757 	if (ifp->if_flags & IFF_RUNNING)
    758 		return;
    759 
    760 	s = splimp();
    761 
    762 	/* Init TX ring. */
    763 	if (upl_tx_list_init(sc) == ENOBUFS) {
    764 		printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
    765 		splx(s);
    766 		return;
    767 	}
    768 
    769 	/* Init RX ring. */
    770 	if (upl_rx_list_init(sc) == ENOBUFS) {
    771 		printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
    772 		splx(s);
    773 		return;
    774 	}
    775 
    776 	if (sc->sc_ep[UPL_ENDPT_RX] == NULL) {
    777 		if (upl_openpipes(sc)) {
    778 			splx(s);
    779 			return;
    780 		}
    781 	}
    782 
    783 	ifp->if_flags |= IFF_RUNNING;
    784 	ifp->if_flags &= ~IFF_OACTIVE;
    785 
    786 	splx(s);
    787 }
    788 
    789 Static int
    790 upl_openpipes(sc)
    791 	struct upl_softc	*sc;
    792 {
    793 	struct upl_chain	*c;
    794 	usbd_status		err;
    795 	int			i;
    796 
    797 	/* Open RX and TX pipes. */
    798 	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX],
    799 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]);
    800 	if (err) {
    801 		printf("%s: open rx pipe failed: %s\n",
    802 		    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
    803 		return (EIO);
    804 	}
    805 	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX],
    806 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]);
    807 	if (err) {
    808 		printf("%s: open tx pipe failed: %s\n",
    809 		    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
    810 		return (EIO);
    811 	}
    812 	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR],
    813 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc,
    814 	    &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr,
    815 	    UPL_INTR_INTERVAL);
    816 	if (err) {
    817 		printf("%s: open intr pipe failed: %s\n",
    818 		    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
    819 		return (EIO);
    820 	}
    821 
    822 
    823 #if 1
    824 	/* Start up the receive pipe. */
    825 	for (i = 0; i < UPL_RX_LIST_CNT; i++) {
    826 		c = &sc->sc_cdata.upl_rx_chain[i];
    827 		usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
    828 		    c, c->upl_buf, UPL_BUFSZ,
    829 		    USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
    830 		    upl_rxeof);
    831 		usbd_transfer(c->upl_xfer);
    832 	}
    833 #endif
    834 
    835 	return (0);
    836 }
    837 
    838 Static void
    839 upl_intr(xfer, priv, status)
    840 	usbd_xfer_handle	xfer;
    841 	usbd_private_handle	priv;
    842 	usbd_status		status;
    843 {
    844 	struct upl_softc	*sc = priv;
    845 	struct ifnet		*ifp = &sc->sc_if;
    846 	uByte			stat;
    847 
    848 	DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
    849 
    850 	if (sc->sc_dying)
    851 		return;
    852 
    853 	if (!(ifp->if_flags & IFF_RUNNING))
    854 		return;
    855 
    856 	if (status != USBD_NORMAL_COMPLETION) {
    857 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
    858 			return;
    859 		}
    860 		sc->sc_intr_errs++;
    861 		if (usbd_ratecheck(&sc->sc_rx_notice)) {
    862 			printf("%s: %u usb errors on intr: %s\n",
    863 			    USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
    864 			    usbd_errstr(status));
    865 			sc->sc_intr_errs = 0;
    866 		}
    867 		if (status == USBD_STALLED)
    868 			usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
    869 		return;
    870 	}
    871 
    872 	stat = sc->sc_ibuf;
    873 
    874 	if (stat == 0)
    875 		return;
    876 
    877 	DPRINTFN(10,("%s: %s: stat=0x%02x\n", USBDEVNAME(sc->sc_dev),
    878 		     __FUNCTION__, stat));
    879 
    880 }
    881 
    882 Static int
    883 upl_ioctl(ifp, command, data)
    884 	struct ifnet		*ifp;
    885 	u_long			command;
    886 	caddr_t			data;
    887 {
    888 	struct upl_softc	*sc = ifp->if_softc;
    889 	struct ifaddr 		*ifa = (struct ifaddr *)data;
    890 	struct ifreq		*ifr = (struct ifreq *)data;
    891 	int			s, error = 0;
    892 
    893 	if (sc->sc_dying)
    894 		return (EIO);
    895 
    896 	DPRINTFN(5,("%s: %s: cmd=0x%08lx\n",
    897 		    USBDEVNAME(sc->sc_dev), __FUNCTION__, command));
    898 
    899 	s = splimp();
    900 
    901 	switch(command) {
    902 	case SIOCSIFADDR:
    903 		ifp->if_flags |= IFF_UP;
    904 		upl_init(sc);
    905 
    906 		switch (ifa->ifa_addr->sa_family) {
    907 #ifdef INET
    908 		case AF_INET:
    909 			break;
    910 #endif /* INET */
    911 #ifdef NS
    912 		case AF_NS:
    913 		    {
    914 			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
    915 
    916 			if (ns_nullhost(*ina))
    917 				ina->x_host = *(union ns_host *)
    918 					LLADDR(ifp->if_sadl);
    919 			else
    920 				memcpy(LLADDR(ifp->if_sadl),
    921 				       ina->x_host.c_host,
    922 				       ifp->if_addrlen);
    923 			break;
    924 		    }
    925 #endif /* NS */
    926 		}
    927 		break;
    928 
    929 	case SIOCSIFMTU:
    930 		if (ifr->ifr_mtu > UPL_BUFSZ)
    931 			error = EINVAL;
    932 		else
    933 			ifp->if_mtu = ifr->ifr_mtu;
    934 		break;
    935 
    936 	case SIOCSIFFLAGS:
    937 		if (ifp->if_flags & IFF_UP) {
    938 			if (!(ifp->if_flags & IFF_RUNNING))
    939 				upl_init(sc);
    940 		} else {
    941 			if (ifp->if_flags & IFF_RUNNING)
    942 				upl_stop(sc);
    943 		}
    944 		error = 0;
    945 		break;
    946 	default:
    947 		error = EINVAL;
    948 		break;
    949 	}
    950 
    951 	splx(s);
    952 
    953 	return (error);
    954 }
    955 
    956 Static void
    957 upl_watchdog(ifp)
    958 	struct ifnet		*ifp;
    959 {
    960 	struct upl_softc	*sc = ifp->if_softc;
    961 
    962 	DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
    963 
    964 	if (sc->sc_dying)
    965 		return;
    966 
    967 	ifp->if_oerrors++;
    968 	printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
    969 
    970 	upl_stop(sc);
    971 	upl_init(sc);
    972 
    973 	if (ifp->if_snd.ifq_head != NULL)
    974 		upl_start(ifp);
    975 }
    976 
    977 /*
    978  * Stop the adapter and free any mbufs allocated to the
    979  * RX and TX lists.
    980  */
    981 Static void
    982 upl_stop(sc)
    983 	struct upl_softc	*sc;
    984 {
    985 	usbd_status		err;
    986 	struct ifnet		*ifp;
    987 	int			i;
    988 
    989 	DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
    990 
    991 	ifp = &sc->sc_if;
    992 	ifp->if_timer = 0;
    993 
    994 	/* Stop transfers. */
    995 	if (sc->sc_ep[UPL_ENDPT_RX] != NULL) {
    996 		err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]);
    997 		if (err) {
    998 			printf("%s: abort rx pipe failed: %s\n",
    999 			USBDEVNAME(sc->sc_dev), usbd_errstr(err));
   1000 		}
   1001 		err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]);
   1002 		if (err) {
   1003 			printf("%s: close rx pipe failed: %s\n",
   1004 			USBDEVNAME(sc->sc_dev), usbd_errstr(err));
   1005 		}
   1006 		sc->sc_ep[UPL_ENDPT_RX] = NULL;
   1007 	}
   1008 
   1009 	if (sc->sc_ep[UPL_ENDPT_TX] != NULL) {
   1010 		err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]);
   1011 		if (err) {
   1012 			printf("%s: abort tx pipe failed: %s\n",
   1013 			USBDEVNAME(sc->sc_dev), usbd_errstr(err));
   1014 		}
   1015 		err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]);
   1016 		if (err) {
   1017 			printf("%s: close tx pipe failed: %s\n",
   1018 			    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
   1019 		}
   1020 		sc->sc_ep[UPL_ENDPT_TX] = NULL;
   1021 	}
   1022 
   1023 	if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) {
   1024 		err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
   1025 		if (err) {
   1026 			printf("%s: abort intr pipe failed: %s\n",
   1027 			USBDEVNAME(sc->sc_dev), usbd_errstr(err));
   1028 		}
   1029 		err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
   1030 		if (err) {
   1031 			printf("%s: close intr pipe failed: %s\n",
   1032 			    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
   1033 		}
   1034 		sc->sc_ep[UPL_ENDPT_INTR] = NULL;
   1035 	}
   1036 
   1037 	/* Free RX resources. */
   1038 	for (i = 0; i < UPL_RX_LIST_CNT; i++) {
   1039 		if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) {
   1040 			m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf);
   1041 			sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL;
   1042 		}
   1043 		if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) {
   1044 			usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer);
   1045 			sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL;
   1046 		}
   1047 	}
   1048 
   1049 	/* Free TX resources. */
   1050 	for (i = 0; i < UPL_TX_LIST_CNT; i++) {
   1051 		if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) {
   1052 			m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf);
   1053 			sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL;
   1054 		}
   1055 		if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) {
   1056 			usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer);
   1057 			sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL;
   1058 		}
   1059 	}
   1060 
   1061 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   1062 }
   1063 
   1064 Static int
   1065 upl_output(ifp, m, dst, rt0)
   1066 	struct ifnet *ifp;
   1067 	struct mbuf *m;
   1068 	struct sockaddr *dst;
   1069 	struct rtentry *rt0;
   1070 {
   1071 	int s;
   1072 
   1073 	DPRINTFN(10,("%s: %s: enter\n",
   1074 		     USBDEVNAME(((struct upl_softc *)ifp->if_softc)->sc_dev),
   1075 		     __FUNCTION__));
   1076 
   1077 	s = splimp();
   1078 	/*
   1079 	 * Queue message on interface, and start output if interface
   1080 	 * not yet active.
   1081 	 */
   1082 	if (IF_QFULL(&ifp->if_snd)) {
   1083 		IF_DROP(&ifp->if_snd);
   1084 		splx(s);
   1085 		return (ENOBUFS);
   1086 	}
   1087 	ifp->if_obytes += m->m_pkthdr.len;
   1088 	IF_ENQUEUE(&ifp->if_snd, m);
   1089 	if ((ifp->if_flags & IFF_OACTIVE) == 0)
   1090 		(*ifp->if_start)(ifp);
   1091 	splx(s);
   1092 
   1093 	return (0);
   1094 }
   1095 
   1096 Static void
   1097 upl_input(ifp, m)
   1098 	struct ifnet *ifp;
   1099 	struct mbuf *m;
   1100 {
   1101 	struct ifqueue *inq;
   1102 	int s;
   1103 
   1104 	/* XXX Assume all traffic is IP */
   1105 
   1106 	schednetisr(NETISR_IP);
   1107 	inq = &ipintrq;
   1108 
   1109 	if (IF_QFULL(inq)) {
   1110 		IF_DROP(inq);
   1111 		splx(s);
   1112 		//if (sc->sc_flags & SC_DEBUG)
   1113 		//printf("%s: input queue full\n", ifp->if_xname);
   1114 		ifp->if_iqdrops++;
   1115 		return;
   1116 	}
   1117 	IF_ENQUEUE(inq, m);
   1118 	splx(s);
   1119 	ifp->if_ipackets++;
   1120 	ifp->if_ibytes += m->m_len;
   1121 	ifp->if_lastchange = time;
   1122 }
   1123