if_cue.c revision 1.21 1 /* $NetBSD: if_cue.c,v 1.21 2000/04/02 21:25:41 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 #if defined(__OpenBSD__)
721 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
722 #endif
723 strncpy(ifp->if_xname, USBDEVNAME(sc->cue_dev), IFNAMSIZ);
724
725 /* Attach the interface. */
726 if_attach(ifp);
727 Ether_ifattach(ifp, eaddr);
728
729 #if NBPFILTER > 0
730 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB,
731 sizeof(struct ether_header));
732 #endif
733 #if NRND > 0
734 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->cue_dev),
735 RND_TYPE_NET, 0);
736 #endif
737
738 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
739
740 usb_callout_init(sc->cue_stat_ch);
741
742 sc->cue_attached = 1;
743 splx(s);
744
745 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cue_udev,
746 USBDEV(sc->cue_dev));
747
748 USB_ATTACH_SUCCESS_RETURN;
749 }
750
751 USB_DETACH(cue)
752 {
753 USB_DETACH_START(cue, sc);
754 struct ifnet *ifp = GET_IFP(sc);
755 int s;
756
757 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__));
758
759 s = splusb();
760
761 usb_uncallout(sc->cue_stat_ch, cue_tick, sc);
762
763 if (!sc->cue_attached) {
764 /* Detached before attached finished, so just bail out. */
765 splx(s);
766 return (0);
767 }
768
769 if (ifp->if_flags & IFF_RUNNING)
770 cue_stop(sc);
771
772 #if defined(__NetBSD__)
773 #if NRND > 0
774 rnd_detach_source(&sc->rnd_source);
775 #endif
776 #if NBPFILTER > 0
777 bpfdetach(ifp);
778 #endif
779 ether_ifdetach(ifp);
780 #endif /* __NetBSD__ */
781
782 if_detach(ifp);
783
784 #ifdef DIAGNOSTIC
785 if (sc->cue_ep[CUE_ENDPT_TX] != NULL ||
786 sc->cue_ep[CUE_ENDPT_RX] != NULL ||
787 sc->cue_ep[CUE_ENDPT_INTR] != NULL)
788 printf("%s: detach has active endpoints\n",
789 USBDEVNAME(sc->cue_dev));
790 #endif
791
792 sc->cue_attached = 0;
793 splx(s);
794
795 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cue_udev,
796 USBDEV(sc->cue_dev));
797
798 return (0);
799 }
800
801 #if defined(__NetBSD__) || defined(__OpenBSD__)
802 int
803 cue_activate(self, act)
804 device_ptr_t self;
805 enum devact act;
806 {
807 struct cue_softc *sc = (struct cue_softc *)self;
808
809 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__));
810
811 switch (act) {
812 case DVACT_ACTIVATE:
813 return (EOPNOTSUPP);
814 break;
815
816 case DVACT_DEACTIVATE:
817 /* Deactivate the interface. */
818 if_deactivate(&sc->cue_ec.ec_if);
819 sc->cue_dying = 1;
820 break;
821 }
822 return (0);
823 }
824 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
825
826 /*
827 * Initialize an RX descriptor and attach an MBUF cluster.
828 */
829 Static int
830 cue_newbuf(sc, c, m)
831 struct cue_softc *sc;
832 struct cue_chain *c;
833 struct mbuf *m;
834 {
835 struct mbuf *m_new = NULL;
836
837 if (m == NULL) {
838 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
839 if (m_new == NULL) {
840 printf("%s: no memory for rx list "
841 "-- packet dropped!\n", USBDEVNAME(sc->cue_dev));
842 return (ENOBUFS);
843 }
844
845 MCLGET(m_new, M_DONTWAIT);
846 if (!(m_new->m_flags & M_EXT)) {
847 printf("%s: no memory for rx list "
848 "-- packet dropped!\n", USBDEVNAME(sc->cue_dev));
849 m_freem(m_new);
850 return (ENOBUFS);
851 }
852 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
853 } else {
854 m_new = m;
855 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
856 m_new->m_data = m_new->m_ext.ext_buf;
857 }
858
859 m_adj(m_new, ETHER_ALIGN);
860 c->cue_mbuf = m_new;
861
862 return (0);
863 }
864
865 Static int
866 cue_rx_list_init(sc)
867 struct cue_softc *sc;
868 {
869 struct cue_cdata *cd;
870 struct cue_chain *c;
871 int i;
872
873 cd = &sc->cue_cdata;
874 for (i = 0; i < CUE_RX_LIST_CNT; i++) {
875 c = &cd->cue_rx_chain[i];
876 c->cue_sc = sc;
877 c->cue_idx = i;
878 if (cue_newbuf(sc, c, NULL) == ENOBUFS)
879 return (ENOBUFS);
880 if (c->cue_xfer == NULL) {
881 c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
882 if (c->cue_xfer == NULL)
883 return (ENOBUFS);
884 c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ);
885 if (c->cue_buf == NULL) {
886 usbd_free_xfer(c->cue_xfer);
887 return (ENOBUFS);
888 }
889 }
890 }
891
892 return (0);
893 }
894
895 Static int
896 cue_tx_list_init(sc)
897 struct cue_softc *sc;
898 {
899 struct cue_cdata *cd;
900 struct cue_chain *c;
901 int i;
902
903 cd = &sc->cue_cdata;
904 for (i = 0; i < CUE_TX_LIST_CNT; i++) {
905 c = &cd->cue_tx_chain[i];
906 c->cue_sc = sc;
907 c->cue_idx = i;
908 c->cue_mbuf = NULL;
909 if (c->cue_xfer == NULL) {
910 c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
911 if (c->cue_xfer == NULL)
912 return (ENOBUFS);
913 c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ);
914 if (c->cue_buf == NULL) {
915 usbd_free_xfer(c->cue_xfer);
916 return (ENOBUFS);
917 }
918 }
919 }
920
921 return (0);
922 }
923
924 #ifdef __FreeBSD__
925 Static void
926 cue_rxstart(ifp)
927 struct ifnet *ifp;
928 {
929 struct cue_softc *sc;
930 struct cue_chain *c;
931
932 sc = ifp->if_softc;
933 c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod];
934
935 if (cue_newbuf(sc, c, NULL) == ENOBUFS) {
936 ifp->if_ierrors++;
937 return;
938 }
939
940 /* Setup new transfer. */
941 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
942 c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
943 USBD_NO_TIMEOUT, cue_rxeof);
944 usbd_transfer(c->cue_xfer);
945 }
946 #endif
947
948 /*
949 * A frame has been uploaded: pass the resulting mbuf chain up to
950 * the higher level protocols.
951 */
952 Static void
953 cue_rxeof(xfer, priv, status)
954 usbd_xfer_handle xfer;
955 usbd_private_handle priv;
956 usbd_status status;
957 {
958 struct cue_chain *c = priv;
959 struct cue_softc *sc = c->cue_sc;
960 struct ifnet *ifp = GET_IFP(sc);
961 struct mbuf *m;
962 int total_len = 0;
963 u_int16_t len;
964 #if defined(__NetBSD__) || defined(__OpenBSD__)
965 int s;
966 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
967
968 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev),
969 __FUNCTION__, status));
970
971 if (sc->cue_dying)
972 return;
973
974 if (!(ifp->if_flags & IFF_RUNNING))
975 return;
976
977 if (status != USBD_NORMAL_COMPLETION) {
978 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
979 return;
980 sc->cue_rx_errs++;
981 if (usbd_ratecheck(&sc->cue_rx_notice)) {
982 printf("%s: %u usb errors on rx: %s\n",
983 USBDEVNAME(sc->cue_dev), sc->cue_rx_errs,
984 usbd_errstr(status));
985 sc->cue_rx_errs = 0;
986 }
987 if (status == USBD_STALLED)
988 usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]);
989 goto done;
990 }
991
992 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
993
994 memcpy(mtod(c->cue_mbuf, char *), c->cue_buf, total_len);
995
996 m = c->cue_mbuf;
997 len = UGETW(mtod(m, u_int8_t *));
998
999 /* No errors; receive the packet. */
1000 total_len = len;
1001
1002 if (len < sizeof(struct ether_header)) {
1003 ifp->if_ierrors++;
1004 goto done;
1005 }
1006
1007 ifp->if_ipackets++;
1008 m_adj(m, sizeof(u_int16_t));
1009 m->m_pkthdr.len = m->m_len = total_len;
1010
1011 #if defined(__FreeBSD__)
1012 m->m_pkthdr.rcvif = (struct ifnet *)&cue_qdat;
1013 /* Put the packet on the special USB input queue. */
1014 usb_ether_input(m);
1015
1016 return;
1017 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1018 m->m_pkthdr.rcvif = ifp;
1019
1020 s = splimp();
1021
1022 /* XXX ugly */
1023 if (cue_newbuf(sc, c, NULL) == ENOBUFS) {
1024 ifp->if_ierrors++;
1025 goto done1;
1026 }
1027
1028 #if NBPFILTER > 0
1029 /*
1030 * Handle BPF listeners. Let the BPF user see the packet, but
1031 * don't pass it up to the ether_input() layer unless it's
1032 * a broadcast packet, multicast packet, matches our ethernet
1033 * address or the interface is in promiscuous mode.
1034 */
1035 if (ifp->if_bpf) {
1036 #if defined(__NetBSD__)
1037 struct ether_header *eh = mtod(m, struct ether_header *);
1038 BPF_MTAP(ifp, m);
1039 if ((ifp->if_flags & IFF_PROMISC) &&
1040 memcmp(eh->ether_dhost, LLADDR(ifp->if_sadl),
1041 ETHER_ADDR_LEN) &&
1042 !(eh->ether_dhost[0] & 1)) {
1043 m_freem(m);
1044 goto done1;
1045 }
1046 #else
1047 BPF_MTAP(ifp, m);
1048 #endif
1049 }
1050 #endif
1051
1052 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->cue_dev),
1053 __FUNCTION__, m->m_len));
1054 IF_INPUT(ifp, m);
1055 done1:
1056 splx(s);
1057 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1058
1059 done:
1060 /* Setup new transfer. */
1061 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
1062 c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
1063 USBD_NO_TIMEOUT, cue_rxeof);
1064 usbd_transfer(c->cue_xfer);
1065
1066 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->cue_dev),
1067 __FUNCTION__));
1068 }
1069
1070 /*
1071 * A frame was downloaded to the chip. It's safe for us to clean up
1072 * the list buffers.
1073 */
1074 Static void
1075 cue_txeof(xfer, priv, status)
1076 usbd_xfer_handle xfer;
1077 usbd_private_handle priv;
1078 usbd_status status;
1079 {
1080 struct cue_chain *c = priv;
1081 struct cue_softc *sc = c->cue_sc;
1082 struct ifnet *ifp = GET_IFP(sc);
1083 int s;
1084
1085 if (sc->cue_dying)
1086 return;
1087
1088 s = splimp();
1089
1090 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev),
1091 __FUNCTION__, status));
1092
1093 ifp->if_timer = 0;
1094 ifp->if_flags &= ~IFF_OACTIVE;
1095
1096 if (status != USBD_NORMAL_COMPLETION) {
1097 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1098 splx(s);
1099 return;
1100 }
1101 ifp->if_oerrors++;
1102 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cue_dev),
1103 usbd_errstr(status));
1104 if (status == USBD_STALLED)
1105 usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);
1106 splx(s);
1107 return;
1108 }
1109
1110 ifp->if_opackets++;
1111
1112 #if defined(__FreeBSD__)
1113 c->cue_mbuf->m_pkthdr.rcvif = ifp;
1114 usb_tx_done(c->cue_mbuf);
1115 c->cue_mbuf = NULL;
1116 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1117 m_freem(c->cue_mbuf);
1118 c->cue_mbuf = NULL;
1119
1120 if (ifp->if_snd.ifq_head != NULL)
1121 cue_start(ifp);
1122 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1123
1124 splx(s);
1125 }
1126
1127 Static void
1128 cue_tick(xsc)
1129 void *xsc;
1130 {
1131 struct cue_softc *sc = xsc;
1132 struct ifnet *ifp;
1133 int s;
1134
1135 if (sc == NULL)
1136 return;
1137
1138 if (sc->cue_dying)
1139 return;
1140
1141 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __FUNCTION__));
1142
1143 s = splimp();
1144
1145 ifp = GET_IFP(sc);
1146
1147 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
1148 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
1149 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
1150
1151 if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
1152 ifp->if_ierrors++;
1153
1154 usb_callout(sc->cue_stat_ch, hz, cue_tick, sc);
1155
1156 splx(s);
1157 }
1158
1159 Static int
1160 cue_send(sc, m, idx)
1161 struct cue_softc *sc;
1162 struct mbuf *m;
1163 int idx;
1164 {
1165 int total_len;
1166 struct cue_chain *c;
1167 usbd_status err;
1168
1169 c = &sc->cue_cdata.cue_tx_chain[idx];
1170
1171 /*
1172 * Copy the mbuf data into a contiguous buffer, leaving two
1173 * bytes at the beginning to hold the frame length.
1174 */
1175 m_copydata(m, 0, m->m_pkthdr.len, c->cue_buf + 2);
1176 c->cue_mbuf = m;
1177
1178 total_len = m->m_pkthdr.len + 2;
1179
1180 DPRINTFN(10,("%s: %s: total_len=%d\n",
1181 USBDEVNAME(sc->cue_dev), __FUNCTION__, total_len));
1182
1183 /* The first two bytes are the frame length */
1184 c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len;
1185 c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
1186
1187 /* XXX 10000 */
1188 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX],
1189 c, c->cue_buf, total_len, USBD_NO_COPY, 10000, cue_txeof);
1190
1191 /* Transmit */
1192 err = usbd_transfer(c->cue_xfer);
1193 if (err != USBD_IN_PROGRESS) {
1194 printf("%s: cue_send error=%s\n", USBDEVNAME(sc->cue_dev),
1195 usbd_errstr(err));
1196 cue_stop(sc);
1197 return (EIO);
1198 }
1199
1200 sc->cue_cdata.cue_tx_cnt++;
1201
1202 return (0);
1203 }
1204
1205 Static void
1206 cue_start(ifp)
1207 struct ifnet *ifp;
1208 {
1209 struct cue_softc *sc = ifp->if_softc;
1210 struct mbuf *m_head = NULL;
1211
1212 if (sc->cue_dying)
1213 return;
1214
1215 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1216
1217 if (ifp->if_flags & IFF_OACTIVE)
1218 return;
1219
1220 IF_DEQUEUE(&ifp->if_snd, m_head);
1221 if (m_head == NULL)
1222 return;
1223
1224 if (cue_send(sc, m_head, 0)) {
1225 IF_PREPEND(&ifp->if_snd, m_head);
1226 ifp->if_flags |= IFF_OACTIVE;
1227 return;
1228 }
1229
1230 #if NBPFILTER > 0
1231 /*
1232 * If there's a BPF listener, bounce a copy of this frame
1233 * to him.
1234 */
1235 if (ifp->if_bpf)
1236 BPF_MTAP(ifp, m_head);
1237 #endif
1238
1239 ifp->if_flags |= IFF_OACTIVE;
1240
1241 /*
1242 * Set a timeout in case the chip goes out to lunch.
1243 */
1244 ifp->if_timer = 5;
1245 }
1246
1247 Static void
1248 cue_init(xsc)
1249 void *xsc;
1250 {
1251 struct cue_softc *sc = xsc;
1252 struct ifnet *ifp = GET_IFP(sc);
1253 int i, s, ctl;
1254 u_char *eaddr;
1255
1256 if (sc->cue_dying)
1257 return;
1258
1259 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1260
1261 if (ifp->if_flags & IFF_RUNNING)
1262 return;
1263
1264 s = splimp();
1265
1266 /*
1267 * Cancel pending I/O and free all RX/TX buffers.
1268 */
1269 #if 1
1270 cue_reset(sc);
1271 #endif
1272
1273 /* Set advanced operation modes. */
1274 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
1275 CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */
1276
1277 #if defined(__FreeBSD__) || defined(__OpenBSD__)
1278 eaddr = sc->arpcom.ac_enaddr;
1279 #elif defined(__NetBSD__)
1280 eaddr = LLADDR(ifp->if_sadl);
1281 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1282 /* Set MAC address */
1283 for (i = 0; i < ETHER_ADDR_LEN; i++)
1284 cue_csr_write_1(sc, CUE_PAR0 - i, eaddr[i]);
1285
1286 /* Enable RX logic. */
1287 ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON;
1288 if (ifp->if_flags & IFF_PROMISC)
1289 ctl |= CUE_ETHCTL_PROMISC;
1290 cue_csr_write_1(sc, CUE_ETHCTL, ctl);
1291
1292 /* Init TX ring. */
1293 if (cue_tx_list_init(sc) == ENOBUFS) {
1294 printf("%s: tx list init failed\n", USBDEVNAME(sc->cue_dev));
1295 splx(s);
1296 return;
1297 }
1298
1299 /* Init RX ring. */
1300 if (cue_rx_list_init(sc) == ENOBUFS) {
1301 printf("%s: rx list init failed\n", USBDEVNAME(sc->cue_dev));
1302 splx(s);
1303 return;
1304 }
1305
1306 /* Load the multicast filter. */
1307 cue_setmulti(sc);
1308
1309 /*
1310 * Set the number of RX and TX buffers that we want
1311 * to reserve inside the ASIC.
1312 */
1313 cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
1314 cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
1315
1316 /* Set advanced operation modes. */
1317 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
1318 CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */
1319
1320 /* Program the LED operation. */
1321 cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
1322
1323 if (sc->cue_ep[CUE_ENDPT_RX] == NULL) {
1324 if (cue_open_pipes(sc)) {
1325 splx(s);
1326 return;
1327 }
1328 }
1329
1330 ifp->if_flags |= IFF_RUNNING;
1331 ifp->if_flags &= ~IFF_OACTIVE;
1332
1333 splx(s);
1334
1335 usb_callout(sc->cue_stat_ch, hz, cue_tick, sc);
1336 }
1337
1338 Static int
1339 cue_open_pipes(sc)
1340 struct cue_softc *sc;
1341 {
1342 struct cue_chain *c;
1343 usbd_status err;
1344 int i;
1345
1346 /* Open RX and TX pipes. */
1347 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX],
1348 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]);
1349 if (err) {
1350 printf("%s: open rx pipe failed: %s\n",
1351 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1352 return (EIO);
1353 }
1354 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX],
1355 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]);
1356 if (err) {
1357 printf("%s: open tx pipe failed: %s\n",
1358 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1359 return (EIO);
1360 }
1361
1362 /* Start up the receive pipe. */
1363 for (i = 0; i < CUE_RX_LIST_CNT; i++) {
1364 c = &sc->cue_cdata.cue_rx_chain[i];
1365 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
1366 c, c->cue_buf, CUE_BUFSZ,
1367 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1368 cue_rxeof);
1369 usbd_transfer(c->cue_xfer);
1370 }
1371
1372 return (0);
1373 }
1374
1375 Static int
1376 cue_ioctl(ifp, command, data)
1377 struct ifnet *ifp;
1378 u_long command;
1379 caddr_t data;
1380 {
1381 struct cue_softc *sc = ifp->if_softc;
1382 #if defined(__NetBSD__) || defined(__OpenBSD__)
1383 struct ifaddr *ifa = (struct ifaddr *)data;
1384 struct ifreq *ifr = (struct ifreq *)data;
1385 #endif
1386 int s, error = 0;
1387
1388 if (sc->cue_dying)
1389 return (EIO);
1390
1391 s = splimp();
1392
1393 switch(command) {
1394 #if defined(__FreeBSD__)
1395 case SIOCSIFADDR:
1396 case SIOCGIFADDR:
1397 case SIOCSIFMTU:
1398 error = ether_ioctl(ifp, command, data);
1399 break;
1400 #elif defined(__NetBSD__) || defined(__OpenBSD__)
1401 case SIOCSIFADDR:
1402 ifp->if_flags |= IFF_UP;
1403 cue_init(sc);
1404
1405 switch (ifa->ifa_addr->sa_family) {
1406 #ifdef INET
1407 case AF_INET:
1408 #if defined(__NetBSD__)
1409 arp_ifinit(ifp, ifa);
1410 #else
1411 arp_ifinit(&sc->arpcom, ifa);
1412 #endif
1413 break;
1414 #endif /* INET */
1415 #ifdef NS
1416 case AF_NS:
1417 {
1418 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1419
1420 if (ns_nullhost(*ina))
1421 ina->x_host = *(union ns_host *)
1422 LLADDR(ifp->if_sadl);
1423 else
1424 memcpy(LLADDR(ifp->if_sadl),
1425 ina->x_host.c_host,
1426 ifp->if_addrlen);
1427 break;
1428 }
1429 #endif /* NS */
1430 }
1431 break;
1432
1433 case SIOCSIFMTU:
1434 if (ifr->ifr_mtu > ETHERMTU)
1435 error = EINVAL;
1436 else
1437 ifp->if_mtu = ifr->ifr_mtu;
1438 break;
1439
1440 #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1441
1442 case SIOCSIFFLAGS:
1443 if (ifp->if_flags & IFF_UP) {
1444 if (ifp->if_flags & IFF_RUNNING &&
1445 ifp->if_flags & IFF_PROMISC &&
1446 !(sc->cue_if_flags & IFF_PROMISC)) {
1447 CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1448 cue_setmulti(sc);
1449 } else if (ifp->if_flags & IFF_RUNNING &&
1450 !(ifp->if_flags & IFF_PROMISC) &&
1451 sc->cue_if_flags & IFF_PROMISC) {
1452 CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1453 cue_setmulti(sc);
1454 } else if (!(ifp->if_flags & IFF_RUNNING))
1455 cue_init(sc);
1456 } else {
1457 if (ifp->if_flags & IFF_RUNNING)
1458 cue_stop(sc);
1459 }
1460 sc->cue_if_flags = ifp->if_flags;
1461 error = 0;
1462 break;
1463 case SIOCADDMULTI:
1464 case SIOCDELMULTI:
1465 cue_setmulti(sc);
1466 error = 0;
1467 break;
1468 default:
1469 error = EINVAL;
1470 break;
1471 }
1472
1473 splx(s);
1474
1475 return (error);
1476 }
1477
1478 Static void
1479 cue_watchdog(ifp)
1480 struct ifnet *ifp;
1481 {
1482 struct cue_softc *sc = ifp->if_softc;
1483
1484 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1485
1486 if (sc->cue_dying)
1487 return;
1488
1489 ifp->if_oerrors++;
1490 printf("%s: watchdog timeout\n", USBDEVNAME(sc->cue_dev));
1491
1492 /*
1493 * The polling business is a kludge to avoid allowing the
1494 * USB code to call tsleep() in usbd_delay_ms(), which will
1495 * kill us since the watchdog routine is invoked from
1496 * interrupt context.
1497 */
1498 usbd_set_polling(sc->cue_udev, 1);
1499 cue_stop(sc);
1500 cue_init(sc);
1501 usbd_set_polling(sc->cue_udev, 0);
1502
1503 if (ifp->if_snd.ifq_head != NULL)
1504 cue_start(ifp);
1505 }
1506
1507 /*
1508 * Stop the adapter and free any mbufs allocated to the
1509 * RX and TX lists.
1510 */
1511 Static void
1512 cue_stop(sc)
1513 struct cue_softc *sc;
1514 {
1515 usbd_status err;
1516 struct ifnet *ifp;
1517 int i;
1518
1519 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__FUNCTION__));
1520
1521 ifp = GET_IFP(sc);
1522 ifp->if_timer = 0;
1523
1524 cue_csr_write_1(sc, CUE_ETHCTL, 0);
1525 cue_reset(sc);
1526 usb_uncallout(sc->cue_stat_ch, cue_tick, sc);
1527
1528 /* Stop transfers. */
1529 if (sc->cue_ep[CUE_ENDPT_RX] != NULL) {
1530 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1531 if (err) {
1532 printf("%s: abort rx pipe failed: %s\n",
1533 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1534 }
1535 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1536 if (err) {
1537 printf("%s: close rx pipe failed: %s\n",
1538 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1539 }
1540 sc->cue_ep[CUE_ENDPT_RX] = NULL;
1541 }
1542
1543 if (sc->cue_ep[CUE_ENDPT_TX] != NULL) {
1544 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1545 if (err) {
1546 printf("%s: abort tx pipe failed: %s\n",
1547 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1548 }
1549 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1550 if (err) {
1551 printf("%s: close tx pipe failed: %s\n",
1552 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1553 }
1554 sc->cue_ep[CUE_ENDPT_TX] = NULL;
1555 }
1556
1557 if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) {
1558 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1559 if (err) {
1560 printf("%s: abort intr pipe failed: %s\n",
1561 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1562 }
1563 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1564 if (err) {
1565 printf("%s: close intr pipe failed: %s\n",
1566 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1567 }
1568 sc->cue_ep[CUE_ENDPT_INTR] = NULL;
1569 }
1570
1571 /* Free RX resources. */
1572 for (i = 0; i < CUE_RX_LIST_CNT; i++) {
1573 if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) {
1574 m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf);
1575 sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL;
1576 }
1577 if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) {
1578 usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer);
1579 sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL;
1580 }
1581 }
1582
1583 /* Free TX resources. */
1584 for (i = 0; i < CUE_TX_LIST_CNT; i++) {
1585 if (sc->cue_cdata.cue_tx_chain[i].cue_mbuf != NULL) {
1586 m_freem(sc->cue_cdata.cue_tx_chain[i].cue_mbuf);
1587 sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL;
1588 }
1589 if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) {
1590 usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer);
1591 sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL;
1592 }
1593 }
1594
1595 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1596 }
1597
1598 #ifdef __FreeBSD__
1599 /*
1600 * Stop all chip I/O so that the kernel's probe routines don't
1601 * get confused by errant DMAs when rebooting.
1602 */
1603 Static void
1604 cue_shutdown(dev)
1605 device_t dev;
1606 {
1607 struct cue_softc *sc;
1608
1609 sc = device_get_softc(dev);
1610
1611 cue_reset(sc);
1612 cue_stop(sc);
1613 }
1614 #endif
1615