xref: /netbsd-src/sys/dev/usb/if_upl.c (revision deb6f0161a9109e7de9b519dc8dfb9478668dcdd)
1 /*	$NetBSD: if_upl.c,v 1.62 2018/06/26 06:48:02 msaitoh 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  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Prolific PL2301/PL2302 driver
34  */
35 
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.62 2018/06/26 06:48:02 msaitoh Exp $");
38 
39 #ifdef _KERNEL_OPT
40 #include "opt_inet.h"
41 #include "opt_usb.h"
42 #endif
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/callout.h>
47 #include <sys/sockio.h>
48 #include <sys/mbuf.h>
49 #include <sys/kernel.h>
50 #include <sys/socket.h>
51 
52 #include <sys/device.h>
53 #include <sys/rndsource.h>
54 
55 #include <net/if.h>
56 #include <net/if_types.h>
57 #include <net/if_dl.h>
58 #include <net/netisr.h>
59 
60 #include <net/bpf.h>
61 
62 #ifdef INET
63 #include <netinet/in.h>
64 #include <netinet/in_var.h>
65 #include <netinet/if_inarp.h>
66 #endif
67 
68 
69 #include <dev/usb/usb.h>
70 #include <dev/usb/usbdi.h>
71 #include <dev/usb/usbdi_util.h>
72 #include <dev/usb/usbdevs.h>
73 
74 /*
75  * 7  6  5  4  3  2  1  0
76  * tx rx 1  0
77  * 1110 0000 rxdata
78  * 1010 0000 idle
79  * 0010 0000 tx over
80  * 0110      tx over + rxd
81  */
82 
83 #define UPL_RXDATA		0x40
84 #define UPL_TXOK		0x80
85 
86 #define UPL_INTR_PKTLEN		1
87 
88 #define UPL_CONFIG_NO		1
89 #define UPL_IFACE_IDX		0
90 
91 /***/
92 
93 #define UPL_INTR_INTERVAL	20
94 
95 #define UPL_BUFSZ		1024
96 
97 #define UPL_RX_FRAMES		1
98 #define UPL_TX_FRAMES		1
99 
100 #define UPL_RX_LIST_CNT		1
101 #define UPL_TX_LIST_CNT		1
102 
103 #define UPL_ENDPT_RX		0x0
104 #define UPL_ENDPT_TX		0x1
105 #define UPL_ENDPT_INTR		0x2
106 #define UPL_ENDPT_MAX		0x3
107 
108 struct upl_type {
109 	uint16_t		upl_vid;
110 	uint16_t		upl_did;
111 };
112 
113 struct upl_softc;
114 
115 struct upl_chain {
116 	struct upl_softc	*upl_sc;
117 	struct usbd_xfer	*upl_xfer;
118 	char			*upl_buf;
119 	struct mbuf		*upl_mbuf;
120 	int			upl_idx;
121 };
122 
123 struct upl_cdata {
124 	struct upl_chain	upl_tx_chain[UPL_TX_LIST_CNT];
125 	struct upl_chain	upl_rx_chain[UPL_RX_LIST_CNT];
126 	int			upl_tx_prod;
127 	int			upl_tx_cons;
128 	int			upl_tx_cnt;
129 	int			upl_rx_prod;
130 };
131 
132 struct upl_softc {
133 	device_t		sc_dev;
134 
135 	struct ifnet		sc_if;
136 	krndsource_t	sc_rnd_source;
137 
138 	struct callout		sc_stat_ch;
139 
140 	struct usbd_device *	sc_udev;
141 	struct usbd_interface *	sc_iface;
142 	uint16_t		sc_vendor;
143 	uint16_t		sc_product;
144 	int			sc_ed[UPL_ENDPT_MAX];
145 	struct usbd_pipe *	sc_ep[UPL_ENDPT_MAX];
146 	struct upl_cdata	sc_cdata;
147 
148 	uByte			sc_ibuf;
149 
150 	char			sc_dying;
151 	char			sc_attached;
152 	u_int			sc_rx_errs;
153 	struct timeval		sc_rx_notice;
154 	u_int			sc_intr_errs;
155 };
156 
157 #ifdef UPL_DEBUG
158 #define DPRINTF(x)	if (upldebug) printf x
159 #define DPRINTFN(n,x)	if (upldebug >= (n)) printf x
160 int	upldebug = 0;
161 #else
162 #define DPRINTF(x)
163 #define DPRINTFN(n,x)
164 #endif
165 
166 /*
167  * Various supported device vendors/products.
168  */
169 Static struct upl_type sc_devs[] = {
170 	{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 },
171 	{ USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 },
172 	{ 0, 0 }
173 };
174 
175 int	upl_match(device_t, cfdata_t, void *);
176 void	upl_attach(device_t, device_t, void *);
177 int	upl_detach(device_t, int);
178 int	upl_activate(device_t, enum devact);
179 extern struct cfdriver upl_cd;
180 CFATTACH_DECL_NEW(upl, sizeof(struct upl_softc), upl_match, upl_attach,
181     upl_detach, upl_activate);
182 
183 Static int upl_openpipes(struct upl_softc *);
184 Static int upl_tx_list_init(struct upl_softc *);
185 Static int upl_rx_list_init(struct upl_softc *);
186 Static int upl_newbuf(struct upl_softc *, struct upl_chain *, struct mbuf *);
187 Static int upl_send(struct upl_softc *, struct mbuf *, int);
188 Static void upl_intr(struct usbd_xfer *, void *, usbd_status);
189 Static void upl_rxeof(struct usbd_xfer *, void *, usbd_status);
190 Static void upl_txeof(struct usbd_xfer *, void *, usbd_status);
191 Static void upl_start(struct ifnet *);
192 Static int upl_ioctl(struct ifnet *, u_long, void *);
193 Static void upl_init(void *);
194 Static void upl_stop(struct upl_softc *);
195 Static void upl_watchdog(struct ifnet *);
196 
197 Static int upl_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
198 		      const struct rtentry *);
199 Static void upl_input(struct ifnet *, struct mbuf *);
200 
201 /*
202  * Probe for a Prolific chip.
203  */
204 int
205 upl_match(device_t parent, cfdata_t match, void *aux)
206 {
207 	struct usb_attach_arg *uaa = aux;
208 	struct upl_type			*t;
209 
210 	for (t = sc_devs; t->upl_vid != 0; t++)
211 		if (uaa->uaa_vendor == t->upl_vid && uaa->uaa_product == t->upl_did)
212 			return UMATCH_VENDOR_PRODUCT;
213 
214 	return UMATCH_NONE;
215 }
216 
217 void
218 upl_attach(device_t parent, device_t self, void *aux)
219 {
220 	struct upl_softc *sc = device_private(self);
221 	struct usb_attach_arg *uaa = aux;
222 	char			*devinfop;
223 	int			s;
224 	struct usbd_device *	dev = uaa->uaa_device;
225 	struct usbd_interface *	iface;
226 	usbd_status		err;
227 	struct ifnet		*ifp;
228 	usb_interface_descriptor_t	*id;
229 	usb_endpoint_descriptor_t	*ed;
230 	int			i;
231 	int			rv;
232 
233 	DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev));
234 
235 	sc->sc_dev = self;
236 
237 	aprint_naive("\n");
238 	aprint_normal("\n");
239 
240 	devinfop = usbd_devinfo_alloc(dev, 0);
241 	aprint_normal_dev(self, "%s\n", devinfop);
242 	usbd_devinfo_free(devinfop);
243 
244 	err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1);
245 	if (err) {
246 		aprint_error_dev(self, "failed to set configuration"
247 		    ", err=%s\n", usbd_errstr(err));
248 		return;
249 	}
250 
251 	sc->sc_udev = dev;
252 	sc->sc_product = uaa->uaa_product;
253 	sc->sc_vendor = uaa->uaa_vendor;
254 
255 	err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface);
256 	if (err) {
257 		aprint_error_dev(self, "getting interface handle failed\n");
258 		return;
259 	}
260 
261 	sc->sc_iface = iface;
262 	id = usbd_get_interface_descriptor(iface);
263 
264 	/* Find endpoints. */
265 	for (i = 0; i < id->bNumEndpoints; i++) {
266 		ed = usbd_interface2endpoint_descriptor(iface, i);
267 		if (ed == NULL) {
268 			aprint_error_dev(self, "couldn't get ep %d\n", i);
269 			return;
270 		}
271 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
272 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
273 			sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress;
274 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
275 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
276 			sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress;
277 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
278 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
279 			sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress;
280 		}
281 	}
282 
283 	if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 ||
284 	    sc->sc_ed[UPL_ENDPT_INTR] == 0) {
285 		aprint_error_dev(self, "missing endpoint\n");
286 		return;
287 	}
288 
289 	s = splnet();
290 
291 	/* Initialize interface info.*/
292 	ifp = &sc->sc_if;
293 	ifp->if_softc = sc;
294 	ifp->if_mtu = UPL_BUFSZ;
295 	ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX;
296 	ifp->if_ioctl = upl_ioctl;
297 	ifp->if_start = upl_start;
298 	ifp->if_watchdog = upl_watchdog;
299 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
300 
301 	ifp->if_type = IFT_OTHER;
302 	ifp->if_addrlen = 0;
303 	ifp->if_hdrlen = 0;
304 	ifp->if_output = upl_output;
305 	ifp->_if_input = upl_input;
306 	ifp->if_baudrate = 12000000;
307 	ifp->if_dlt = DLT_RAW;
308 	IFQ_SET_READY(&ifp->if_snd);
309 
310 	/* Attach the interface. */
311 	rv = if_initialize(ifp);
312 	if (rv != 0) {
313 		aprint_error_dev(self, "if_initialize failed(%d)\n", rv);
314 		splx(s);
315 		return;
316 	}
317 	if_register(ifp);
318 	if_alloc_sadl(ifp);
319 
320 	bpf_attach(ifp, DLT_RAW, 0);
321 	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
322 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
323 
324 	sc->sc_attached = 1;
325 	splx(s);
326 
327 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
328 
329 	return;
330 }
331 
332 int
333 upl_detach(device_t self, int flags)
334 {
335 	struct upl_softc *sc = device_private(self);
336 	struct ifnet		*ifp = &sc->sc_if;
337 	int			s;
338 
339 	DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
340 
341 	s = splusb();
342 
343 	if (!sc->sc_attached) {
344 		/* Detached before attached finished, so just bail out. */
345 		splx(s);
346 		return 0;
347 	}
348 
349 	if (ifp->if_flags & IFF_RUNNING)
350 		upl_stop(sc);
351 
352 	rnd_detach_source(&sc->sc_rnd_source);
353 	bpf_detach(ifp);
354 
355 	if_detach(ifp);
356 
357 #ifdef DIAGNOSTIC
358 	if (sc->sc_ep[UPL_ENDPT_TX] != NULL ||
359 	    sc->sc_ep[UPL_ENDPT_RX] != NULL ||
360 	    sc->sc_ep[UPL_ENDPT_INTR] != NULL)
361 		aprint_debug_dev(self, "detach has active endpoints\n");
362 #endif
363 
364 	sc->sc_attached = 0;
365 	splx(s);
366 
367 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
368 
369 	return 0;
370 }
371 
372 int
373 upl_activate(device_t self, enum devact act)
374 {
375 	struct upl_softc *sc = device_private(self);
376 
377 	DPRINTFN(2,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
378 
379 	switch (act) {
380 	case DVACT_DEACTIVATE:
381 		/* Deactivate the interface. */
382 		if_deactivate(&sc->sc_if);
383 		sc->sc_dying = 1;
384 		return 0;
385 	default:
386 		return EOPNOTSUPP;
387 	}
388 }
389 
390 /*
391  * Initialize an RX descriptor and attach an MBUF cluster.
392  */
393 Static int
394 upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m)
395 {
396 	struct mbuf		*m_new = NULL;
397 
398 	DPRINTFN(8,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
399 
400 	if (m == NULL) {
401 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
402 		if (m_new == NULL) {
403 			printf("%s: no memory for rx list "
404 			    "-- packet dropped!\n", device_xname(sc->sc_dev));
405 			return ENOBUFS;
406 		}
407 
408 		MCLGET(m_new, M_DONTWAIT);
409 		if (!(m_new->m_flags & M_EXT)) {
410 			printf("%s: no memory for rx list "
411 			    "-- packet dropped!\n", device_xname(sc->sc_dev));
412 			m_freem(m_new);
413 			return ENOBUFS;
414 		}
415 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
416 	} else {
417 		m_new = m;
418 		m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
419 		m_new->m_data = m_new->m_ext.ext_buf;
420 	}
421 
422 	c->upl_mbuf = m_new;
423 
424 	return 0;
425 }
426 
427 Static int
428 upl_rx_list_init(struct upl_softc *sc)
429 {
430 	struct upl_cdata	*cd;
431 	struct upl_chain	*c;
432 	int			i;
433 
434 	DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev), __func__));
435 
436 	cd = &sc->sc_cdata;
437 	for (i = 0; i < UPL_RX_LIST_CNT; i++) {
438 		c = &cd->upl_rx_chain[i];
439 		c->upl_sc = sc;
440 		c->upl_idx = i;
441 		if (upl_newbuf(sc, c, NULL) == ENOBUFS)
442 			return ENOBUFS;
443 		if (c->upl_xfer == NULL) {
444 			int error = usbd_create_xfer(sc->sc_ep[UPL_ENDPT_RX],
445 			    UPL_BUFSZ, 0, 0, &c->upl_xfer);
446 			if (error)
447 				return error;
448 			c->upl_buf = usbd_get_buffer(c->upl_xfer);
449 		}
450 	}
451 
452 	return 0;
453 }
454 
455 Static int
456 upl_tx_list_init(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", device_xname(sc->sc_dev), __func__));
463 
464 	cd = &sc->sc_cdata;
465 	for (i = 0; i < UPL_TX_LIST_CNT; i++) {
466 		c = &cd->upl_tx_chain[i];
467 		c->upl_sc = sc;
468 		c->upl_idx = i;
469 		c->upl_mbuf = NULL;
470 		if (c->upl_xfer == NULL) {
471 			int error = usbd_create_xfer(sc->sc_ep[UPL_ENDPT_TX],
472 			    UPL_BUFSZ, 0, 0, &c->upl_xfer);
473 			if (error)
474 				return error;
475 			c->upl_buf = usbd_get_buffer(c->upl_xfer);
476 		}
477 	}
478 
479 	return 0;
480 }
481 
482 /*
483  * A frame has been uploaded: pass the resulting mbuf chain up to
484  * the higher level protocols.
485  */
486 Static void
487 upl_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
488 {
489 	struct upl_chain	*c = priv;
490 	struct upl_softc	*sc = c->upl_sc;
491 	struct ifnet		*ifp = &sc->sc_if;
492 	struct mbuf		*m;
493 	int			total_len = 0;
494 	int			s;
495 
496 	if (sc->sc_dying)
497 		return;
498 
499 	if (!(ifp->if_flags & IFF_RUNNING))
500 		return;
501 
502 	if (status != USBD_NORMAL_COMPLETION) {
503 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
504 			return;
505 		sc->sc_rx_errs++;
506 		if (usbd_ratecheck(&sc->sc_rx_notice)) {
507 			printf("%s: %u usb errors on rx: %s\n",
508 			    device_xname(sc->sc_dev), sc->sc_rx_errs,
509 			    usbd_errstr(status));
510 			sc->sc_rx_errs = 0;
511 		}
512 		if (status == USBD_STALLED)
513 			usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]);
514 		goto done;
515 	}
516 
517 	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
518 
519 	DPRINTFN(9,("%s: %s: enter status=%d length=%d\n",
520 		    device_xname(sc->sc_dev), __func__, status, total_len));
521 
522 	m = c->upl_mbuf;
523 	memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len);
524 
525 	m->m_pkthdr.len = m->m_len = total_len;
526 
527 	m_set_rcvif(m, ifp);
528 
529 	s = splnet();
530 
531 	/* XXX ugly */
532 	if (upl_newbuf(sc, c, NULL) == ENOBUFS) {
533 		ifp->if_ierrors++;
534 		goto done1;
535 	}
536 
537 	DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->sc_dev),
538 		    __func__, m->m_len));
539 
540 	if_input((ifp), (m));
541 
542  done1:
543 	splx(s);
544 
545  done:
546 #if 1
547 	/* Setup new transfer. */
548 	usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ,
549 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upl_rxeof);
550 	usbd_transfer(c->upl_xfer);
551 
552 	DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->sc_dev),
553 		    __func__));
554 #endif
555 }
556 
557 /*
558  * A frame was downloaded to the chip. It's safe for us to clean up
559  * the list buffers.
560  */
561 Static void
562 upl_txeof(struct usbd_xfer *xfer, void *priv,
563     usbd_status status)
564 {
565 	struct upl_chain	*c = priv;
566 	struct upl_softc	*sc = c->upl_sc;
567 	struct ifnet		*ifp = &sc->sc_if;
568 	int			s;
569 
570 	if (sc->sc_dying)
571 		return;
572 
573 	s = splnet();
574 
575 	DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->sc_dev),
576 		    __func__, status));
577 
578 	ifp->if_timer = 0;
579 	ifp->if_flags &= ~IFF_OACTIVE;
580 
581 	if (status != USBD_NORMAL_COMPLETION) {
582 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
583 			splx(s);
584 			return;
585 		}
586 		ifp->if_oerrors++;
587 		printf("%s: usb error on tx: %s\n", device_xname(sc->sc_dev),
588 		    usbd_errstr(status));
589 		if (status == USBD_STALLED)
590 			usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_TX]);
591 		splx(s);
592 		return;
593 	}
594 
595 	ifp->if_opackets++;
596 
597 	m_freem(c->upl_mbuf);
598 	c->upl_mbuf = NULL;
599 
600 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
601 		upl_start(ifp);
602 
603 	splx(s);
604 }
605 
606 Static int
607 upl_send(struct upl_softc *sc, struct mbuf *m, int idx)
608 {
609 	int			total_len;
610 	struct upl_chain	*c;
611 	usbd_status		err;
612 
613 	c = &sc->sc_cdata.upl_tx_chain[idx];
614 
615 	/*
616 	 * Copy the mbuf data into a contiguous buffer, leaving two
617 	 * bytes at the beginning to hold the frame length.
618 	 */
619 	m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf);
620 	c->upl_mbuf = m;
621 
622 	total_len = m->m_pkthdr.len;
623 
624 	DPRINTFN(10,("%s: %s: total_len=%d\n",
625 		     device_xname(sc->sc_dev), __func__, total_len));
626 
627 	usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, total_len, 0,
628 	    USBD_DEFAULT_TIMEOUT, upl_txeof);
629 
630 	/* Transmit */
631 	err = usbd_transfer(c->upl_xfer);
632 	if (err != USBD_IN_PROGRESS) {
633 		printf("%s: upl_send error=%s\n", device_xname(sc->sc_dev),
634 		       usbd_errstr(err));
635 		upl_stop(sc);
636 		return EIO;
637 	}
638 
639 	sc->sc_cdata.upl_tx_cnt++;
640 
641 	return 0;
642 }
643 
644 Static void
645 upl_start(struct ifnet *ifp)
646 {
647 	struct upl_softc	*sc = ifp->if_softc;
648 	struct mbuf		*m_head = NULL;
649 
650 	if (sc->sc_dying)
651 		return;
652 
653 	DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__));
654 
655 	if (ifp->if_flags & IFF_OACTIVE)
656 		return;
657 
658 	IFQ_POLL(&ifp->if_snd, m_head);
659 	if (m_head == NULL)
660 		return;
661 
662 	if (upl_send(sc, m_head, 0)) {
663 		ifp->if_flags |= IFF_OACTIVE;
664 		return;
665 	}
666 
667 	IFQ_DEQUEUE(&ifp->if_snd, m_head);
668 
669 	/*
670 	 * If there's a BPF listener, bounce a copy of this frame
671 	 * to him.
672 	 */
673 	bpf_mtap(ifp, m_head, BPF_D_OUT);
674 
675 	ifp->if_flags |= IFF_OACTIVE;
676 
677 	/*
678 	 * Set a timeout in case the chip goes out to lunch.
679 	 */
680 	ifp->if_timer = 5;
681 }
682 
683 Static void
684 upl_init(void *xsc)
685 {
686 	struct upl_softc	*sc = xsc;
687 	struct ifnet		*ifp = &sc->sc_if;
688 	int			s;
689 
690 	if (sc->sc_dying)
691 		return;
692 
693 	DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__));
694 
695 	if (ifp->if_flags & IFF_RUNNING)
696 		return;
697 
698 	s = splnet();
699 
700 	if (sc->sc_ep[UPL_ENDPT_RX] == NULL) {
701 		if (upl_openpipes(sc)) {
702 			splx(s);
703 			return;
704 		}
705 	}
706 	/* Init TX ring. */
707 	if (upl_tx_list_init(sc)) {
708 		printf("%s: tx list init failed\n", device_xname(sc->sc_dev));
709 		splx(s);
710 		return;
711 	}
712 
713 	/* Init RX ring. */
714 	if (upl_rx_list_init(sc)) {
715 		printf("%s: rx list init failed\n", device_xname(sc->sc_dev));
716 		splx(s);
717 		return;
718 	}
719 
720 	/* Start up the receive pipe. */
721 	for (int i = 0; i < UPL_RX_LIST_CNT; i++) {
722 		struct upl_chain *c = &sc->sc_cdata.upl_rx_chain[i];
723 		usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ,
724 		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
725 		    upl_rxeof);
726 		usbd_transfer(c->upl_xfer);
727 	}
728 
729 	ifp->if_flags |= IFF_RUNNING;
730 	ifp->if_flags &= ~IFF_OACTIVE;
731 
732 	splx(s);
733 }
734 
735 Static int
736 upl_openpipes(struct upl_softc *sc)
737 {
738 	usbd_status		err;
739 
740 	/* Open RX and TX pipes. */
741 	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX],
742 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]);
743 	if (err) {
744 		printf("%s: open rx pipe failed: %s\n",
745 		    device_xname(sc->sc_dev), usbd_errstr(err));
746 		return EIO;
747 	}
748 	err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX],
749 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]);
750 	if (err) {
751 		printf("%s: open tx pipe failed: %s\n",
752 		    device_xname(sc->sc_dev), usbd_errstr(err));
753 		return EIO;
754 	}
755 	err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR],
756 	    USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc,
757 	    &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr,
758 	    UPL_INTR_INTERVAL);
759 	if (err) {
760 		printf("%s: open intr pipe failed: %s\n",
761 		    device_xname(sc->sc_dev), usbd_errstr(err));
762 		return EIO;
763 	}
764 
765 	return 0;
766 }
767 
768 Static void
769 upl_intr(struct usbd_xfer *xfer, void *priv,
770     usbd_status status)
771 {
772 	struct upl_softc	*sc = priv;
773 	struct ifnet		*ifp = &sc->sc_if;
774 	uByte			stat;
775 
776 	DPRINTFN(15,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__));
777 
778 	if (sc->sc_dying)
779 		return;
780 
781 	if (!(ifp->if_flags & IFF_RUNNING))
782 		return;
783 
784 	if (status != USBD_NORMAL_COMPLETION) {
785 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
786 			return;
787 		}
788 		sc->sc_intr_errs++;
789 		if (usbd_ratecheck(&sc->sc_rx_notice)) {
790 			printf("%s: %u usb errors on intr: %s\n",
791 			    device_xname(sc->sc_dev), sc->sc_rx_errs,
792 			    usbd_errstr(status));
793 			sc->sc_intr_errs = 0;
794 		}
795 		if (status == USBD_STALLED)
796 			usbd_clear_endpoint_stall_async(sc->sc_ep[UPL_ENDPT_RX]);
797 		return;
798 	}
799 
800 	stat = sc->sc_ibuf;
801 
802 	if (stat == 0)
803 		return;
804 
805 	DPRINTFN(10,("%s: %s: stat=0x%02x\n", device_xname(sc->sc_dev),
806 		     __func__, stat));
807 
808 }
809 
810 Static int
811 upl_ioctl(struct ifnet *ifp, u_long command, void *data)
812 {
813 	struct upl_softc	*sc = ifp->if_softc;
814 	struct ifaddr 		*ifa = (struct ifaddr *)data;
815 	struct ifreq		*ifr = (struct ifreq *)data;
816 	int			s, error = 0;
817 
818 	if (sc->sc_dying)
819 		return EIO;
820 
821 	DPRINTFN(5,("%s: %s: cmd=0x%08lx\n",
822 		    device_xname(sc->sc_dev), __func__, command));
823 
824 	s = splnet();
825 
826 	switch(command) {
827 	case SIOCINITIFADDR:
828 		ifp->if_flags |= IFF_UP;
829 		upl_init(sc);
830 
831 		switch (ifa->ifa_addr->sa_family) {
832 #ifdef INET
833 		case AF_INET:
834 			break;
835 #endif /* INET */
836 		}
837 		break;
838 
839 	case SIOCSIFMTU:
840 		if (ifr->ifr_mtu > UPL_BUFSZ)
841 			error = EINVAL;
842 		else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET)
843 			error = 0;
844 		break;
845 
846 	case SIOCSIFFLAGS:
847 		if ((error = ifioctl_common(ifp, command, data)) != 0)
848 			break;
849 		/* XXX re-use ether_ioctl() */
850 		switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
851 		case IFF_UP:
852 			upl_init(sc);
853 			break;
854 		case IFF_RUNNING:
855 			upl_stop(sc);
856 			break;
857 		default:
858 			break;
859 		}
860 		break;
861 	default:
862 		error = ifioctl_common(ifp, command, data);
863 		break;
864 	}
865 
866 	splx(s);
867 
868 	return error;
869 }
870 
871 Static void
872 upl_watchdog(struct ifnet *ifp)
873 {
874 	struct upl_softc	*sc = ifp->if_softc;
875 
876 	DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__));
877 
878 	if (sc->sc_dying)
879 		return;
880 
881 	ifp->if_oerrors++;
882 	printf("%s: watchdog timeout\n", device_xname(sc->sc_dev));
883 
884 	upl_stop(sc);
885 	upl_init(sc);
886 
887 	if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
888 		upl_start(ifp);
889 }
890 
891 /*
892  * Stop the adapter and free any mbufs allocated to the
893  * RX and TX lists.
894  */
895 Static void
896 upl_stop(struct upl_softc *sc)
897 {
898 	usbd_status		err;
899 	struct ifnet		*ifp;
900 	int			i;
901 
902 	DPRINTFN(10,("%s: %s: enter\n", device_xname(sc->sc_dev),__func__));
903 
904 	ifp = &sc->sc_if;
905 	ifp->if_timer = 0;
906 
907 	/* Stop transfers. */
908 	if (sc->sc_ep[UPL_ENDPT_RX] != NULL) {
909 		err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]);
910 		if (err) {
911 			printf("%s: abort rx pipe failed: %s\n",
912 			device_xname(sc->sc_dev), usbd_errstr(err));
913 		}
914 	}
915 
916 	if (sc->sc_ep[UPL_ENDPT_TX] != NULL) {
917 		err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]);
918 		if (err) {
919 			printf("%s: abort tx pipe failed: %s\n",
920 			device_xname(sc->sc_dev), usbd_errstr(err));
921 		}
922 	}
923 
924 	if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) {
925 		err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
926 		if (err) {
927 			printf("%s: abort intr pipe failed: %s\n",
928 			device_xname(sc->sc_dev), usbd_errstr(err));
929 		}
930 	}
931 
932 	/* Free RX resources. */
933 	for (i = 0; i < UPL_RX_LIST_CNT; i++) {
934 		if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) {
935 			m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf);
936 			sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL;
937 		}
938 	}
939 
940 	/* Free TX resources. */
941 	for (i = 0; i < UPL_TX_LIST_CNT; i++) {
942 		if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) {
943 			m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf);
944 			sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL;
945 		}
946 		if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) {
947 			usbd_destroy_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer);
948 			sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL;
949 		}
950 	}
951 
952 	/* Close pipes */
953 	if (sc->sc_ep[UPL_ENDPT_RX] != NULL) {
954 		err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]);
955 		if (err) {
956 			printf("%s: close rx pipe failed: %s\n",
957 			device_xname(sc->sc_dev), usbd_errstr(err));
958 		}
959 		sc->sc_ep[UPL_ENDPT_RX] = NULL;
960 	}
961 
962 	if (sc->sc_ep[UPL_ENDPT_TX] != NULL) {
963 		err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]);
964 		if (err) {
965 			printf("%s: close tx pipe failed: %s\n",
966 			    device_xname(sc->sc_dev), usbd_errstr(err));
967 		}
968 		sc->sc_ep[UPL_ENDPT_TX] = NULL;
969 	}
970 
971 	if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) {
972 		err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
973 		if (err) {
974 			printf("%s: close intr pipe failed: %s\n",
975 			    device_xname(sc->sc_dev), usbd_errstr(err));
976 		}
977 		sc->sc_ep[UPL_ENDPT_INTR] = NULL;
978 	}
979 
980 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
981 }
982 
983 Static int
984 upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
985     const struct rtentry *rt0)
986 {
987 	int error;
988 
989 	DPRINTFN(10,("%s: %s: enter\n",
990 		     device_xname(((struct upl_softc *)ifp->if_softc)->sc_dev),
991 		     __func__));
992 
993 	/*
994 	 * if the queueing discipline needs packet classification,
995 	 * do it now.
996 	 */
997 	IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
998 
999 	/*
1000 	 * Queue message on interface, and start output if interface
1001 	 * not yet active.
1002 	 */
1003 	error = if_transmit_lock(ifp, m);
1004 
1005 	return error;
1006 }
1007 
1008 Static void
1009 upl_input(struct ifnet *ifp, struct mbuf *m)
1010 {
1011 #ifdef INET
1012 	size_t pktlen = m->m_len;
1013 	int s;
1014 
1015 	s = splnet();
1016 	if (__predict_false(!pktq_enqueue(ip_pktq, m, 0))) {
1017 		ifp->if_iqdrops++;
1018 		m_freem(m);
1019 	} else {
1020 		ifp->if_ipackets++;
1021 		ifp->if_ibytes += pktlen;
1022 	}
1023 	splx(s);
1024 #endif
1025 }
1026