if_cue.c revision 1.18 1 /* $NetBSD: if_cue.c,v 1.18 2000/03/29 18:24:52 augustss Exp $ */
2 /*
3 * Copyright (c) 1997, 1998, 1999, 2000
4 * Bill Paul <wpaul (at) ee.columbia.edu>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Bill Paul.
17 * 4. Neither the name of the author nor the names of any co-contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $
34 */
35
36 /*
37 * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate
38 * adapters and others.
39 *
40 * Written by Bill Paul <wpaul (at) ee.columbia.edu>
41 * Electrical Engineering Department
42 * Columbia University, New York City
43 */
44
45 /*
46 * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The
47 * RX filter uses a 512-bit multicast hash table, single perfect entry
48 * for the station address, and promiscuous mode. Unlike the ADMtek
49 * and KLSI chips, the CATC ASIC supports read and write combining
50 * mode where multiple packets can be transfered using a single bulk
51 * transaction, which helps performance a great deal.
52 */
53
54 /*
55 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
56 */
57
58 /*
59 * TODO:
60 * proper cleanup on errors
61 */
62 #if defined(__NetBSD__)
63 #include "opt_inet.h"
64 #include "opt_ns.h"
65 #include "bpfilter.h"
66 #include "rnd.h"
67 #elif defined(__OpenBSD__)
68 #include "bpfilter.h"
69 #endif /* defined(__OpenBSD__) */
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #if !defined(__OpenBSD__)
74 #include <sys/callout.h>
75 #endif
76 #include <sys/sockio.h>
77 #include <sys/mbuf.h>
78 #include <sys/malloc.h>
79 #include <sys/kernel.h>
80 #include <sys/socket.h>
81
82 #if defined(__FreeBSD__)
83
84 #include <net/ethernet.h>
85 #include <machine/clock.h> /* for DELAY */
86 #include <sys/bus.h>
87
88 #elif defined(__NetBSD__) || defined(__OpenBSD__)
89
90 #include <sys/device.h>
91 #if NRND > 0
92 #include <sys/rnd.h>
93 #endif
94
95 #endif
96
97 #include <net/if.h>
98 #if defined(__NetBSD__) || defined(__FreeBSD__)
99 #include <net/if_arp.h>
100 #endif
101 #include <net/if_dl.h>
102
103 #if defined(__NetBSD__) || defined(__OpenBSD__)
104 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
105 #else
106 #define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m))
107 #endif
108
109 #if defined(__FreeBSD__) || NBPFILTER > 0
110 #include <net/bpf.h>
111 #endif
112
113 #if defined(__NetBSD__)
114 #include <net/if_ether.h>
115 #ifdef INET
116 #include <netinet/in.h>
117 #include <netinet/if_inarp.h>
118 #endif
119 #endif /* defined(__NetBSD__) */
120
121 #if defined(__OpenBSD__)
122 #ifdef INET
123 #include <netinet/in.h>
124 #include <netinet/in_systm.h>
125 #include <netinet/in_var.h>
126 #include <netinet/ip.h>
127 #include <netinet/if_ether.h>
128 #endif
129 #endif /* defined(__OpenBSD__) */
130
131 #if defined(__NetBSD__) || defined(__OpenBSD__)
132 #ifdef NS
133 #include <netns/ns.h>
134 #include <netns/ns_if.h>
135 #endif
136 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
137
138 #include <dev/usb/usb.h>
139 #include <dev/usb/usbdi.h>
140 #include <dev/usb/usbdi_util.h>
141 #include <dev/usb/usbdevs.h>
142
143 #ifdef __FreeBSD__
144 #include <dev/usb/usb_ethersubr.h>
145 #endif
146
147 #include <dev/usb/if_cuereg.h>
148
149 #ifdef CUE_DEBUG
150 #define DPRINTF(x) if (cuedebug) logprintf x
151 #define DPRINTFN(n,x) if (cuedebug >= (n)) logprintf x
152 int cuedebug = 0;
153 #else
154 #define DPRINTF(x)
155 #define DPRINTFN(n,x)
156 #endif
157
158 /*
159 * Various supported device vendors/products.
160 */
161 Static struct cue_type cue_devs[] = {
162 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE },
163 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 },
164 /* Belkin F5U111 adapter covered by NETMATE entry */
165 { 0, 0 }
166 };
167
168 USB_DECLARE_DRIVER(cue);
169
170 Static int cue_open_pipes __P((struct cue_softc *));
171 Static int cue_tx_list_init __P((struct cue_softc *));
172 Static int cue_rx_list_init __P((struct cue_softc *));
173 Static int cue_newbuf __P((struct cue_softc *, struct cue_chain *,
174 struct mbuf *));
175 Static int cue_send __P((struct cue_softc *, struct mbuf *, int));
176 Static void cue_rxeof __P((usbd_xfer_handle,
177 usbd_private_handle, usbd_status));
178 Static void cue_txeof __P((usbd_xfer_handle,
179 usbd_private_handle, usbd_status));
180 Static void cue_tick __P((void *));
181 Static void cue_start __P((struct ifnet *));
182 Static int cue_ioctl __P((struct ifnet *, u_long, caddr_t));
183 Static void cue_init __P((void *));
184 Static void cue_stop __P((struct cue_softc *));
185 Static void cue_watchdog __P((struct ifnet *));
186
187 Static void cue_setmulti __P((struct cue_softc *));
188 Static u_int32_t cue_crc __P((caddr_t));
189 Static void cue_reset __P((struct cue_softc *));
190
191 Static int cue_csr_read_1 __P((struct cue_softc *, int));
192 Static int cue_csr_write_1 __P((struct cue_softc *, int, int));
193 Static int cue_csr_read_2 __P((struct cue_softc *, int));
194 #ifdef notdef
195 Static int cue_csr_write_2 __P((struct cue_softc *, int, int));
196 #endif
197 Static int cue_mem __P((struct cue_softc *, int,
198 int, void *, int));
199 Static int cue_getmac __P((struct cue_softc *, void *));
200
201 #ifdef __FreeBSD__
202 #ifndef lint
203 static const char rcsid[] =
204 "$FreeBSD: src/sys/dev/usb/if_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $";
205 #endif
206
207 Static void cue_rxstart __P((struct ifnet *));
208 Static void cue_shutdown __P((device_t));
209
210 Static struct usb_qdat cue_qdat;
211
212 Static device_method_t cue_methods[] = {
213 /* Device interface */
214 DEVMETHOD(device_probe, cue_match),
215 DEVMETHOD(device_attach, cue_attach),
216 DEVMETHOD(device_detach, cue_detach),
217 DEVMETHOD(device_shutdown, cue_shutdown),
218
219 { 0, 0 }
220 };
221
222 Static driver_t cue_driver = {
223 "cue",
224 cue_methods,
225 sizeof(struct cue_softc)
226 };
227
228 Static devclass_t cue_devclass;
229
230 DRIVER_MODULE(if_cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0);
231
232 #endif /* defined(__FreeBSD__) */
233
234 #define CUE_DO_REQUEST(dev, req, data) \
235 usbd_do_request_flags(dev, req, data, USBD_NO_TSLEEP, NULL)
236
237 #define CUE_SETBIT(sc, reg, x) \
238 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
239
240 #define CUE_CLRBIT(sc, reg, x) \
241 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
242
243 Static int
244 cue_csr_read_1(sc, reg)
245 struct cue_softc *sc;
246 int reg;
247 {
248 usb_device_request_t req;
249 usbd_status err;
250 u_int8_t val = 0;
251 int s;
252
253 if (sc->cue_dying)
254 return (0);
255
256 req.bmRequestType = UT_READ_VENDOR_DEVICE;
257 req.bRequest = CUE_CMD_READREG;
258 USETW(req.wValue, 0);
259 USETW(req.wIndex, reg);
260 USETW(req.wLength, 1);
261
262 s = splusb();
263 err = CUE_DO_REQUEST(sc->cue_udev, &req, &val);
264 splx(s);
265
266 if (err) {
267 DPRINTF(("%s: cue_csr_read_1: reg=0x%x err=%s\n",
268 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
269 return (0);
270 }
271
272 DPRINTFN(10,("%s: cue_csr_read_1 reg=0x%x val=0x%x\n",
273 USBDEVNAME(sc->cue_dev), reg, val));
274
275 return (val);
276 }
277
278 Static int
279 cue_csr_read_2(sc, reg)
280 struct cue_softc *sc;
281 int reg;
282 {
283 usb_device_request_t req;
284 usbd_status err;
285 uWord val;
286 int s;
287
288 if (sc->cue_dying)
289 return (0);
290
291 req.bmRequestType = UT_READ_VENDOR_DEVICE;
292 req.bRequest = CUE_CMD_READREG;
293 USETW(req.wValue, 0);
294 USETW(req.wIndex, reg);
295 USETW(req.wLength, 2);
296
297 s = splusb();
298 err = CUE_DO_REQUEST(sc->cue_udev, &req, &val);
299 splx(s);
300
301 DPRINTFN(10,("%s: cue_csr_read_2 reg=0x%x val=0x%x\n",
302 USBDEVNAME(sc->cue_dev), reg, UGETW(val)));
303
304 if (err) {
305 DPRINTF(("%s: cue_csr_read_2: reg=0x%x err=%s\n",
306 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
307 return (0);
308 }
309
310 return (UGETW(val));
311 }
312
313 Static int
314 cue_csr_write_1(sc, reg, val)
315 struct cue_softc *sc;
316 int reg, val;
317 {
318 usb_device_request_t req;
319 usbd_status err;
320 int s;
321
322 if (sc->cue_dying)
323 return (0);
324
325 DPRINTFN(10,("%s: cue_csr_write_1 reg=0x%x val=0x%x\n",
326 USBDEVNAME(sc->cue_dev), reg, val));
327
328 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
329 req.bRequest = CUE_CMD_WRITEREG;
330 USETW(req.wValue, val);
331 USETW(req.wIndex, reg);
332 USETW(req.wLength, 0);
333
334 s = splusb();
335 err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL);
336 splx(s);
337
338 if (err) {
339 DPRINTF(("%s: cue_csr_write_1: reg=0x%x err=%s\n",
340 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
341 return (-1);
342 }
343
344 DPRINTFN(20,("%s: cue_csr_write_1, after reg=0x%x val=0x%x\n",
345 USBDEVNAME(sc->cue_dev), reg, cue_csr_read_1(sc, reg)));
346
347 return (0);
348 }
349
350 #ifdef notdef
351 Static int
352 cue_csr_write_2(sc, reg, val)
353 struct cue_softc *sc;
354 int reg, aval;
355 {
356 usb_device_request_t req;
357 usbd_status err;
358 uWord val;
359 int s;
360
361 if (sc->cue_dying)
362 return (0);
363
364 DPRINTFN(10,("%s: cue_csr_write_2 reg=0x%x val=0x%x\n",
365 USBDEVNAME(sc->cue_dev), reg, aval));
366
367 USETW(val, aval);
368 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
369 req.bRequest = CUE_CMD_WRITEREG;
370 USETW(req.wValue, val);
371 USETW(req.wIndex, reg);
372 USETW(req.wLength, 0);
373
374 s = splusb();
375 err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL);
376 splx(s);
377
378 if (err) {
379 DPRINTF(("%s: cue_csr_write_2: reg=0x%x err=%s\n",
380 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
381 return (-1);
382 }
383
384 return (0);
385 }
386 #endif
387
388 Static int
389 cue_mem(sc, cmd, addr, buf, len)
390 struct cue_softc *sc;
391 int cmd;
392 int addr;
393 void *buf;
394 int len;
395 {
396 usb_device_request_t req;
397 usbd_status err;
398 int s;
399
400 DPRINTFN(10,("%s: cue_mem cmd=0x%x addr=0x%x len=%d\n",
401 USBDEVNAME(sc->cue_dev), cmd, addr, len));
402
403 if (cmd == CUE_CMD_READSRAM)
404 req.bmRequestType = UT_READ_VENDOR_DEVICE;
405 else
406 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
407 req.bRequest = cmd;
408 USETW(req.wValue, 0);
409 USETW(req.wIndex, addr);
410 USETW(req.wLength, len);
411
412 s = splusb();
413 err = CUE_DO_REQUEST(sc->cue_udev, &req, buf);
414 splx(s);
415
416 if (err) {
417 DPRINTF(("%s: cue_csr_mem: addr=0x%x err=%s\n",
418 USBDEVNAME(sc->cue_dev), addr, usbd_errstr(err)));
419 return (-1);
420 }
421
422 return (0);
423 }
424
425 Static int
426 cue_getmac(sc, buf)
427 struct cue_softc *sc;
428 void *buf;
429 {
430 usb_device_request_t req;
431 usbd_status err;
432 int s;
433
434 DPRINTFN(10,("%s: cue_getmac\n", USBDEVNAME(sc->cue_dev)));
435
436 req.bmRequestType = UT_READ_VENDOR_DEVICE;
437 req.bRequest = CUE_CMD_GET_MACADDR;
438 USETW(req.wValue, 0);
439 USETW(req.wIndex, 0);
440 USETW(req.wLength, ETHER_ADDR_LEN);
441
442 s = splusb();
443 err = CUE_DO_REQUEST(sc->cue_udev, &req, buf);
444 splx(s);
445
446 if (err) {
447 printf("%s: read MAC address failed\n", USBDEVNAME(sc->cue_dev));
448 return (-1);
449 }
450
451 return (0);
452 }
453
454 #define CUE_POLY 0xEDB88320
455 #define CUE_BITS 9
456
457 Static u_int32_t
458 cue_crc(addr)
459 caddr_t addr;
460 {
461 u_int32_t idx, bit, data, crc;
462
463 /* Compute CRC for the address value. */
464 crc = 0xFFFFFFFF; /* initial value */
465
466 for (idx = 0; idx < 6; idx++) {
467 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
468 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0);
469 }
470
471 return (crc & ((1 << CUE_BITS) - 1));
472 }
473
474 Static void
475 cue_setmulti(sc)
476 struct cue_softc *sc;
477 {
478 struct ifnet *ifp;
479 #if defined(__FreeBSD__)
480 struct ifmultiaddr *ifma;
481 #elif defined(__NetBSD__) || defined(__OpenBSD__)
482 struct ether_multi *enm;
483 struct ether_multistep step;
484 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
485 u_int32_t h, i;
486
487 ifp = GET_IFP(sc);
488
489 DPRINTFN(2,("%s: cue_setmulti if_flags=0x%x\n",
490 USBDEVNAME(sc->cue_dev), ifp->if_flags));
491
492 if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
493 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
494 sc->cue_mctab[i] = 0xFF;
495 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
496 &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
497 return;
498 }
499
500 /* first, zot all the existing hash bits */
501 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
502 sc->cue_mctab[i] = 0;
503
504 /* now program new ones */
505 #if defined(__FreeBSD__)
506 for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
507 ifma = ifma->ifma_link.le_next) {
508 if (ifma->ifma_addr->sa_family != AF_LINK)
509 continue;
510 h = cue_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
511 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
512 }
513 #elif defined(__NetBSD__) || defined(__OpenBSD__)
514 #if defined(__NetBSD__)
515 ETHER_FIRST_MULTI(step, &sc->cue_ec, enm);
516 #else
517 ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
518 #endif
519 while (enm != NULL) {
520 #if 0
521 if (memcmp(enm->enm_addrlo,
522 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
523 ifp->if_flags |= IFF_ALLMULTI;
524 /* XXX what now? */
525 return;
526 }
527 #endif
528 h = cue_crc(enm->enm_addrlo);
529 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
530 ETHER_NEXT_MULTI(step, enm);
531 }
532 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
533
534 /*
535 * Also include the broadcast address in the filter
536 * so we can receive broadcast frames.
537 */
538 if (ifp->if_flags & IFF_BROADCAST) {
539 h = cue_crc(etherbroadcastaddr);
540 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
541 }
542
543 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
544 &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
545 }
546
547 Static void
548 cue_reset(sc)
549 struct cue_softc *sc;
550 {
551 usb_device_request_t req;
552 usbd_status err;
553 int s;
554
555 DPRINTFN(2,("%s: cue_reset\n", USBDEVNAME(sc->cue_dev)));
556
557 if (sc->cue_dying)
558 return;
559
560 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
561 req.bRequest = CUE_CMD_RESET;
562 USETW(req.wValue, 0);
563 USETW(req.wIndex, 0);
564 USETW(req.wLength, 0);
565
566 s = splusb();
567 err = CUE_DO_REQUEST(sc->cue_udev, &req, NULL);
568 splx(s);
569
570 if (err)
571 printf("%s: reset failed\n", USBDEVNAME(sc->cue_dev));
572
573 /* Wait a little while for the chip to get its brains in order. */
574 delay(1000); /* XXX */
575 }
576
577 /*
578 * Probe for a CATC chip.
579 */
580 USB_MATCH(cue)
581 {
582 USB_MATCH_START(cue, uaa);
583 struct cue_type *t;
584
585 if (uaa->iface != NULL)
586 return (UMATCH_NONE);
587
588 for (t = cue_devs; t->cue_vid != 0; t++)
589 if (uaa->vendor == t->cue_vid && uaa->product == t->cue_did)
590 return (UMATCH_VENDOR_PRODUCT);
591
592 return (UMATCH_NONE);
593 }
594
595 /*
596 * Attach the interface. Allocate softc structures, do ifmedia
597 * setup and ethernet/BPF attach.
598 */
599 USB_ATTACH(cue)
600 {
601 USB_ATTACH_START(cue, sc, uaa);
602 char devinfo[1024];
603 int s;
604 u_char eaddr[ETHER_ADDR_LEN];
605 usbd_device_handle dev = uaa->device;
606 usbd_interface_handle iface;
607 usbd_status err;
608 struct ifnet *ifp;
609 usb_interface_descriptor_t *id;
610 usb_endpoint_descriptor_t *ed;
611 int i;
612
613 #ifdef __FreeBSD__
614 bzero(sc, sizeof(struct cue_softc));
615 #endif
616
617 DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc, dev));
618
619 usbd_devinfo(dev, 0, devinfo);
620 USB_ATTACH_SETUP;
621 printf("%s: %s\n", USBDEVNAME(sc->cue_dev), devinfo);
622
623 err = usbd_set_config_no(dev, CUE_CONFIG_NO, 0);
624 if (err) {
625 printf("%s: setting config no failed\n",
626 USBDEVNAME(sc->cue_dev));
627 USB_ATTACH_ERROR_RETURN;
628 }
629
630 sc->cue_udev = dev;
631 sc->cue_product = uaa->product;
632 sc->cue_vendor = uaa->vendor;
633
634 err = usbd_device2interface_handle(dev, CUE_IFACE_IDX, &iface);
635 if (err) {
636 printf("%s: getting interface handle failed\n",
637 USBDEVNAME(sc->cue_dev));
638 USB_ATTACH_ERROR_RETURN;
639 }
640
641 sc->cue_iface = iface;
642 id = usbd_get_interface_descriptor(iface);
643
644 /* Find endpoints. */
645 for (i = 0; i < id->bNumEndpoints; i++) {
646 ed = usbd_interface2endpoint_descriptor(iface, i);
647 if (ed == NULL) {
648 printf("%s: couldn't get ep %d\n",
649 USBDEVNAME(sc->cue_dev), i);
650 USB_ATTACH_ERROR_RETURN;
651 }
652 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
653 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
654 sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress;
655 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
656 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
657 sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress;
658 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
659 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
660 sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress;
661 }
662 }
663
664 #if 0
665 /* Reset the adapter. */
666 cue_reset(sc);
667 #endif
668 /*
669 * Get station address.
670 */
671 cue_getmac(sc, &eaddr);
672
673 s = splimp();
674
675 /*
676 * A CATC chip was detected. Inform the world.
677 */
678 #if defined(__FreeBSD__)
679 printf("%s: Ethernet address: %6D\n", USBDEVNAME(sc->cue_dev), eaddr, ":");
680
681 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
682
683 ifp = &sc->arpcom.ac_if;
684 ifp->if_softc = sc;
685 ifp->if_unit = USBDEVNAME(sc->cue_dev);
686 ifp->if_name = "cue";
687 ifp->if_mtu = ETHERMTU;
688 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
689 ifp->if_ioctl = cue_ioctl;
690 ifp->if_output = ether_output;
691 ifp->if_start = cue_start;
692 ifp->if_watchdog = cue_watchdog;
693 ifp->if_init = cue_init;
694 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
695
696 cue_qdat.ifp = ifp;
697 cue_qdat.if_rxstart = cue_rxstart;
698
699 /*
700 * Call MI attach routines.
701 */
702 if_attach(ifp);
703 ether_ifattach(ifp);
704 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
705 usb_register_netisr();
706
707 #elif defined(__NetBSD__) || defined(__OpenBSD__)
708
709 printf("%s: Ethernet address %s\n", USBDEVNAME(sc->cue_dev),
710 ether_sprintf(eaddr));
711
712 /* Initialize interface info.*/
713 ifp = GET_IFP(sc);
714 ifp->if_softc = sc;
715 ifp->if_mtu = ETHERMTU;
716 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
717 ifp->if_ioctl = cue_ioctl;
718 ifp->if_start = cue_start;
719 ifp->if_watchdog = cue_watchdog;
720 strncpy(ifp->if_xname, USBDEVNAME(sc->cue_dev), IFNAMSIZ);
721
722 /* Attach the interface. */
723 if_attach(ifp);
724 Ether_ifattach(ifp, eaddr);
725
726 #if NBPFILTER > 0
727 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB,
728 sizeof(struct ether_header));
729 #endif
730 #if NRND > 0
731 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->cue_dev),
732 RND_TYPE_NET, 0);
733 #endif
734
735 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
736
737 usb_callout_init(sc->cue_stat_ch);
738
739 sc->cue_attached = 1;
740 splx(s);
741
742 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cue_udev,
743 USBDEV(sc->cue_dev));
744
745 USB_ATTACH_SUCCESS_RETURN;
746 }
747
748 USB_DETACH(cue)
749 {
750 USB_DETACH_START(cue, sc);
751 struct ifnet *ifp = GET_IFP(sc);
752 int s;
753
754 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__));
755
756 s = splusb();
757
758 usb_uncallout(sc->cue_stat_ch, cue_tick, sc);
759
760 if (!sc->cue_attached) {
761 /* Detached before attached finished, so just bail out. */
762 splx(s);
763 return (0);
764 }
765
766 if (ifp->if_flags & IFF_RUNNING)
767 cue_stop(sc);
768
769 #if defined(__NetBSD__)
770 #if NRND > 0
771 rnd_detach_source(&sc->rnd_source);
772 #endif
773 #if NBPFILTER > 0
774 bpfdetach(ifp);
775 #endif
776 ether_ifdetach(ifp);
777 #endif /* __NetBSD__ */
778
779 if_detach(ifp);
780
781 #ifdef DIAGNOSTIC
782 if (sc->cue_ep[CUE_ENDPT_TX] != NULL ||
783 sc->cue_ep[CUE_ENDPT_RX] != NULL ||
784 sc->cue_ep[CUE_ENDPT_INTR] != NULL)
785 printf("%s: detach has active endpoints\n",
786 USBDEVNAME(sc->cue_dev));
787 #endif
788
789 sc->cue_attached = 0;
790 splx(s);
791
792 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cue_udev,
793 USBDEV(sc->cue_dev));
794
795 return (0);
796 }
797
798 #if defined(__NetBSD__) || defined(__OpenBSD__)
799 int
800 cue_activate(self, act)
801 device_ptr_t self;
802 enum devact act;
803 {
804 struct cue_softc *sc = (struct cue_softc *)self;
805
806 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__));
807
808 switch (act) {
809 case DVACT_ACTIVATE:
810 return (EOPNOTSUPP);
811 break;
812
813 case DVACT_DEACTIVATE:
814 /* Deactivate the interface. */
815 if_deactivate(&sc->cue_ec.ec_if);
816 sc->cue_dying = 1;
817 break;
818 }
819 return (0);
820 }
821 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
822
823 /*
824 * Initialize an RX descriptor and attach an MBUF cluster.
825 */
826 Static int
827 cue_newbuf(sc, c, m)
828 struct cue_softc *sc;
829 struct cue_chain *c;
830 struct mbuf *m;
831 {
832 struct mbuf *m_new = NULL;
833
834 if (m == NULL) {
835 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
836 if (m_new == NULL) {
837 printf("%s: no memory for rx list "
838 "-- packet dropped!\n", USBDEVNAME(sc->cue_dev));
839 return (ENOBUFS);
840 }
841
842 MCLGET(m_new, M_DONTWAIT);
843 if (!(m_new->m_flags & M_EXT)) {
844 printf("%s: no memory for rx list "
845 "-- packet dropped!\n", USBDEVNAME(sc->cue_dev));
846 m_freem(m_new);
847 return (ENOBUFS);
848 }
849 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
850 } else {
851 m_new = m;
852 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
853 m_new->m_data = m_new->m_ext.ext_buf;
854 }
855
856 m_adj(m_new, ETHER_ALIGN);
857 c->cue_mbuf = m_new;
858
859 return (0);
860 }
861
862 Static int
863 cue_rx_list_init(sc)
864 struct cue_softc *sc;
865 {
866 struct cue_cdata *cd;
867 struct cue_chain *c;
868 int i;
869
870 cd = &sc->cue_cdata;
871 for (i = 0; i < CUE_RX_LIST_CNT; i++) {
872 c = &cd->cue_rx_chain[i];
873 c->cue_sc = sc;
874 c->cue_idx = i;
875 if (cue_newbuf(sc, c, NULL) == ENOBUFS)
876 return (ENOBUFS);
877 if (c->cue_xfer == NULL) {
878 c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
879 if (c->cue_xfer == NULL)
880 return (ENOBUFS);
881 c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ);
882 if (c->cue_buf == NULL) {
883 usbd_free_xfer(c->cue_xfer);
884 return (ENOBUFS);
885 }
886 }
887 }
888
889 return (0);
890 }
891
892 Static int
893 cue_tx_list_init(sc)
894 struct cue_softc *sc;
895 {
896 struct cue_cdata *cd;
897 struct cue_chain *c;
898 int i;
899
900 cd = &sc->cue_cdata;
901 for (i = 0; i < CUE_TX_LIST_CNT; i++) {
902 c = &cd->cue_tx_chain[i];
903 c->cue_sc = sc;
904 c->cue_idx = i;
905 c->cue_mbuf = NULL;
906 if (c->cue_xfer == NULL) {
907 c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
908 if (c->cue_xfer == NULL)
909 return (ENOBUFS);
910 c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ);
911 if (c->cue_buf == NULL) {
912 usbd_free_xfer(c->cue_xfer);
913 return (ENOBUFS);
914 }
915 }
916 }
917
918 return (0);
919 }
920
921 #ifdef __FreeBSD__
922 Static void
923 cue_rxstart(ifp)
924 struct ifnet *ifp;
925 {
926 struct cue_softc *sc;
927 struct cue_chain *c;
928
929 sc = ifp->if_softc;
930 c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod];
931
932 if (cue_newbuf(sc, c, NULL) == ENOBUFS) {
933 ifp->if_ierrors++;
934 return;
935 }
936
937 /* Setup new transfer. */
938 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
939 c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
940 USBD_NO_TIMEOUT, cue_rxeof);
941 usbd_transfer(c->cue_xfer);
942 }
943 #endif
944
945 /*
946 * A frame has been uploaded: pass the resulting mbuf chain up to
947 * the higher level protocols.
948 */
949 Static void
950 cue_rxeof(xfer, priv, status)
951 usbd_xfer_handle xfer;
952 usbd_private_handle priv;
953 usbd_status status;
954 {
955 struct cue_chain *c = priv;
956 struct cue_softc *sc = c->cue_sc;
957 struct ifnet *ifp = GET_IFP(sc);
958 struct mbuf *m;
959 int total_len = 0;
960 u_int16_t len;
961 #if defined(__NetBSD__) || defined(__OpenBSD__)
962 int s;
963 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
964
965 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev),
966 __FUNCTION__, status));
967
968 if (sc->cue_dying)
969 return;
970
971 if (!(ifp->if_flags & IFF_RUNNING))
972 return;
973
974 if (status != USBD_NORMAL_COMPLETION) {
975 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
976 return;
977 sc->cue_rx_errs++;
978 if (usbd_ratecheck(&sc->cue_rx_notice)) {
979 printf("%s: %u usb errors on rx: %s\n",
980 USBDEVNAME(sc->cue_dev), sc->cue_rx_errs,
981 usbd_errstr(status));
982 sc->cue_rx_errs = 0;
983 }
984 if (status == USBD_STALLED)
985 usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]);
986 goto done;
987 }
988
989 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
990
991 memcpy(mtod(c->cue_mbuf, char *), c->cue_buf, total_len);
992
993 m = c->cue_mbuf;
994 len = UGETW(mtod(m, u_int8_t *));
995
996 /* No errors; receive the packet. */
997 total_len = len;
998
999 if (len < sizeof(struct ether_header)) {
1000 ifp->if_ierrors++;
1001 goto done;
1002 }
1003
1004 ifp->if_ipackets++;
1005 m_adj(m, sizeof(u_int16_t));
1006 m->m_pkthdr.len = m->m_len = total_len;
1007
1008 #if defined(__FreeBSD__)
1009 m->m_pkthdr.rcvif = (struct ifnet *)&cue_qdat;
1010 /* Put the packet on the special USB input queue. */
1011 usb_ether_input(m);
1012
1013 return;
1014 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1015 m->m_pkthdr.rcvif = ifp;
1016
1017 s = splimp();
1018
1019 /* XXX ugly */
1020 if (cue_newbuf(sc, c, NULL) == ENOBUFS) {
1021 ifp->if_ierrors++;
1022 goto done1;
1023 }
1024
1025 #if NBPFILTER > 0
1026 /*
1027 * Handle BPF listeners. Let the BPF user see the packet, but
1028 * don't pass it up to the ether_input() layer unless it's
1029 * a broadcast packet, multicast packet, matches our ethernet
1030 * address or the interface is in promiscuous mode.
1031 */
1032 if (ifp->if_bpf) {
1033 struct ether_header *eh = mtod(m, struct ether_header *);
1034 BPF_MTAP(ifp, m);
1035 #if defined(__NetBSD__)
1036 if ((ifp->if_flags & IFF_PROMISC) &&
1037 memcmp(eh->ether_dhost, LLADDR(ifp->if_sadl),
1038 ETHER_ADDR_LEN) &&
1039 !(eh->ether_dhost[0] & 1)) {
1040 m_freem(m);
1041 goto done1;
1042 }
1043 #endif
1044 }
1045 #endif
1046
1047 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->cue_dev),
1048 __FUNCTION__, m->m_len));
1049 IF_INPUT(ifp, m);
1050 done1:
1051 splx(s);
1052 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1053
1054 done:
1055 /* Setup new transfer. */
1056 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
1057 c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
1058 USBD_NO_TIMEOUT, cue_rxeof);
1059 usbd_transfer(c->cue_xfer);
1060
1061 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->cue_dev),
1062 __FUNCTION__));
1063 }
1064
1065 /*
1066 * A frame was downloaded to the chip. It's safe for us to clean up
1067 * the list buffers.
1068 */
1069 Static void
1070 cue_txeof(xfer, priv, status)
1071 usbd_xfer_handle xfer;
1072 usbd_private_handle priv;
1073 usbd_status status;
1074 {
1075 struct cue_chain *c = priv;
1076 struct cue_softc *sc = c->cue_sc;
1077 struct ifnet *ifp = GET_IFP(sc);
1078 int s;
1079
1080 if (sc->cue_dying)
1081 return;
1082
1083 s = splimp();
1084
1085 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev),
1086 __FUNCTION__, status));
1087
1088 ifp->if_timer = 0;
1089 ifp->if_flags &= ~IFF_OACTIVE;
1090
1091 if (status != USBD_NORMAL_COMPLETION) {
1092 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1093 splx(s);
1094 return;
1095 }
1096 ifp->if_oerrors++;
1097 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cue_dev),
1098 usbd_errstr(status));
1099 if (status == USBD_STALLED)
1100 usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);
1101 splx(s);
1102 return;
1103 }
1104
1105 ifp->if_opackets++;
1106
1107 #if defined(__FreeBSD__)
1108 c->cue_mbuf->m_pkthdr.rcvif = ifp;
1109 usb_tx_done(c->cue_mbuf);
1110 c->cue_mbuf = NULL;
1111 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1112 m_freem(c->cue_mbuf);
1113 c->cue_mbuf = NULL;
1114
1115 if (ifp->if_snd.ifq_head != NULL)
1116 cue_start(ifp);
1117 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1118
1119 splx(s);
1120 }
1121
1122 Static void
1123 cue_tick(xsc)
1124 void *xsc;
1125 {
1126 struct cue_softc *sc = xsc;
1127 struct ifnet *ifp;
1128 int s;
1129
1130 if (sc == NULL)
1131 return;
1132
1133 if (sc->cue_dying)
1134 return;
1135
1136 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__));
1137
1138 s = splimp();
1139
1140 ifp = GET_IFP(sc);
1141
1142 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
1143 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
1144 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
1145
1146 if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
1147 ifp->if_ierrors++;
1148
1149 usb_callout(sc->cue_stat_ch, hz, cue_tick, sc);
1150
1151 splx(s);
1152 }
1153
1154 Static int
1155 cue_send(sc, m, idx)
1156 struct cue_softc *sc;
1157 struct mbuf *m;
1158 int idx;
1159 {
1160 int total_len;
1161 struct cue_chain *c;
1162 usbd_status err;
1163
1164 c = &sc->cue_cdata.cue_tx_chain[idx];
1165
1166 /*
1167 * Copy the mbuf data into a contiguous buffer, leaving two
1168 * bytes at the beginning to hold the frame length.
1169 */
1170 m_copydata(m, 0, m->m_pkthdr.len, c->cue_buf + 2);
1171 c->cue_mbuf = m;
1172
1173 total_len = m->m_pkthdr.len + 2;
1174
1175 DPRINTFN(10,("%s: %s: total_len=%d\n",
1176 USBDEVNAME(sc->cue_dev), __FUNCTION__, total_len));
1177
1178 /* The first two bytes are the frame length */
1179 c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len;
1180 c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
1181
1182 /* XXX 10000 */
1183 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX],
1184 c, c->cue_buf, total_len, USBD_NO_COPY, 10000, cue_txeof);
1185
1186 /* Transmit */
1187 err = usbd_transfer(c->cue_xfer);
1188 if (err != USBD_IN_PROGRESS) {
1189 cue_stop(sc);
1190 return (EIO);
1191 }
1192
1193 sc->cue_cdata.cue_tx_cnt++;
1194
1195 return (0);
1196 }
1197
1198 Static void
1199 cue_start(ifp)
1200 struct ifnet *ifp;
1201 {
1202 struct cue_softc *sc = ifp->if_softc;
1203 struct mbuf *m_head = NULL;
1204
1205 if (sc->cue_dying)
1206 return;
1207
1208 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1209
1210 if (ifp->if_flags & IFF_OACTIVE)
1211 return;
1212
1213 IF_DEQUEUE(&ifp->if_snd, m_head);
1214 if (m_head == NULL)
1215 return;
1216
1217 if (cue_send(sc, m_head, 0)) {
1218 IF_PREPEND(&ifp->if_snd, m_head);
1219 ifp->if_flags |= IFF_OACTIVE;
1220 return;
1221 }
1222
1223 #if NBPFILTER > 0
1224 /*
1225 * If there's a BPF listener, bounce a copy of this frame
1226 * to him.
1227 */
1228 if (ifp->if_bpf)
1229 BPF_MTAP(ifp, m_head);
1230 #endif
1231
1232 ifp->if_flags |= IFF_OACTIVE;
1233
1234 /*
1235 * Set a timeout in case the chip goes out to lunch.
1236 */
1237 ifp->if_timer = 5;
1238 }
1239
1240 Static void
1241 cue_init(xsc)
1242 void *xsc;
1243 {
1244 struct cue_softc *sc = xsc;
1245 struct ifnet *ifp = GET_IFP(sc);
1246 int i, s, ctl;
1247 u_char *eaddr;
1248
1249 if (sc->cue_dying)
1250 return;
1251
1252 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1253
1254 if (ifp->if_flags & IFF_RUNNING)
1255 return;
1256
1257 s = splimp();
1258
1259 /*
1260 * Cancel pending I/O and free all RX/TX buffers.
1261 */
1262 #if 1
1263 cue_reset(sc);
1264 #endif
1265
1266 /* Set advanced operation modes. */
1267 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
1268 CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */
1269
1270 #if defined(__FreeBSD__) || defined(__OpenBSD__)
1271 eaddr = sc->arpcom.ac_enaddr;
1272 #elif defined(__NetBSD__)
1273 eaddr = LLADDR(ifp->if_sadl);
1274 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1275 /* Set MAC address */
1276 for (i = 0; i < ETHER_ADDR_LEN; i++)
1277 cue_csr_write_1(sc, CUE_PAR0 - i, eaddr[i]);
1278
1279 /* Enable RX logic. */
1280 ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON;
1281 if (ifp->if_flags & IFF_PROMISC)
1282 ctl |= CUE_ETHCTL_PROMISC;
1283 cue_csr_write_1(sc, CUE_ETHCTL, ctl);
1284
1285 /* Init TX ring. */
1286 if (cue_tx_list_init(sc) == ENOBUFS) {
1287 printf("%s: tx list init failed\n", USBDEVNAME(sc->cue_dev));
1288 splx(s);
1289 return;
1290 }
1291
1292 /* Init RX ring. */
1293 if (cue_rx_list_init(sc) == ENOBUFS) {
1294 printf("%s: rx list init failed\n", USBDEVNAME(sc->cue_dev));
1295 splx(s);
1296 return;
1297 }
1298
1299 /* Load the multicast filter. */
1300 cue_setmulti(sc);
1301
1302 /*
1303 * Set the number of RX and TX buffers that we want
1304 * to reserve inside the ASIC.
1305 */
1306 cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
1307 cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
1308
1309 /* Set advanced operation modes. */
1310 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
1311 CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */
1312
1313 /* Program the LED operation. */
1314 cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
1315
1316 if (sc->cue_ep[CUE_ENDPT_RX] == NULL) {
1317 if (cue_open_pipes(sc)) {
1318 splx(s);
1319 return;
1320 }
1321 }
1322
1323 ifp->if_flags |= IFF_RUNNING;
1324 ifp->if_flags &= ~IFF_OACTIVE;
1325
1326 splx(s);
1327
1328 usb_callout(sc->cue_stat_ch, hz, cue_tick, sc);
1329 }
1330
1331 Static int
1332 cue_open_pipes(sc)
1333 struct cue_softc *sc;
1334 {
1335 struct cue_chain *c;
1336 usbd_status err;
1337 int i;
1338
1339 /* Open RX and TX pipes. */
1340 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX],
1341 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]);
1342 if (err) {
1343 printf("%s: open rx pipe failed: %s\n",
1344 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1345 return (EIO);
1346 }
1347 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX],
1348 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]);
1349 if (err) {
1350 printf("%s: open tx pipe failed: %s\n",
1351 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1352 return (EIO);
1353 }
1354
1355 /* Start up the receive pipe. */
1356 for (i = 0; i < CUE_RX_LIST_CNT; i++) {
1357 c = &sc->cue_cdata.cue_rx_chain[i];
1358 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
1359 c, c->cue_buf, CUE_BUFSZ,
1360 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1361 cue_rxeof);
1362 usbd_transfer(c->cue_xfer);
1363 }
1364
1365 return (0);
1366 }
1367
1368 Static int
1369 cue_ioctl(ifp, command, data)
1370 struct ifnet *ifp;
1371 u_long command;
1372 caddr_t data;
1373 {
1374 struct cue_softc *sc = ifp->if_softc;
1375 #if defined(__NetBSD__) || defined(__OpenBSD__)
1376 struct ifaddr *ifa = (struct ifaddr *)data;
1377 struct ifreq *ifr = (struct ifreq *)data;
1378 #endif
1379 int s, error = 0;
1380
1381 if (sc->cue_dying)
1382 return (EIO);
1383
1384 s = splimp();
1385
1386 switch(command) {
1387 #if defined(__FreeBSD__)
1388 case SIOCSIFADDR:
1389 case SIOCGIFADDR:
1390 case SIOCSIFMTU:
1391 error = ether_ioctl(ifp, command, data);
1392 break;
1393 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1394 case SIOCSIFADDR:
1395 ifp->if_flags |= IFF_UP;
1396 cue_init(sc);
1397
1398 switch (ifa->ifa_addr->sa_family) {
1399 #ifdef INET
1400 case AF_INET:
1401 #if defined(__NetBSD__)
1402 arp_ifinit(ifp, ifa);
1403 #else
1404 arp_ifinit(&sc->arpcom, ifa);
1405 #endif
1406 break;
1407 #endif /* INET */
1408 #ifdef NS
1409 case AF_NS:
1410 {
1411 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1412
1413 if (ns_nullhost(*ina))
1414 ina->x_host = *(union ns_host *)
1415 LLADDR(ifp->if_sadl);
1416 else
1417 memcpy(LLADDR(ifp->if_sadl),
1418 ina->x_host.c_host,
1419 ifp->if_addrlen);
1420 break;
1421 }
1422 #endif /* NS */
1423 }
1424 break;
1425
1426 case SIOCSIFMTU:
1427 if (ifr->ifr_mtu > ETHERMTU)
1428 error = EINVAL;
1429 else
1430 ifp->if_mtu = ifr->ifr_mtu;
1431 break;
1432
1433 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1434
1435 case SIOCSIFFLAGS:
1436 if (ifp->if_flags & IFF_UP) {
1437 if (ifp->if_flags & IFF_RUNNING &&
1438 ifp->if_flags & IFF_PROMISC &&
1439 !(sc->cue_if_flags & IFF_PROMISC)) {
1440 CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1441 cue_setmulti(sc);
1442 } else if (ifp->if_flags & IFF_RUNNING &&
1443 !(ifp->if_flags & IFF_PROMISC) &&
1444 sc->cue_if_flags & IFF_PROMISC) {
1445 CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1446 cue_setmulti(sc);
1447 } else if (!(ifp->if_flags & IFF_RUNNING))
1448 cue_init(sc);
1449 } else {
1450 if (ifp->if_flags & IFF_RUNNING)
1451 cue_stop(sc);
1452 }
1453 sc->cue_if_flags = ifp->if_flags;
1454 error = 0;
1455 break;
1456 case SIOCADDMULTI:
1457 case SIOCDELMULTI:
1458 cue_setmulti(sc);
1459 error = 0;
1460 break;
1461 default:
1462 error = EINVAL;
1463 break;
1464 }
1465
1466 splx(s);
1467
1468 return (error);
1469 }
1470
1471 Static void
1472 cue_watchdog(ifp)
1473 struct ifnet *ifp;
1474 {
1475 struct cue_softc *sc = ifp->if_softc;
1476
1477 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1478
1479 if (sc->cue_dying)
1480 return;
1481
1482 ifp->if_oerrors++;
1483 printf("%s: watchdog timeout\n", USBDEVNAME(sc->cue_dev));
1484
1485 /*
1486 * The polling business is a kludge to avoid allowing the
1487 * USB code to call tsleep() in usbd_delay_ms(), which will
1488 * kill us since the watchdog routine is invoked from
1489 * interrupt context.
1490 */
1491 usbd_set_polling(sc->cue_udev, 1);
1492 cue_stop(sc);
1493 cue_init(sc);
1494 usbd_set_polling(sc->cue_udev, 0);
1495
1496 if (ifp->if_snd.ifq_head != NULL)
1497 cue_start(ifp);
1498 }
1499
1500 /*
1501 * Stop the adapter and free any mbufs allocated to the
1502 * RX and TX lists.
1503 */
1504 Static void
1505 cue_stop(sc)
1506 struct cue_softc *sc;
1507 {
1508 usbd_status err;
1509 struct ifnet *ifp;
1510 int i;
1511
1512 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1513
1514 ifp = GET_IFP(sc);
1515 ifp->if_timer = 0;
1516
1517 cue_csr_write_1(sc, CUE_ETHCTL, 0);
1518 cue_reset(sc);
1519 usb_uncallout(sc->cue_stat_ch, cue_tick, sc);
1520
1521 /* Stop transfers. */
1522 if (sc->cue_ep[CUE_ENDPT_RX] != NULL) {
1523 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1524 if (err) {
1525 printf("%s: abort rx pipe failed: %s\n",
1526 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1527 }
1528 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1529 if (err) {
1530 printf("%s: close rx pipe failed: %s\n",
1531 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1532 }
1533 sc->cue_ep[CUE_ENDPT_RX] = NULL;
1534 }
1535
1536 if (sc->cue_ep[CUE_ENDPT_TX] != NULL) {
1537 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1538 if (err) {
1539 printf("%s: abort tx pipe failed: %s\n",
1540 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1541 }
1542 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1543 if (err) {
1544 printf("%s: close tx pipe failed: %s\n",
1545 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1546 }
1547 sc->cue_ep[CUE_ENDPT_TX] = NULL;
1548 }
1549
1550 if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) {
1551 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1552 if (err) {
1553 printf("%s: abort intr pipe failed: %s\n",
1554 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1555 }
1556 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1557 if (err) {
1558 printf("%s: close intr pipe failed: %s\n",
1559 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1560 }
1561 sc->cue_ep[CUE_ENDPT_INTR] = NULL;
1562 }
1563
1564 /* Free RX resources. */
1565 for (i = 0; i < CUE_RX_LIST_CNT; i++) {
1566 if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) {
1567 m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf);
1568 sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL;
1569 }
1570 if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) {
1571 usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer);
1572 sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL;
1573 }
1574 }
1575
1576 /* Free TX resources. */
1577 for (i = 0; i < CUE_TX_LIST_CNT; i++) {
1578 if (sc->cue_cdata.cue_tx_chain[i].cue_mbuf != NULL) {
1579 m_freem(sc->cue_cdata.cue_tx_chain[i].cue_mbuf);
1580 sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL;
1581 }
1582 if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) {
1583 usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer);
1584 sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL;
1585 }
1586 }
1587
1588 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1589 }
1590
1591 #ifdef __FreeBSD__
1592 /*
1593 * Stop all chip I/O so that the kernel's probe routines don't
1594 * get confused by errant DMAs when rebooting.
1595 */
1596 Static void
1597 cue_shutdown(dev)
1598 device_t dev;
1599 {
1600 struct cue_softc *sc;
1601
1602 sc = device_get_softc(dev);
1603
1604 cue_reset(sc);
1605 cue_stop(sc);
1606 }
1607 #endif
1608