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