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