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