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