if_upl.c revision 1.12 1 /* $NetBSD: if_upl.c,v 1.12 2001/01/21 02:22:27 augustss Exp $ */
2 /*
3 * Copyright (c) 2000 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Lennart Augustsson (lennart (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 = splimp();
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 IFQ_SET_READY(ifp->if_snd);
318
319 /* Attach the interface. */
320 if_attach(ifp);
321 if_alloc_sadl(ifp);
322
323 #if NBPFILTER > 0
324 bpfattach(ifp, DLT_RAW, 0);
325 #endif
326 #if NRND > 0
327 rnd_attach_source(&sc->sc_rnd_source, USBDEVNAME(sc->sc_dev),
328 RND_TYPE_NET, 0);
329 #endif
330
331 sc->sc_attached = 1;
332 splx(s);
333
334 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
335 USBDEV(sc->sc_dev));
336
337 USB_ATTACH_SUCCESS_RETURN;
338 }
339
340 USB_DETACH(upl)
341 {
342 USB_DETACH_START(upl, sc);
343 struct ifnet *ifp = &sc->sc_if;
344 int s;
345
346 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
347
348 s = splusb();
349
350 if (!sc->sc_attached) {
351 /* Detached before attached finished, so just bail out. */
352 splx(s);
353 return (0);
354 }
355
356 if (ifp->if_flags & IFF_RUNNING)
357 upl_stop(sc);
358
359 #if NRND > 0
360 rnd_detach_source(&sc->sc_rnd_source);
361 #endif
362 #if NBPFILTER > 0
363 bpfdetach(ifp);
364 #endif
365
366 if_detach(ifp);
367
368 #ifdef DIAGNOSTIC
369 if (sc->sc_ep[UPL_ENDPT_TX] != NULL ||
370 sc->sc_ep[UPL_ENDPT_RX] != NULL ||
371 sc->sc_ep[UPL_ENDPT_INTR] != NULL)
372 printf("%s: detach has active endpoints\n",
373 USBDEVNAME(sc->sc_dev));
374 #endif
375
376 sc->sc_attached = 0;
377 splx(s);
378
379 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
380 USBDEV(sc->sc_dev));
381
382 return (0);
383 }
384
385 int
386 upl_activate(device_ptr_t self, enum devact act)
387 {
388 struct upl_softc *sc = (struct upl_softc *)self;
389
390 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
391
392 switch (act) {
393 case DVACT_ACTIVATE:
394 return (EOPNOTSUPP);
395 break;
396
397 case DVACT_DEACTIVATE:
398 /* Deactivate the interface. */
399 if_deactivate(&sc->sc_if);
400 sc->sc_dying = 1;
401 break;
402 }
403 return (0);
404 }
405
406 /*
407 * Initialize an RX descriptor and attach an MBUF cluster.
408 */
409 Static int
410 upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m)
411 {
412 struct mbuf *m_new = NULL;
413
414 DPRINTFN(8,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
415
416 if (m == NULL) {
417 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
418 if (m_new == NULL) {
419 printf("%s: no memory for rx list "
420 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
421 return (ENOBUFS);
422 }
423
424 MCLGET(m_new, M_DONTWAIT);
425 if (!(m_new->m_flags & M_EXT)) {
426 printf("%s: no memory for rx list "
427 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
428 m_freem(m_new);
429 return (ENOBUFS);
430 }
431 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
432 } else {
433 m_new = m;
434 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
435 m_new->m_data = m_new->m_ext.ext_buf;
436 }
437
438 c->upl_mbuf = m_new;
439
440 return (0);
441 }
442
443 Static int
444 upl_rx_list_init(struct upl_softc *sc)
445 {
446 struct upl_cdata *cd;
447 struct upl_chain *c;
448 int i;
449
450 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
451
452 cd = &sc->sc_cdata;
453 for (i = 0; i < UPL_RX_LIST_CNT; i++) {
454 c = &cd->upl_rx_chain[i];
455 c->upl_sc = sc;
456 c->upl_idx = i;
457 if (upl_newbuf(sc, c, NULL) == ENOBUFS)
458 return (ENOBUFS);
459 if (c->upl_xfer == NULL) {
460 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
461 if (c->upl_xfer == NULL)
462 return (ENOBUFS);
463 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
464 if (c->upl_buf == NULL) {
465 usbd_free_xfer(c->upl_xfer);
466 return (ENOBUFS);
467 }
468 }
469 }
470
471 return (0);
472 }
473
474 Static int
475 upl_tx_list_init(struct upl_softc *sc)
476 {
477 struct upl_cdata *cd;
478 struct upl_chain *c;
479 int i;
480
481 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __FUNCTION__));
482
483 cd = &sc->sc_cdata;
484 for (i = 0; i < UPL_TX_LIST_CNT; i++) {
485 c = &cd->upl_tx_chain[i];
486 c->upl_sc = sc;
487 c->upl_idx = i;
488 c->upl_mbuf = NULL;
489 if (c->upl_xfer == NULL) {
490 c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
491 if (c->upl_xfer == NULL)
492 return (ENOBUFS);
493 c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
494 if (c->upl_buf == NULL) {
495 usbd_free_xfer(c->upl_xfer);
496 return (ENOBUFS);
497 }
498 }
499 }
500
501 return (0);
502 }
503
504 /*
505 * A frame has been uploaded: pass the resulting mbuf chain up to
506 * the higher level protocols.
507 */
508 Static void
509 upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
510 {
511 struct upl_chain *c = priv;
512 struct upl_softc *sc = c->upl_sc;
513 struct ifnet *ifp = &sc->sc_if;
514 struct mbuf *m;
515 int total_len = 0;
516 int s;
517
518 if (sc->sc_dying)
519 return;
520
521 if (!(ifp->if_flags & IFF_RUNNING))
522 return;
523
524 if (status != USBD_NORMAL_COMPLETION) {
525 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
526 return;
527 sc->sc_rx_errs++;
528 if (usbd_ratecheck(&sc->sc_rx_notice)) {
529 printf("%s: %u usb errors on rx: %s\n",
530 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
531 usbd_errstr(status));
532 sc->sc_rx_errs = 0;
533 }
534 if (status == USBD_STALLED)
535 usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
536 goto done;
537 }
538
539 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
540
541 DPRINTFN(9,("%s: %s: enter status=%d length=%d\n",
542 USBDEVNAME(sc->sc_dev), __FUNCTION__, status, total_len));
543
544 m = c->upl_mbuf;
545 memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len);
546
547 ifp->if_ipackets++;
548 m->m_pkthdr.len = m->m_len = total_len;
549
550 m->m_pkthdr.rcvif = ifp;
551
552 s = splimp();
553
554 /* XXX ugly */
555 if (upl_newbuf(sc, c, NULL) == ENOBUFS) {
556 ifp->if_ierrors++;
557 goto done1;
558 }
559
560 #if NBPFILTER > 0
561 /*
562 * Handle BPF listeners. Let the BPF user see the packet, but
563 * don't pass it up to the ether_input() layer unless it's
564 * a broadcast packet, multicast packet, matches our ethernet
565 * address or the interface is in promiscuous mode.
566 */
567 if (ifp->if_bpf) {
568 BPF_MTAP(ifp, m);
569 }
570 #endif
571
572 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
573 __FUNCTION__, m->m_len));
574
575 IF_INPUT(ifp, m);
576
577 done1:
578 splx(s);
579
580 done:
581 #if 1
582 /* Setup new transfer. */
583 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
584 c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
585 USBD_NO_TIMEOUT, upl_rxeof);
586 usbd_transfer(c->upl_xfer);
587
588 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev),
589 __FUNCTION__));
590 #endif
591 }
592
593 /*
594 * A frame was downloaded to the chip. It's safe for us to clean up
595 * the list buffers.
596 */
597 Static void
598 upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
599 {
600 struct upl_chain *c = priv;
601 struct upl_softc *sc = c->upl_sc;
602 struct ifnet *ifp = &sc->sc_if;
603 int s;
604
605 if (sc->sc_dying)
606 return;
607
608 s = splimp();
609
610 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->sc_dev),
611 __FUNCTION__, status));
612
613 ifp->if_timer = 0;
614 ifp->if_flags &= ~IFF_OACTIVE;
615
616 if (status != USBD_NORMAL_COMPLETION) {
617 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
618 splx(s);
619 return;
620 }
621 ifp->if_oerrors++;
622 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
623 usbd_errstr(status));
624 if (status == USBD_STALLED)
625 usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_TX]);
626 splx(s);
627 return;
628 }
629
630 ifp->if_opackets++;
631
632 m_freem(c->upl_mbuf);
633 c->upl_mbuf = NULL;
634
635 if (ifp->if_snd.ifq_head != NULL)
636 upl_start(ifp);
637
638 splx(s);
639 }
640
641 Static int
642 upl_send(struct upl_softc *sc, struct mbuf *m, int idx)
643 {
644 int total_len;
645 struct upl_chain *c;
646 usbd_status err;
647
648 c = &sc->sc_cdata.upl_tx_chain[idx];
649
650 /*
651 * Copy the mbuf data into a contiguous buffer, leaving two
652 * bytes at the beginning to hold the frame length.
653 */
654 m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf);
655 c->upl_mbuf = m;
656
657 total_len = m->m_pkthdr.len;
658
659 DPRINTFN(10,("%s: %s: total_len=%d\n",
660 USBDEVNAME(sc->sc_dev), __FUNCTION__, total_len));
661
662 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX],
663 c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT,
664 upl_txeof);
665
666 /* Transmit */
667 err = usbd_transfer(c->upl_xfer);
668 if (err != USBD_IN_PROGRESS) {
669 printf("%s: upl_send error=%s\n", USBDEVNAME(sc->sc_dev),
670 usbd_errstr(err));
671 upl_stop(sc);
672 return (EIO);
673 }
674
675 sc->sc_cdata.upl_tx_cnt++;
676
677 return (0);
678 }
679
680 Static void
681 upl_start(struct ifnet *ifp)
682 {
683 struct upl_softc *sc = ifp->if_softc;
684 struct mbuf *m_head = NULL;
685
686 if (sc->sc_dying)
687 return;
688
689 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
690
691 if (ifp->if_flags & IFF_OACTIVE)
692 return;
693
694 IF_DEQUEUE(&ifp->if_snd, m_head);
695 if (m_head == NULL)
696 return;
697
698 if (upl_send(sc, m_head, 0)) {
699 IF_PREPEND(&ifp->if_snd, m_head);
700 ifp->if_flags |= IFF_OACTIVE;
701 return;
702 }
703
704 #if NBPFILTER > 0
705 /*
706 * If there's a BPF listener, bounce a copy of this frame
707 * to him.
708 */
709 if (ifp->if_bpf)
710 BPF_MTAP(ifp, m_head);
711 #endif
712
713 ifp->if_flags |= IFF_OACTIVE;
714
715 /*
716 * Set a timeout in case the chip goes out to lunch.
717 */
718 ifp->if_timer = 5;
719 }
720
721 Static void
722 upl_init(void *xsc)
723 {
724 struct upl_softc *sc = xsc;
725 struct ifnet *ifp = &sc->sc_if;
726 int s;
727
728 if (sc->sc_dying)
729 return;
730
731 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
732
733 if (ifp->if_flags & IFF_RUNNING)
734 return;
735
736 s = splimp();
737
738 /* Init TX ring. */
739 if (upl_tx_list_init(sc) == ENOBUFS) {
740 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
741 splx(s);
742 return;
743 }
744
745 /* Init RX ring. */
746 if (upl_rx_list_init(sc) == ENOBUFS) {
747 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
748 splx(s);
749 return;
750 }
751
752 if (sc->sc_ep[UPL_ENDPT_RX] == NULL) {
753 if (upl_openpipes(sc)) {
754 splx(s);
755 return;
756 }
757 }
758
759 ifp->if_flags |= IFF_RUNNING;
760 ifp->if_flags &= ~IFF_OACTIVE;
761
762 splx(s);
763 }
764
765 Static int
766 upl_openpipes(struct upl_softc *sc)
767 {
768 struct upl_chain *c;
769 usbd_status err;
770 int i;
771
772 /* Open RX and TX pipes. */
773 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX],
774 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]);
775 if (err) {
776 printf("%s: open rx pipe failed: %s\n",
777 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
778 return (EIO);
779 }
780 err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX],
781 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]);
782 if (err) {
783 printf("%s: open tx pipe failed: %s\n",
784 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
785 return (EIO);
786 }
787 err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR],
788 USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc,
789 &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr,
790 UPL_INTR_INTERVAL);
791 if (err) {
792 printf("%s: open intr pipe failed: %s\n",
793 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
794 return (EIO);
795 }
796
797
798 #if 1
799 /* Start up the receive pipe. */
800 for (i = 0; i < UPL_RX_LIST_CNT; i++) {
801 c = &sc->sc_cdata.upl_rx_chain[i];
802 usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
803 c, c->upl_buf, UPL_BUFSZ,
804 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
805 upl_rxeof);
806 usbd_transfer(c->upl_xfer);
807 }
808 #endif
809
810 return (0);
811 }
812
813 Static void
814 upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
815 {
816 struct upl_softc *sc = priv;
817 struct ifnet *ifp = &sc->sc_if;
818 uByte stat;
819
820 DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
821
822 if (sc->sc_dying)
823 return;
824
825 if (!(ifp->if_flags & IFF_RUNNING))
826 return;
827
828 if (status != USBD_NORMAL_COMPLETION) {
829 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
830 return;
831 }
832 sc->sc_intr_errs++;
833 if (usbd_ratecheck(&sc->sc_rx_notice)) {
834 printf("%s: %u usb errors on intr: %s\n",
835 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
836 usbd_errstr(status));
837 sc->sc_intr_errs = 0;
838 }
839 if (status == USBD_STALLED)
840 usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
841 return;
842 }
843
844 stat = sc->sc_ibuf;
845
846 if (stat == 0)
847 return;
848
849 DPRINTFN(10,("%s: %s: stat=0x%02x\n", USBDEVNAME(sc->sc_dev),
850 __FUNCTION__, stat));
851
852 }
853
854 Static int
855 upl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
856 {
857 struct upl_softc *sc = ifp->if_softc;
858 struct ifaddr *ifa = (struct ifaddr *)data;
859 struct ifreq *ifr = (struct ifreq *)data;
860 int s, error = 0;
861
862 if (sc->sc_dying)
863 return (EIO);
864
865 DPRINTFN(5,("%s: %s: cmd=0x%08lx\n",
866 USBDEVNAME(sc->sc_dev), __FUNCTION__, command));
867
868 s = splimp();
869
870 switch(command) {
871 case SIOCSIFADDR:
872 ifp->if_flags |= IFF_UP;
873 upl_init(sc);
874
875 switch (ifa->ifa_addr->sa_family) {
876 #ifdef INET
877 case AF_INET:
878 break;
879 #endif /* INET */
880 #ifdef NS
881 case AF_NS:
882 {
883 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
884
885 if (ns_nullhost(*ina))
886 ina->x_host = *(union ns_host *)
887 LLADDR(ifp->if_sadl);
888 else
889 memcpy(LLADDR(ifp->if_sadl),
890 ina->x_host.c_host,
891 ifp->if_addrlen);
892 break;
893 }
894 #endif /* NS */
895 }
896 break;
897
898 case SIOCSIFMTU:
899 if (ifr->ifr_mtu > UPL_BUFSZ)
900 error = EINVAL;
901 else
902 ifp->if_mtu = ifr->ifr_mtu;
903 break;
904
905 case SIOCSIFFLAGS:
906 if (ifp->if_flags & IFF_UP) {
907 if (!(ifp->if_flags & IFF_RUNNING))
908 upl_init(sc);
909 } else {
910 if (ifp->if_flags & IFF_RUNNING)
911 upl_stop(sc);
912 }
913 error = 0;
914 break;
915 default:
916 error = EINVAL;
917 break;
918 }
919
920 splx(s);
921
922 return (error);
923 }
924
925 Static void
926 upl_watchdog(struct ifnet *ifp)
927 {
928 struct upl_softc *sc = ifp->if_softc;
929
930 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
931
932 if (sc->sc_dying)
933 return;
934
935 ifp->if_oerrors++;
936 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
937
938 upl_stop(sc);
939 upl_init(sc);
940
941 if (ifp->if_snd.ifq_head != NULL)
942 upl_start(ifp);
943 }
944
945 /*
946 * Stop the adapter and free any mbufs allocated to the
947 * RX and TX lists.
948 */
949 Static void
950 upl_stop(struct upl_softc *sc)
951 {
952 usbd_status err;
953 struct ifnet *ifp;
954 int i;
955
956 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__FUNCTION__));
957
958 ifp = &sc->sc_if;
959 ifp->if_timer = 0;
960
961 /* Stop transfers. */
962 if (sc->sc_ep[UPL_ENDPT_RX] != NULL) {
963 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]);
964 if (err) {
965 printf("%s: abort rx pipe failed: %s\n",
966 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
967 }
968 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]);
969 if (err) {
970 printf("%s: close rx pipe failed: %s\n",
971 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
972 }
973 sc->sc_ep[UPL_ENDPT_RX] = NULL;
974 }
975
976 if (sc->sc_ep[UPL_ENDPT_TX] != NULL) {
977 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]);
978 if (err) {
979 printf("%s: abort tx pipe failed: %s\n",
980 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
981 }
982 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]);
983 if (err) {
984 printf("%s: close tx pipe failed: %s\n",
985 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
986 }
987 sc->sc_ep[UPL_ENDPT_TX] = NULL;
988 }
989
990 if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) {
991 err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
992 if (err) {
993 printf("%s: abort intr pipe failed: %s\n",
994 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
995 }
996 err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
997 if (err) {
998 printf("%s: close intr pipe failed: %s\n",
999 USBDEVNAME(sc->sc_dev), usbd_errstr(err));
1000 }
1001 sc->sc_ep[UPL_ENDPT_INTR] = NULL;
1002 }
1003
1004 /* Free RX resources. */
1005 for (i = 0; i < UPL_RX_LIST_CNT; i++) {
1006 if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) {
1007 m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf);
1008 sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL;
1009 }
1010 if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) {
1011 usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer);
1012 sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL;
1013 }
1014 }
1015
1016 /* Free TX resources. */
1017 for (i = 0; i < UPL_TX_LIST_CNT; i++) {
1018 if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) {
1019 m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf);
1020 sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL;
1021 }
1022 if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) {
1023 usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer);
1024 sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL;
1025 }
1026 }
1027
1028 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1029 }
1030
1031 Static int
1032 upl_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
1033 struct rtentry *rt0)
1034 {
1035 int s;
1036
1037 DPRINTFN(10,("%s: %s: enter\n",
1038 USBDEVNAME(((struct upl_softc *)ifp->if_softc)->sc_dev),
1039 __FUNCTION__));
1040
1041 s = splimp();
1042 /*
1043 * Queue message on interface, and start output if interface
1044 * not yet active.
1045 */
1046 if (IF_QFULL(&ifp->if_snd)) {
1047 IF_DROP(&ifp->if_snd);
1048 splx(s);
1049 return (ENOBUFS);
1050 }
1051 ifp->if_obytes += m->m_pkthdr.len;
1052 IF_ENQUEUE(&ifp->if_snd, m);
1053 if ((ifp->if_flags & IFF_OACTIVE) == 0)
1054 (*ifp->if_start)(ifp);
1055 splx(s);
1056
1057 return (0);
1058 }
1059
1060 Static void
1061 upl_input(struct ifnet *ifp, struct mbuf *m)
1062 {
1063 struct ifqueue *inq;
1064 int s;
1065
1066 /* XXX Assume all traffic is IP */
1067
1068 schednetisr(NETISR_IP);
1069 inq = &ipintrq;
1070
1071 s = splimp();
1072 if (IF_QFULL(inq)) {
1073 IF_DROP(inq);
1074 splx(s);
1075 #if 0
1076 if (sc->sc_flags & SC_DEBUG)
1077 printf("%s: input queue full\n", ifp->if_xname);
1078 #endif
1079 ifp->if_iqdrops++;
1080 return;
1081 }
1082 IF_ENQUEUE(inq, m);
1083 splx(s);
1084 ifp->if_ipackets++;
1085 ifp->if_ibytes += m->m_len;
1086 ifp->if_lastchange = time;
1087 }
1088