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