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