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