if_cue.c revision 1.48.10.3 1 /* $NetBSD: if_cue.c,v 1.48.10.3 2007/06/17 00:51:33 itohy 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 #include <sys/cdefs.h>
59 __KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.48.10.3 2007/06/17 00:51:33 itohy Exp $");
60
61 #if defined(__NetBSD__)
62 #include "opt_inet.h"
63 #include "bpfilter.h"
64 #include "rnd.h"
65 #elif defined(__OpenBSD__)
66 #include "bpfilter.h"
67 #endif /* defined(__OpenBSD__) */
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #if !defined(__OpenBSD__)
72 #include <sys/callout.h>
73 #endif
74 #include <sys/sockio.h>
75 #include <sys/mbuf.h>
76 #include <sys/malloc.h>
77 #include <sys/kernel.h>
78 #include <sys/socket.h>
79
80 #include <sys/device.h>
81 #if NRND > 0
82 #include <sys/rnd.h>
83 #endif
84
85 #include <net/if.h>
86 #if defined(__NetBSD__)
87 #include <net/if_arp.h>
88 #endif
89 #include <net/if_dl.h>
90
91 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
92
93 #if NBPFILTER > 0
94 #include <net/bpf.h>
95 #endif
96
97 #if defined(__NetBSD__)
98 #include <net/if_ether.h>
99 #ifdef INET
100 #include <netinet/in.h>
101 #include <netinet/if_inarp.h>
102 #endif
103 #endif /* defined(__NetBSD__) */
104
105 #if defined(__OpenBSD__)
106 #ifdef INET
107 #include <netinet/in.h>
108 #include <netinet/in_systm.h>
109 #include <netinet/in_var.h>
110 #include <netinet/ip.h>
111 #include <netinet/if_ether.h>
112 #endif
113 #endif /* defined(__OpenBSD__) */
114
115
116 #include <dev/usb/usb.h>
117 #include <dev/usb/usbdi.h>
118 #include <dev/usb/usbdi_util.h>
119 #include <dev/usb/usbdevs.h>
120 #include <dev/usb/usb_ethersubr.h>
121
122 #include <dev/usb/if_cuereg.h>
123
124 #ifdef CUE_DEBUG
125 #define DPRINTF(x) if (cuedebug) logprintf x
126 #define DPRINTFN(n,x) if (cuedebug >= (n)) logprintf x
127 int cuedebug = 0;
128 #else
129 #define DPRINTF(x)
130 #define DPRINTFN(n,x)
131 #endif
132
133 /*
134 * Various supported device vendors/products.
135 */
136 Static struct usb_devno cue_devs[] = {
137 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE },
138 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 },
139 { USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK },
140 /* Belkin F5U111 adapter covered by NETMATE entry */
141 };
142 #define cue_lookup(v, p) (usb_lookup(cue_devs, v, p))
143
144 USB_DECLARE_DRIVER(cue);
145
146 Static int cue_open_pipes(struct cue_softc *);
147 Static int cue_send(struct cue_softc *, struct mbuf *, int);
148 Static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
149 Static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
150 Static void cue_tick(void *);
151 Static void cue_tick_task(void *);
152 Static void cue_start(struct ifnet *);
153 Static int cue_ioctl(struct ifnet *, u_long, usb_ioctlarg_t);
154 Static int cue_init(struct ifnet *);
155 Static void cue_stop(struct ifnet *, int);
156 Static void cue_watchdog(struct ifnet *);
157
158 Static void cue_setmulti(struct cue_softc *);
159 Static u_int32_t cue_crc(const char *);
160 Static void cue_reset(struct cue_softc *);
161
162 Static int cue_csr_read_1(struct cue_softc *, int);
163 Static int cue_csr_write_1(struct cue_softc *, int, int);
164 Static int cue_csr_read_2(struct cue_softc *, int);
165 #if 0
166 Static int cue_csr_write_2(struct cue_softc *, int, int);
167 #endif
168 Static int cue_mem(struct cue_softc *, int, int, void *, int);
169 Static int cue_getmac(struct cue_softc *, void *);
170
171 #define CUE_SETBIT(sc, reg, x) \
172 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
173
174 #define CUE_CLRBIT(sc, reg, x) \
175 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
176
177 Static int
178 cue_csr_read_1(struct cue_softc *sc, int reg)
179 {
180 usb_device_request_t req;
181 usbd_status err;
182 u_int8_t val = 0;
183
184 if (sc->cue_dying)
185 return (0);
186
187 req.bmRequestType = UT_READ_VENDOR_DEVICE;
188 req.bRequest = CUE_CMD_READREG;
189 USETW(req.wValue, 0);
190 USETW(req.wIndex, reg);
191 USETW(req.wLength, 1);
192
193 err = usbd_do_request(sc->cue_udev, &req, &val);
194
195 if (err) {
196 DPRINTF(("%s: cue_csr_read_1: reg=0x%x err=%s\n",
197 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
198 return (0);
199 }
200
201 DPRINTFN(10,("%s: cue_csr_read_1 reg=0x%x val=0x%x\n",
202 USBDEVNAME(sc->cue_dev), reg, val));
203
204 return (val);
205 }
206
207 Static int
208 cue_csr_read_2(struct cue_softc *sc, int reg)
209 {
210 usb_device_request_t req;
211 usbd_status err;
212 uWord val;
213
214 if (sc->cue_dying)
215 return (0);
216
217 req.bmRequestType = UT_READ_VENDOR_DEVICE;
218 req.bRequest = CUE_CMD_READREG;
219 USETW(req.wValue, 0);
220 USETW(req.wIndex, reg);
221 USETW(req.wLength, 2);
222
223 err = usbd_do_request(sc->cue_udev, &req, &val);
224
225 DPRINTFN(10,("%s: cue_csr_read_2 reg=0x%x val=0x%x\n",
226 USBDEVNAME(sc->cue_dev), reg, UGETW(val)));
227
228 if (err) {
229 DPRINTF(("%s: cue_csr_read_2: reg=0x%x err=%s\n",
230 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
231 return (0);
232 }
233
234 return (UGETW(val));
235 }
236
237 Static int
238 cue_csr_write_1(struct cue_softc *sc, int reg, int val)
239 {
240 usb_device_request_t req;
241 usbd_status err;
242
243 if (sc->cue_dying)
244 return (0);
245
246 DPRINTFN(10,("%s: cue_csr_write_1 reg=0x%x val=0x%x\n",
247 USBDEVNAME(sc->cue_dev), reg, val));
248
249 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
250 req.bRequest = CUE_CMD_WRITEREG;
251 USETW(req.wValue, val);
252 USETW(req.wIndex, reg);
253 USETW(req.wLength, 0);
254
255 err = usbd_do_request(sc->cue_udev, &req, NULL);
256
257 if (err) {
258 DPRINTF(("%s: cue_csr_write_1: reg=0x%x err=%s\n",
259 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
260 return (-1);
261 }
262
263 DPRINTFN(20,("%s: cue_csr_write_1, after reg=0x%x val=0x%x\n",
264 USBDEVNAME(sc->cue_dev), reg, cue_csr_read_1(sc, reg)));
265
266 return (0);
267 }
268
269 #if 0
270 Static int
271 cue_csr_write_2(struct cue_softc *sc, int reg, int aval)
272 {
273 usb_device_request_t req;
274 usbd_status err;
275 uWord val;
276 int s;
277
278 if (sc->cue_dying)
279 return (0);
280
281 DPRINTFN(10,("%s: cue_csr_write_2 reg=0x%x val=0x%x\n",
282 USBDEVNAME(sc->cue_dev), reg, aval));
283
284 USETW(val, aval);
285 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
286 req.bRequest = CUE_CMD_WRITEREG;
287 USETW(req.wValue, val);
288 USETW(req.wIndex, reg);
289 USETW(req.wLength, 0);
290
291 err = usbd_do_request(sc->cue_udev, &req, NULL);
292
293 if (err) {
294 DPRINTF(("%s: cue_csr_write_2: reg=0x%x err=%s\n",
295 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err)));
296 return (-1);
297 }
298
299 return (0);
300 }
301 #endif
302
303 Static int
304 cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len)
305 {
306 usb_device_request_t req;
307 usbd_status err;
308
309 DPRINTFN(10,("%s: cue_mem cmd=0x%x addr=0x%x len=%d\n",
310 USBDEVNAME(sc->cue_dev), cmd, addr, len));
311
312 if (cmd == CUE_CMD_READSRAM)
313 req.bmRequestType = UT_READ_VENDOR_DEVICE;
314 else
315 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
316 req.bRequest = cmd;
317 USETW(req.wValue, 0);
318 USETW(req.wIndex, addr);
319 USETW(req.wLength, len);
320
321 err = usbd_do_request(sc->cue_udev, &req, buf);
322
323 if (err) {
324 DPRINTF(("%s: cue_csr_mem: addr=0x%x err=%s\n",
325 USBDEVNAME(sc->cue_dev), addr, usbd_errstr(err)));
326 return (-1);
327 }
328
329 return (0);
330 }
331
332 Static int
333 cue_getmac(struct cue_softc *sc, void *buf)
334 {
335 usb_device_request_t req;
336 usbd_status err;
337
338 DPRINTFN(10,("%s: cue_getmac\n", USBDEVNAME(sc->cue_dev)));
339
340 req.bmRequestType = UT_READ_VENDOR_DEVICE;
341 req.bRequest = CUE_CMD_GET_MACADDR;
342 USETW(req.wValue, 0);
343 USETW(req.wIndex, 0);
344 USETW(req.wLength, ETHER_ADDR_LEN);
345
346 err = usbd_do_request(sc->cue_udev, &req, buf);
347
348 if (err) {
349 printf("%s: read MAC address failed\n",USBDEVNAME(sc->cue_dev));
350 return (-1);
351 }
352
353 return (0);
354 }
355
356 #define CUE_POLY 0xEDB88320
357 #define CUE_BITS 9
358
359 Static u_int32_t
360 cue_crc(const char *addr)
361 {
362 u_int32_t idx, bit, data, crc;
363
364 /* Compute CRC for the address value. */
365 crc = 0xFFFFFFFF; /* initial value */
366
367 for (idx = 0; idx < 6; idx++) {
368 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
369 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0);
370 }
371
372 return (crc & ((1 << CUE_BITS) - 1));
373 }
374
375 Static void
376 cue_setmulti(struct cue_softc *sc)
377 {
378 struct ifnet *ifp;
379 struct ether_multi *enm;
380 struct ether_multistep step;
381 u_int32_t h, i;
382
383 ifp = GET_IFP(sc);
384
385 DPRINTFN(2,("%s: cue_setmulti if_flags=0x%x\n",
386 USBDEVNAME(sc->cue_dev), ifp->if_flags));
387
388 if (ifp->if_flags & IFF_PROMISC) {
389 allmulti:
390 ifp->if_flags |= IFF_ALLMULTI;
391 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
392 sc->cue_mctab[i] = 0xFF;
393 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
394 &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
395 return;
396 }
397
398 /* first, zot all the existing hash bits */
399 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
400 sc->cue_mctab[i] = 0;
401
402 /* now program new ones */
403 #if defined(__NetBSD__)
404 ETHER_FIRST_MULTI(step, &sc->cue_ec, enm);
405 #else
406 ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
407 #endif
408 while (enm != NULL) {
409 if (memcmp(enm->enm_addrlo,
410 enm->enm_addrhi, ETHER_ADDR_LEN) != 0)
411 goto allmulti;
412
413 h = cue_crc(enm->enm_addrlo);
414 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
415 ETHER_NEXT_MULTI(step, enm);
416 }
417
418 ifp->if_flags &= ~IFF_ALLMULTI;
419
420 /*
421 * Also include the broadcast address in the filter
422 * so we can receive broadcast frames.
423 */
424 if (ifp->if_flags & IFF_BROADCAST) {
425 h = cue_crc(etherbroadcastaddr);
426 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
427 }
428
429 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
430 &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
431 }
432
433 Static void
434 cue_reset(struct cue_softc *sc)
435 {
436 usb_device_request_t req;
437 usbd_status err;
438
439 DPRINTFN(2,("%s: cue_reset\n", USBDEVNAME(sc->cue_dev)));
440
441 if (sc->cue_dying)
442 return;
443
444 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
445 req.bRequest = CUE_CMD_RESET;
446 USETW(req.wValue, 0);
447 USETW(req.wIndex, 0);
448 USETW(req.wLength, 0);
449
450 err = usbd_do_request(sc->cue_udev, &req, NULL);
451
452 if (err)
453 printf("%s: reset failed\n", USBDEVNAME(sc->cue_dev));
454
455 /* Wait a little while for the chip to get its brains in order. */
456 usbd_delay_ms(sc->cue_udev, 1);
457 }
458
459 /*
460 * Probe for a CATC chip.
461 */
462 USB_MATCH(cue)
463 {
464 USB_MATCH_START(cue, uaa);
465
466 if (uaa->iface != NULL)
467 return (UMATCH_NONE);
468
469 return (cue_lookup(uaa->vendor, uaa->product) != NULL ?
470 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
471 }
472
473 /*
474 * Attach the interface. Allocate softc structures, do ifmedia
475 * setup and ethernet/BPF attach.
476 */
477 USB_ATTACH(cue)
478 {
479 USB_ATTACH_START(cue, sc, uaa);
480 char *devinfop;
481 int s;
482 u_char eaddr[ETHER_ADDR_LEN];
483 usbd_device_handle dev = uaa->device;
484 usbd_interface_handle iface;
485 usbd_status err;
486 struct ifnet *ifp;
487 usb_interface_descriptor_t *id;
488 usb_endpoint_descriptor_t *ed;
489 int i;
490
491 DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc, dev));
492
493 devinfop = usbd_devinfo_alloc(dev, 0);
494 USB_ATTACH_SETUP;
495 printf("%s: %s\n", USBDEVNAME(sc->cue_dev), devinfop);
496 usbd_devinfo_free(devinfop);
497
498 err = usbd_set_config_no(dev, CUE_CONFIG_NO, 1);
499 if (err) {
500 printf("%s: setting config no failed\n",
501 USBDEVNAME(sc->cue_dev));
502 USB_ATTACH_ERROR_RETURN;
503 }
504
505 sc->cue_udev = dev;
506 sc->cue_product = uaa->product;
507 sc->cue_vendor = uaa->vendor;
508
509 usb_init_task(&sc->cue_tick_task, cue_tick_task, sc);
510 usb_init_task(&sc->cue_stop_task, (void (*)(void *))cue_stop, sc);
511
512 err = usbd_device2interface_handle(dev, CUE_IFACE_IDX, &iface);
513 if (err) {
514 printf("%s: getting interface handle failed\n",
515 USBDEVNAME(sc->cue_dev));
516 USB_ATTACH_ERROR_RETURN;
517 }
518
519 sc->cue_iface = iface;
520 id = usbd_get_interface_descriptor(iface);
521
522 /* Find endpoints. */
523 for (i = 0; i < id->bNumEndpoints; i++) {
524 ed = usbd_interface2endpoint_descriptor(iface, i);
525 if (ed == NULL) {
526 printf("%s: couldn't get ep %d\n",
527 USBDEVNAME(sc->cue_dev), i);
528 USB_ATTACH_ERROR_RETURN;
529 }
530 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
531 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
532 sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress;
533 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
534 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
535 sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress;
536 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
537 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
538 sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress;
539 }
540 }
541
542 #if 0
543 /* Reset the adapter. */
544 cue_reset(sc);
545 #endif
546 /*
547 * Get station address.
548 */
549 cue_getmac(sc, &eaddr);
550
551 s = splnet();
552
553 /*
554 * A CATC chip was detected. Inform the world.
555 */
556 printf("%s: Ethernet address %s\n", USBDEVNAME(sc->cue_dev),
557 ether_sprintf(eaddr));
558
559 /* Initialize interface info.*/
560 ifp = GET_IFP(sc);
561 ifp->if_softc = sc;
562 ifp->if_mtu = ETHERMTU;
563 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
564 ifp->if_ioctl = cue_ioctl;
565 ifp->if_start = cue_start;
566 ifp->if_init = cue_init;
567 ifp->if_stop = cue_stop;
568 ifp->if_watchdog = cue_watchdog;
569 #if defined(__OpenBSD__)
570 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
571 #endif
572 strncpy(ifp->if_xname, USBDEVNAME(sc->cue_dev), IFNAMSIZ);
573
574 IFQ_SET_READY(&ifp->if_snd);
575
576 /* Attach the interface. */
577 if_attach(ifp);
578 Ether_ifattach(ifp, eaddr);
579 #if NRND > 0
580 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->cue_dev),
581 RND_TYPE_NET, 0);
582 #endif
583
584 usb_callout_init(sc->cue_stat_ch);
585
586 sc->cue_attached = 1;
587 splx(s);
588
589 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cue_udev,
590 USBDEV(sc->cue_dev));
591
592 USB_ATTACH_SUCCESS_RETURN;
593 }
594
595 USB_DETACH(cue)
596 {
597 USB_DETACH_START(cue, sc);
598 struct ifnet *ifp = GET_IFP(sc);
599 int s;
600
601 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__));
602
603 usb_uncallout(sc->cue_stat_ch, cue_tick, sc);
604 /*
605 * Remove any pending task. It cannot be executing because it run
606 * in the same thread as detach.
607 */
608 usb_rem_task(sc->cue_udev, &sc->cue_tick_task);
609 usb_rem_task(sc->cue_udev, &sc->cue_stop_task);
610
611 if (!sc->cue_attached) {
612 /* Detached before attached finished, so just bail out. */
613 return (0);
614 }
615
616 s = splusb();
617
618 if (ifp->if_flags & IFF_RUNNING)
619 cue_stop(ifp, 1);
620
621 #if defined(__NetBSD__)
622 #if NRND > 0
623 rnd_detach_source(&sc->rnd_source);
624 #endif
625 ether_ifdetach(ifp);
626 #endif /* __NetBSD__ */
627
628 if_detach(ifp);
629
630 #ifdef DIAGNOSTIC
631 if (sc->cue_ep[CUE_ENDPT_TX] != NULL ||
632 sc->cue_ep[CUE_ENDPT_RX] != NULL ||
633 sc->cue_ep[CUE_ENDPT_INTR] != NULL)
634 printf("%s: detach has active endpoints\n",
635 USBDEVNAME(sc->cue_dev));
636 #endif
637
638 sc->cue_attached = 0;
639 splx(s);
640
641 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cue_udev,
642 USBDEV(sc->cue_dev));
643
644 return (0);
645 }
646
647 int
648 cue_activate(device_ptr_t self, enum devact act)
649 {
650 struct cue_softc *sc = (struct cue_softc *)self;
651
652 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__));
653
654 switch (act) {
655 case DVACT_ACTIVATE:
656 return (EOPNOTSUPP);
657 break;
658
659 case DVACT_DEACTIVATE:
660 /* Deactivate the interface. */
661 if_deactivate(&sc->cue_ec.ec_if);
662 sc->cue_dying = 1;
663 break;
664 }
665 return (0);
666 }
667
668 /*
669 * A frame has been uploaded: pass the resulting mbuf chain up to
670 * the higher level protocols.
671 */
672 Static void
673 cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
674 {
675 struct ue_chain *c = priv;
676 struct cue_softc *sc = (void *)c->ue_dev;
677 struct ifnet *ifp = GET_IFP(sc);
678 struct mbuf *m;
679 int total_len = 0;
680 u_int16_t len;
681 int s;
682
683 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev),
684 __func__, status));
685
686 if (sc->cue_dying)
687 return;
688
689 if (!(ifp->if_flags & IFF_RUNNING))
690 return;
691
692 usbd_unmap_buffer(xfer);
693
694 if (status != USBD_NORMAL_COMPLETION) {
695 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
696 return;
697 sc->cue_rx_errs++;
698 if (usbd_ratecheck(&sc->cue_rx_notice)) {
699 printf("%s: %u usb errors on rx: %s\n",
700 USBDEVNAME(sc->cue_dev), sc->cue_rx_errs,
701 usbd_errstr(status));
702 sc->cue_rx_errs = 0;
703 }
704 if (status == USBD_STALLED)
705 usbd_clear_endpoint_stall_async(sc->cue_ep[CUE_ENDPT_RX]);
706 goto done;
707 }
708
709 #if 0
710 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
711 /* XXX should check total_len ? */
712 #endif
713
714 m = c->ue_mbuf;
715 len = UGETW(mtod(m, u_int8_t *));
716
717 /* No errors; receive the packet. */
718 total_len = len;
719
720 if (len < sizeof(struct ether_header)) {
721 ifp->if_ierrors++;
722 goto done;
723 }
724
725 /*
726 * Allocate new mbuf cluster for the next transfer.
727 * If that failed, discard current packet and recycle the mbuf.
728 */
729 if ((c->ue_mbuf = usb_ether_newbuf(NULL)) == NULL) {
730 printf("%s: no memory for rx list -- packet dropped!\n",
731 USBDEVNAME(sc->cue_dev));
732 ifp->if_ierrors++;
733 c->ue_mbuf = usb_ether_newbuf(m);
734 goto done;
735 }
736
737 ifp->if_ipackets++;
738 m_adj(m, sizeof(u_int16_t));
739 m->m_pkthdr.len = m->m_len = total_len;
740
741 m->m_pkthdr.rcvif = ifp;
742
743 s = splnet();
744
745 #if NBPFILTER > 0
746 /*
747 * Handle BPF listeners. Let the BPF user see the packet, but
748 * don't pass it up to the ether_input() layer unless it's
749 * a broadcast packet, multicast packet, matches our ethernet
750 * address or the interface is in promiscuous mode.
751 */
752 if (ifp->if_bpf)
753 BPF_MTAP(ifp, m);
754 #endif
755
756 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->cue_dev),
757 __func__, m->m_len));
758 IF_INPUT(ifp, m);
759 splx(s);
760
761 done:
762 /* Setup new transfer. */
763 (void)usbd_map_buffer_mbuf(c->ue_xfer, c->ue_mbuf);
764 usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
765 c, NULL /* XXX buf */, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
766 USBD_NO_TIMEOUT, cue_rxeof);
767 usbd_transfer(c->ue_xfer);
768
769 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->cue_dev),
770 __func__));
771 }
772
773 /*
774 * A frame was downloaded to the chip. It's safe for us to clean up
775 * the list buffers.
776 */
777 Static void
778 cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv,
779 usbd_status status)
780 {
781 struct ue_chain *c = priv;
782 struct cue_softc *sc = (void *)c->ue_dev;
783 struct ifnet *ifp = GET_IFP(sc);
784 int s;
785
786 if (sc->cue_dying)
787 return;
788
789 usbd_unmap_buffer(xfer);
790
791 s = splnet();
792
793 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev),
794 __func__, status));
795
796 ifp->if_timer = 0;
797 ifp->if_flags &= ~IFF_OACTIVE;
798
799 if (status != USBD_NORMAL_COMPLETION) {
800 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
801 splx(s);
802 return;
803 }
804 ifp->if_oerrors++;
805 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cue_dev),
806 usbd_errstr(status));
807 if (status == USBD_STALLED)
808 usbd_clear_endpoint_stall_async(sc->cue_ep[CUE_ENDPT_TX]);
809 splx(s);
810 return;
811 }
812
813 ifp->if_opackets++;
814
815 m_freem(c->ue_mbuf);
816 c->ue_mbuf = NULL;
817
818 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
819 cue_start(ifp);
820
821 splx(s);
822 }
823
824 Static void
825 cue_tick(void *xsc)
826 {
827 struct cue_softc *sc = xsc;
828
829 if (sc == NULL)
830 return;
831
832 if (sc->cue_dying)
833 return;
834
835 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__));
836
837 /* Perform statistics update in process context. */
838 usb_add_task(sc->cue_udev, &sc->cue_tick_task, USB_TASKQ_DRIVER);
839 }
840
841 Static void
842 cue_tick_task(void *xsc)
843 {
844 struct cue_softc *sc = xsc;
845 struct ifnet *ifp;
846
847 if (sc->cue_dying)
848 return;
849
850 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__));
851
852 ifp = GET_IFP(sc);
853
854 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
855 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
856 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
857
858 if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
859 ifp->if_ierrors++;
860 }
861
862 Static int
863 cue_send(struct cue_softc *sc, struct mbuf *m, int idx)
864 {
865 int total_len;
866 struct ue_chain *c;
867 usbd_status err;
868 int ret;
869
870 c = &sc->cue_cdata.cue_tx_chain[idx];
871
872 /* Prepend two bytes at the beginning to hold the frame length. */
873 M_PREPEND(m, sizeof(u_int16_t), M_DONTWAIT);
874 if (m != NULL)
875 m = m_pullup(m, sizeof(u_int16_t)); /* just in case */
876 if (m == NULL) {
877 GET_IFP(sc)->if_oerrors++;
878 return (ENOBUFS);
879 }
880
881 total_len = m->m_pkthdr.len;
882
883 DPRINTFN(10,("%s: %s: total_len=%d\n",
884 USBDEVNAME(sc->cue_dev), __func__, total_len));
885
886 /* The first two bytes are the frame length */
887 USETW(mtod(m, char *), m->m_pkthdr.len - sizeof(u_int16_t));
888
889 ret = usb_ether_map_tx_buffer_mbuf(c, m);
890 if (ret) {
891 m_freem(m);
892 return (ret);
893 }
894
895 /* XXX 10000 */
896 usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_TX],
897 c, NULL /* XXX buf */, total_len, USBD_NO_COPY, 10000, cue_txeof);
898
899 /* Transmit */
900 err = usbd_transfer(c->ue_xfer);
901 if (err != USBD_IN_PROGRESS) {
902 c->ue_mbuf = NULL;
903 m_freem(m);
904 printf("%s: cue_send error=%s\n", USBDEVNAME(sc->cue_dev),
905 usbd_errstr(err));
906 /* Stop the interface from process context. */
907 usb_add_task(sc->cue_udev, &sc->cue_stop_task,
908 USB_TASKQ_DRIVER);
909 return (EIO);
910 }
911
912 sc->cue_cdata.cue_tx_cnt++;
913
914 return (0);
915 }
916
917 Static void
918 cue_start(struct ifnet *ifp)
919 {
920 struct cue_softc *sc = ifp->if_softc;
921 struct mbuf *m_head = NULL;
922
923 if (sc->cue_dying)
924 return;
925
926 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__));
927
928 if (ifp->if_flags & IFF_OACTIVE)
929 return;
930
931 IFQ_POLL(&ifp->if_snd, m_head);
932 if (m_head == NULL)
933 return;
934
935 IFQ_DEQUEUE(&ifp->if_snd, m_head);
936
937 #if NBPFILTER > 0
938 /*
939 * If there's a BPF listener, bounce a copy of this frame
940 * to him.
941 */
942 if (ifp->if_bpf)
943 BPF_MTAP(ifp, m_head);
944 #endif
945
946 if (cue_send(sc, m_head, 0)) {
947 ifp->if_flags |= IFF_OACTIVE;
948 return;
949 }
950
951 ifp->if_flags |= IFF_OACTIVE;
952
953 /*
954 * Set a timeout in case the chip goes out to lunch.
955 */
956 ifp->if_timer = 5;
957 }
958
959 Static int
960 cue_init(struct ifnet *ifp)
961 {
962 struct cue_softc *sc = ifp->if_softc;
963 int i, s, ctl;
964 u_char *eaddr;
965 struct ue_chain *c;
966
967 if (sc->cue_dying)
968 return (EIO);
969
970 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__));
971
972 if (ifp->if_flags & IFF_RUNNING)
973 return (EIO);
974
975 s = splnet();
976
977 /*
978 * Cancel pending I/O and free all RX/TX buffers.
979 */
980 #if 1
981 cue_reset(sc);
982 #endif
983
984 /* Set advanced operation modes. */
985 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
986 CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */
987
988 #if defined(__OpenBSD__)
989 eaddr = sc->arpcom.ac_enaddr;
990 #elif defined(__NetBSD__)
991 eaddr = LLADDR(ifp->if_sadl);
992 #endif
993 /* Set MAC address */
994 for (i = 0; i < ETHER_ADDR_LEN; i++)
995 cue_csr_write_1(sc, CUE_PAR0 - i, eaddr[i]);
996
997 /* Enable RX logic. */
998 ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON;
999 if (ifp->if_flags & IFF_PROMISC)
1000 ctl |= CUE_ETHCTL_PROMISC;
1001 cue_csr_write_1(sc, CUE_ETHCTL, ctl);
1002
1003 /* Load the multicast filter. */
1004 cue_setmulti(sc);
1005
1006 /*
1007 * Set the number of RX and TX buffers that we want
1008 * to reserve inside the ASIC.
1009 */
1010 cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
1011 cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
1012
1013 /* Set advanced operation modes. */
1014 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
1015 CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */
1016
1017 /* Program the LED operation. */
1018 cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
1019
1020 if (sc->cue_ep[CUE_ENDPT_RX] == NULL) {
1021 if (cue_open_pipes(sc)) {
1022 splx(s);
1023 return (EIO);
1024 }
1025 }
1026
1027 /* Init TX ring. */
1028 if ((i = usb_ether_tx_list_init(USBDEV(sc->cue_dev),
1029 sc->cue_cdata.cue_tx_chain, CUE_TX_LIST_CNT,
1030 sc->cue_udev, sc->cue_ep[CUE_ENDPT_TX], NULL))) {
1031 printf("%s: tx list init failed\n", USBDEVNAME(sc->cue_dev));
1032 splx(s);
1033 return (i);
1034 }
1035
1036 /* Init RX ring. */
1037 if ((i = usb_ether_rx_list_init(USBDEV(sc->cue_dev),
1038 sc->cue_cdata.cue_rx_chain, CUE_RX_LIST_CNT,
1039 sc->cue_udev, sc->cue_ep[CUE_ENDPT_RX]))) {
1040 printf("%s: rx list init failed\n", USBDEVNAME(sc->cue_dev));
1041 splx(s);
1042 return (i);
1043 }
1044
1045 /* Start up the receive pipe. */
1046 for (i = 0; i < CUE_RX_LIST_CNT; i++) {
1047 c = &sc->cue_cdata.cue_rx_chain[i];
1048 (void)usbd_map_buffer_mbuf(c->ue_xfer, c->ue_mbuf);
1049 usbd_setup_xfer(c->ue_xfer, sc->cue_ep[CUE_ENDPT_RX],
1050 c, NULL /* XXX buf */, CUE_BUFSZ,
1051 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1052 cue_rxeof);
1053 usbd_transfer(c->ue_xfer);
1054 }
1055
1056 ifp->if_flags |= IFF_RUNNING;
1057 ifp->if_flags &= ~IFF_OACTIVE;
1058
1059 splx(s);
1060
1061 usb_callout(sc->cue_stat_ch, hz, cue_tick, sc);
1062
1063 return (0);
1064 }
1065
1066 Static int
1067 cue_open_pipes(struct cue_softc *sc)
1068 {
1069 usbd_status err;
1070
1071 /* Open RX and TX pipes. */
1072 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX],
1073 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]);
1074 if (err) {
1075 printf("%s: open rx pipe failed: %s\n",
1076 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1077 return (EIO);
1078 }
1079 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX],
1080 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]);
1081 if (err) {
1082 printf("%s: open tx pipe failed: %s\n",
1083 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1084 return (EIO);
1085 }
1086
1087 return (0);
1088 }
1089
1090 Static int
1091 cue_ioctl(struct ifnet *ifp, u_long command, usb_ioctlarg_t data)
1092 {
1093 struct cue_softc *sc = ifp->if_softc;
1094 #if 0
1095 struct ifaddr *ifa = (struct ifaddr *)data;
1096 struct ifreq *ifr = (struct ifreq *)data;
1097 #endif
1098 int s, error = 0;
1099
1100 if (sc->cue_dying)
1101 return (EIO);
1102
1103 s = splnet();
1104
1105 switch(command) {
1106 #if 0
1107 case SIOCSIFADDR:
1108 ifp->if_flags |= IFF_UP;
1109 cue_init(ifp);
1110
1111 switch (ifa->ifa_addr->sa_family) {
1112 #ifdef INET
1113 case AF_INET:
1114 #if defined(__NetBSD__)
1115 arp_ifinit(ifp, ifa);
1116 #else
1117 arp_ifinit(&sc->arpcom, ifa);
1118 #endif
1119 break;
1120 #endif /* INET */
1121 }
1122 break;
1123
1124 case SIOCSIFMTU:
1125 if (ifr->ifr_mtu > ETHERMTU)
1126 error = EINVAL;
1127 else
1128 ifp->if_mtu = ifr->ifr_mtu;
1129 break;
1130 #endif
1131
1132 case SIOCSIFFLAGS:
1133 if (ifp->if_flags & IFF_UP) {
1134 if (ifp->if_flags & IFF_RUNNING &&
1135 ifp->if_flags & IFF_PROMISC &&
1136 !(sc->cue_if_flags & IFF_PROMISC)) {
1137 CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1138 cue_setmulti(sc);
1139 } else if (ifp->if_flags & IFF_RUNNING &&
1140 !(ifp->if_flags & IFF_PROMISC) &&
1141 sc->cue_if_flags & IFF_PROMISC) {
1142 CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1143 cue_setmulti(sc);
1144 } else if (!(ifp->if_flags & IFF_RUNNING))
1145 cue_init(ifp);
1146 } else {
1147 if (ifp->if_flags & IFF_RUNNING)
1148 cue_stop(ifp, 0);
1149 }
1150 sc->cue_if_flags = ifp->if_flags;
1151 error = 0;
1152 break;
1153 #if 0
1154 case SIOCADDMULTI:
1155 case SIOCDELMULTI:
1156 cue_setmulti(sc);
1157 error = 0;
1158 break;
1159 #endif
1160 default:
1161 error = ether_ioctl(ifp, command, data);
1162 if (error == ENETRESET) {
1163 /*
1164 * Multicast list has changed; set the hardware
1165 * filter accordingly.
1166 */
1167 if (ifp->if_flags & IFF_RUNNING)
1168 cue_setmulti(sc);
1169 error = 0;
1170 }
1171 break;
1172 }
1173
1174 splx(s);
1175
1176 return (error);
1177 }
1178
1179 Static void
1180 cue_watchdog(struct ifnet *ifp)
1181 {
1182 struct cue_softc *sc = ifp->if_softc;
1183 struct ue_chain *c;
1184 usbd_status stat;
1185 int s;
1186
1187 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__));
1188
1189 if (sc->cue_dying)
1190 return;
1191
1192 ifp->if_oerrors++;
1193 printf("%s: watchdog timeout\n", USBDEVNAME(sc->cue_dev));
1194
1195 s = splusb();
1196 c = &sc->cue_cdata.cue_tx_chain[0];
1197 usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
1198 cue_txeof(c->ue_xfer, c, stat);
1199
1200 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1201 cue_start(ifp);
1202 splx(s);
1203 }
1204
1205 /*
1206 * Stop the adapter and free any mbufs allocated to the
1207 * RX and TX lists.
1208 */
1209 Static void
1210 cue_stop(struct ifnet *ifp, int disable)
1211 {
1212 struct cue_softc *sc = ifp->if_softc;
1213 usbd_status err;
1214
1215 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__));
1216
1217 ifp = GET_IFP(sc);
1218 ifp->if_timer = 0;
1219
1220 cue_csr_write_1(sc, CUE_ETHCTL, 0);
1221 cue_reset(sc);
1222 usb_uncallout(sc->cue_stat_ch, cue_tick, sc);
1223
1224 /* Stop transfers. */
1225 if (sc->cue_ep[CUE_ENDPT_RX] != NULL) {
1226 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1227 if (err) {
1228 printf("%s: abort rx pipe failed: %s\n",
1229 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1230 }
1231 }
1232
1233 if (sc->cue_ep[CUE_ENDPT_TX] != NULL) {
1234 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1235 if (err) {
1236 printf("%s: abort tx pipe failed: %s\n",
1237 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1238 }
1239 }
1240
1241 if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) {
1242 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1243 if (err) {
1244 printf("%s: abort intr pipe failed: %s\n",
1245 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1246 }
1247 }
1248
1249 /* Free RX/TX resources. */
1250 usb_ether_rx_list_free(sc->cue_cdata.cue_rx_chain, CUE_RX_LIST_CNT);
1251 usb_ether_tx_list_free(sc->cue_cdata.cue_tx_chain, CUE_TX_LIST_CNT);
1252
1253 /* Close pipes. */
1254 if (sc->cue_ep[CUE_ENDPT_RX] != NULL) {
1255 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1256 if (err) {
1257 printf("%s: close rx pipe failed: %s\n",
1258 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1259 }
1260 sc->cue_ep[CUE_ENDPT_RX] = NULL;
1261 }
1262 if (sc->cue_ep[CUE_ENDPT_TX] != NULL) {
1263 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1264 if (err) {
1265 printf("%s: close tx pipe failed: %s\n",
1266 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1267 }
1268 sc->cue_ep[CUE_ENDPT_TX] = NULL;
1269 }
1270 if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) {
1271 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1272 if (err) {
1273 printf("%s: close intr pipe failed: %s\n",
1274 USBDEVNAME(sc->cue_dev), usbd_errstr(err));
1275 }
1276 sc->cue_ep[CUE_ENDPT_INTR] = NULL;
1277 }
1278
1279 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1280 }
1281