1 /* $NetBSD: if_cue.c,v 1.55 2009/09/23 19:07:19 plunky Exp $ */
3 * Copyright (c) 1997, 1998, 1999, 2000
4 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
33 * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $
37 * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate
38 * adapters and others.
40 * Written by Bill Paul <wpaul@ee.columbia.edu>
41 * Electrical Engineering Department
42 * Columbia University, New York City
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.
55 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
58 #include <sys/cdefs.h>
59 __KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.55 2009/09/23 19:07:19 plunky Exp $");
61 #if defined(__NetBSD__)
65 #elif defined(__OpenBSD__)
67 #endif /* defined(__OpenBSD__) */
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #if !defined(__OpenBSD__)
72 #include <sys/callout.h>
74 #include <sys/sockio.h>
76 #include <sys/malloc.h>
77 #include <sys/kernel.h>
78 #include <sys/socket.h>
80 #include <sys/device.h>
86 #if defined(__NetBSD__)
87 #include <net/if_arp.h>
89 #include <net/if_dl.h>
91 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
97 #if defined(__NetBSD__)
98 #include <net/if_ether.h>
100 #include <netinet/in.h>
101 #include <netinet/if_inarp.h>
103 #endif /* defined(__NetBSD__) */
105 #if defined(__OpenBSD__)
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>
113 #endif /* defined(__OpenBSD__) */
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>
121 #include <dev/usb/if_cuereg.h>
124 #define DPRINTF(x) if (cuedebug) logprintf x
125 #define DPRINTFN(n,x) if (cuedebug >= (n)) logprintf x
129 #define DPRINTFN(n,x)
133 * Various supported device vendors/products.
135 Static
struct usb_devno cue_devs
[] = {
136 { USB_VENDOR_CATC
, USB_PRODUCT_CATC_NETMATE
},
137 { USB_VENDOR_CATC
, USB_PRODUCT_CATC_NETMATE2
},
138 { USB_VENDOR_SMARTBRIDGES
, USB_PRODUCT_SMARTBRIDGES_SMARTLINK
},
139 /* Belkin F5U111 adapter covered by NETMATE entry */
141 #define cue_lookup(v, p) (usb_lookup(cue_devs, v, p))
143 USB_DECLARE_DRIVER(cue
);
145 Static
int cue_open_pipes(struct cue_softc
*);
146 Static
int cue_tx_list_init(struct cue_softc
*);
147 Static
int cue_rx_list_init(struct cue_softc
*);
148 Static
int cue_newbuf(struct cue_softc
*, struct cue_chain
*, struct mbuf
*);
149 Static
int cue_send(struct cue_softc
*, struct mbuf
*, int);
150 Static
void cue_rxeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
151 Static
void cue_txeof(usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
152 Static
void cue_tick(void *);
153 Static
void cue_tick_task(void *);
154 Static
void cue_start(struct ifnet
*);
155 Static
int cue_ioctl(struct ifnet
*, u_long
, void *);
156 Static
void cue_init(void *);
157 Static
void cue_stop(struct cue_softc
*);
158 Static
void cue_watchdog(struct ifnet
*);
160 Static
void cue_setmulti(struct cue_softc
*);
161 Static u_int32_t
cue_crc(const char *);
162 Static
void cue_reset(struct cue_softc
*);
164 Static
int cue_csr_read_1(struct cue_softc
*, int);
165 Static
int cue_csr_write_1(struct cue_softc
*, int, int);
166 Static
int cue_csr_read_2(struct cue_softc
*, int);
168 Static
int cue_csr_write_2(struct cue_softc
*, int, int);
170 Static
int cue_mem(struct cue_softc
*, int, int, void *, int);
171 Static
int cue_getmac(struct cue_softc
*, void *);
173 #define CUE_SETBIT(sc, reg, x) \
174 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
176 #define CUE_CLRBIT(sc, reg, x) \
177 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
180 cue_csr_read_1(struct cue_softc
*sc
, int reg
)
182 usb_device_request_t req
;
189 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
190 req
.bRequest
= CUE_CMD_READREG
;
191 USETW(req
.wValue
, 0);
192 USETW(req
.wIndex
, reg
);
193 USETW(req
.wLength
, 1);
195 err
= usbd_do_request(sc
->cue_udev
, &req
, &val
);
198 DPRINTF(("%s: cue_csr_read_1: reg=0x%x err=%s\n",
199 USBDEVNAME(sc
->cue_dev
), reg
, usbd_errstr(err
)));
203 DPRINTFN(10,("%s: cue_csr_read_1 reg=0x%x val=0x%x\n",
204 USBDEVNAME(sc
->cue_dev
), reg
, val
));
210 cue_csr_read_2(struct cue_softc
*sc
, int reg
)
212 usb_device_request_t req
;
219 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
220 req
.bRequest
= CUE_CMD_READREG
;
221 USETW(req
.wValue
, 0);
222 USETW(req
.wIndex
, reg
);
223 USETW(req
.wLength
, 2);
225 err
= usbd_do_request(sc
->cue_udev
, &req
, &val
);
227 DPRINTFN(10,("%s: cue_csr_read_2 reg=0x%x val=0x%x\n",
228 USBDEVNAME(sc
->cue_dev
), reg
, UGETW(val
)));
231 DPRINTF(("%s: cue_csr_read_2: reg=0x%x err=%s\n",
232 USBDEVNAME(sc
->cue_dev
), reg
, usbd_errstr(err
)));
240 cue_csr_write_1(struct cue_softc
*sc
, int reg
, int val
)
242 usb_device_request_t req
;
248 DPRINTFN(10,("%s: cue_csr_write_1 reg=0x%x val=0x%x\n",
249 USBDEVNAME(sc
->cue_dev
), reg
, val
));
251 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
252 req
.bRequest
= CUE_CMD_WRITEREG
;
253 USETW(req
.wValue
, val
);
254 USETW(req
.wIndex
, reg
);
255 USETW(req
.wLength
, 0);
257 err
= usbd_do_request(sc
->cue_udev
, &req
, NULL
);
260 DPRINTF(("%s: cue_csr_write_1: reg=0x%x err=%s\n",
261 USBDEVNAME(sc
->cue_dev
), reg
, usbd_errstr(err
)));
265 DPRINTFN(20,("%s: cue_csr_write_1, after reg=0x%x val=0x%x\n",
266 USBDEVNAME(sc
->cue_dev
), reg
, cue_csr_read_1(sc
, reg
)));
273 cue_csr_write_2(struct cue_softc
*sc
, int reg
, int aval
)
275 usb_device_request_t req
;
283 DPRINTFN(10,("%s: cue_csr_write_2 reg=0x%x val=0x%x\n",
284 USBDEVNAME(sc
->cue_dev
), reg
, aval
));
287 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
288 req
.bRequest
= CUE_CMD_WRITEREG
;
289 USETW(req
.wValue
, val
);
290 USETW(req
.wIndex
, reg
);
291 USETW(req
.wLength
, 0);
293 err
= usbd_do_request(sc
->cue_udev
, &req
, NULL
);
296 DPRINTF(("%s: cue_csr_write_2: reg=0x%x err=%s\n",
297 USBDEVNAME(sc
->cue_dev
), reg
, usbd_errstr(err
)));
306 cue_mem(struct cue_softc
*sc
, int cmd
, int addr
, void *buf
, int len
)
308 usb_device_request_t req
;
311 DPRINTFN(10,("%s: cue_mem cmd=0x%x addr=0x%x len=%d\n",
312 USBDEVNAME(sc
->cue_dev
), cmd
, addr
, len
));
314 if (cmd
== CUE_CMD_READSRAM
)
315 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
317 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
319 USETW(req
.wValue
, 0);
320 USETW(req
.wIndex
, addr
);
321 USETW(req
.wLength
, len
);
323 err
= usbd_do_request(sc
->cue_udev
, &req
, buf
);
326 DPRINTF(("%s: cue_csr_mem: addr=0x%x err=%s\n",
327 USBDEVNAME(sc
->cue_dev
), addr
, usbd_errstr(err
)));
335 cue_getmac(struct cue_softc
*sc
, void *buf
)
337 usb_device_request_t req
;
340 DPRINTFN(10,("%s: cue_getmac\n", USBDEVNAME(sc
->cue_dev
)));
342 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
343 req
.bRequest
= CUE_CMD_GET_MACADDR
;
344 USETW(req
.wValue
, 0);
345 USETW(req
.wIndex
, 0);
346 USETW(req
.wLength
, ETHER_ADDR_LEN
);
348 err
= usbd_do_request(sc
->cue_udev
, &req
, buf
);
351 printf("%s: read MAC address failed\n",USBDEVNAME(sc
->cue_dev
));
358 #define CUE_POLY 0xEDB88320
362 cue_crc(const char *addr
)
364 u_int32_t idx
, bit
, data
, crc
;
366 /* Compute CRC for the address value. */
367 crc
= 0xFFFFFFFF; /* initial value */
369 for (idx
= 0; idx
< 6; idx
++) {
370 for (data
= *addr
++, bit
= 0; bit
< 8; bit
++, data
>>= 1)
371 crc
= (crc
>> 1) ^ (((crc
^ data
) & 1) ? CUE_POLY
: 0);
374 return (crc
& ((1 << CUE_BITS
) - 1));
378 cue_setmulti(struct cue_softc
*sc
)
381 struct ether_multi
*enm
;
382 struct ether_multistep step
;
387 DPRINTFN(2,("%s: cue_setmulti if_flags=0x%x\n",
388 USBDEVNAME(sc
->cue_dev
), ifp
->if_flags
));
390 if (ifp
->if_flags
& IFF_PROMISC
) {
392 ifp
->if_flags
|= IFF_ALLMULTI
;
393 for (i
= 0; i
< CUE_MCAST_TABLE_LEN
; i
++)
394 sc
->cue_mctab
[i
] = 0xFF;
395 cue_mem(sc
, CUE_CMD_WRITESRAM
, CUE_MCAST_TABLE_ADDR
,
396 &sc
->cue_mctab
, CUE_MCAST_TABLE_LEN
);
400 /* first, zot all the existing hash bits */
401 for (i
= 0; i
< CUE_MCAST_TABLE_LEN
; i
++)
402 sc
->cue_mctab
[i
] = 0;
404 /* now program new ones */
405 #if defined(__NetBSD__)
406 ETHER_FIRST_MULTI(step
, &sc
->cue_ec
, enm
);
408 ETHER_FIRST_MULTI(step
, &sc
->arpcom
, enm
);
410 while (enm
!= NULL
) {
411 if (memcmp(enm
->enm_addrlo
,
412 enm
->enm_addrhi
, ETHER_ADDR_LEN
) != 0)
415 h
= cue_crc(enm
->enm_addrlo
);
416 sc
->cue_mctab
[h
>> 3] |= 1 << (h
& 0x7);
417 ETHER_NEXT_MULTI(step
, enm
);
420 ifp
->if_flags
&= ~IFF_ALLMULTI
;
423 * Also include the broadcast address in the filter
424 * so we can receive broadcast frames.
426 if (ifp
->if_flags
& IFF_BROADCAST
) {
427 h
= cue_crc(etherbroadcastaddr
);
428 sc
->cue_mctab
[h
>> 3] |= 1 << (h
& 0x7);
431 cue_mem(sc
, CUE_CMD_WRITESRAM
, CUE_MCAST_TABLE_ADDR
,
432 &sc
->cue_mctab
, CUE_MCAST_TABLE_LEN
);
436 cue_reset(struct cue_softc
*sc
)
438 usb_device_request_t req
;
441 DPRINTFN(2,("%s: cue_reset\n", USBDEVNAME(sc
->cue_dev
)));
446 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
447 req
.bRequest
= CUE_CMD_RESET
;
448 USETW(req
.wValue
, 0);
449 USETW(req
.wIndex
, 0);
450 USETW(req
.wLength
, 0);
452 err
= usbd_do_request(sc
->cue_udev
, &req
, NULL
);
455 printf("%s: reset failed\n", USBDEVNAME(sc
->cue_dev
));
457 /* Wait a little while for the chip to get its brains in order. */
458 usbd_delay_ms(sc
->cue_udev
, 1);
462 * Probe for a CATC chip.
466 USB_MATCH_START(cue
, uaa
);
468 return (cue_lookup(uaa
->vendor
, uaa
->product
) != NULL
?
469 UMATCH_VENDOR_PRODUCT
: UMATCH_NONE
);
473 * Attach the interface. Allocate softc structures, do ifmedia
474 * setup and ethernet/BPF attach.
478 USB_ATTACH_START(cue
, sc
, uaa
);
481 u_char eaddr
[ETHER_ADDR_LEN
];
482 usbd_device_handle dev
= uaa
->device
;
483 usbd_interface_handle iface
;
486 usb_interface_descriptor_t
*id
;
487 usb_endpoint_descriptor_t
*ed
;
490 DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc
, dev
));
497 devinfop
= usbd_devinfo_alloc(dev
, 0);
498 aprint_normal_dev(self
, "%s\n", devinfop
);
499 usbd_devinfo_free(devinfop
);
501 err
= usbd_set_config_no(dev
, CUE_CONFIG_NO
, 1);
503 aprint_error_dev(self
, "setting config no failed\n");
504 USB_ATTACH_ERROR_RETURN
;
508 sc
->cue_product
= uaa
->product
;
509 sc
->cue_vendor
= uaa
->vendor
;
511 usb_init_task(&sc
->cue_tick_task
, cue_tick_task
, sc
);
512 usb_init_task(&sc
->cue_stop_task
, (void (*)(void *))cue_stop
, sc
);
514 err
= usbd_device2interface_handle(dev
, CUE_IFACE_IDX
, &iface
);
516 aprint_error_dev(self
, "getting interface handle failed\n");
517 USB_ATTACH_ERROR_RETURN
;
520 sc
->cue_iface
= iface
;
521 id
= usbd_get_interface_descriptor(iface
);
523 /* Find endpoints. */
524 for (i
= 0; i
< id
->bNumEndpoints
; i
++) {
525 ed
= usbd_interface2endpoint_descriptor(iface
, i
);
527 aprint_error_dev(self
, "couldn't get ep %d\n", i
);
528 USB_ATTACH_ERROR_RETURN
;
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
;
543 /* Reset the adapter. */
547 * Get station address.
549 cue_getmac(sc
, &eaddr
);
554 * A CATC chip was detected. Inform the world.
556 aprint_normal_dev(self
, "Ethernet address %s\n", ether_sprintf(eaddr
));
558 /* Initialize interface info.*/
561 ifp
->if_mtu
= ETHERMTU
;
562 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
563 ifp
->if_ioctl
= cue_ioctl
;
564 ifp
->if_start
= cue_start
;
565 ifp
->if_watchdog
= cue_watchdog
;
566 #if defined(__OpenBSD__)
567 ifp
->if_snd
.ifq_maxlen
= IFQ_MAXLEN
;
569 strncpy(ifp
->if_xname
, USBDEVNAME(sc
->cue_dev
), IFNAMSIZ
);
571 IFQ_SET_READY(&ifp
->if_snd
);
573 /* Attach the interface. */
575 Ether_ifattach(ifp
, eaddr
);
577 rnd_attach_source(&sc
->rnd_source
, USBDEVNAME(sc
->cue_dev
),
581 usb_callout_init(sc
->cue_stat_ch
);
583 sc
->cue_attached
= 1;
586 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, sc
->cue_udev
,
587 USBDEV(sc
->cue_dev
));
589 USB_ATTACH_SUCCESS_RETURN
;
594 USB_DETACH_START(cue
, sc
);
595 struct ifnet
*ifp
= GET_IFP(sc
);
598 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
), __func__
));
600 usb_uncallout(sc
->cue_stat_ch
, cue_tick
, sc
);
602 * Remove any pending task. It cannot be executing because it run
603 * in the same thread as detach.
605 usb_rem_task(sc
->cue_udev
, &sc
->cue_tick_task
);
606 usb_rem_task(sc
->cue_udev
, &sc
->cue_stop_task
);
608 if (!sc
->cue_attached
) {
609 /* Detached before attached finished, so just bail out. */
615 if (ifp
->if_flags
& IFF_RUNNING
)
618 #if defined(__NetBSD__)
620 rnd_detach_source(&sc
->rnd_source
);
623 #endif /* __NetBSD__ */
628 if (sc
->cue_ep
[CUE_ENDPT_TX
] != NULL
||
629 sc
->cue_ep
[CUE_ENDPT_RX
] != NULL
||
630 sc
->cue_ep
[CUE_ENDPT_INTR
] != NULL
)
631 aprint_debug_dev(self
, "detach has active endpoints\n");
634 sc
->cue_attached
= 0;
637 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->cue_udev
,
638 USBDEV(sc
->cue_dev
));
644 cue_activate(device_ptr_t self
, enum devact act
)
646 struct cue_softc
*sc
= device_private(self
);
648 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
), __func__
));
651 case DVACT_DEACTIVATE
:
652 /* Deactivate the interface. */
653 if_deactivate(&sc
->cue_ec
.ec_if
);
662 * Initialize an RX descriptor and attach an MBUF cluster.
665 cue_newbuf(struct cue_softc
*sc
, struct cue_chain
*c
, struct mbuf
*m
)
667 struct mbuf
*m_new
= NULL
;
670 MGETHDR(m_new
, M_DONTWAIT
, MT_DATA
);
672 printf("%s: no memory for rx list "
673 "-- packet dropped!\n", USBDEVNAME(sc
->cue_dev
));
677 MCLGET(m_new
, M_DONTWAIT
);
678 if (!(m_new
->m_flags
& M_EXT
)) {
679 printf("%s: no memory for rx list "
680 "-- packet dropped!\n", USBDEVNAME(sc
->cue_dev
));
684 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
687 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
688 m_new
->m_data
= m_new
->m_ext
.ext_buf
;
691 m_adj(m_new
, ETHER_ALIGN
);
698 cue_rx_list_init(struct cue_softc
*sc
)
700 struct cue_cdata
*cd
;
705 for (i
= 0; i
< CUE_RX_LIST_CNT
; i
++) {
706 c
= &cd
->cue_rx_chain
[i
];
709 if (cue_newbuf(sc
, c
, NULL
) == ENOBUFS
)
711 if (c
->cue_xfer
== NULL
) {
712 c
->cue_xfer
= usbd_alloc_xfer(sc
->cue_udev
);
713 if (c
->cue_xfer
== NULL
)
715 c
->cue_buf
= usbd_alloc_buffer(c
->cue_xfer
, CUE_BUFSZ
);
716 if (c
->cue_buf
== NULL
) {
717 usbd_free_xfer(c
->cue_xfer
);
727 cue_tx_list_init(struct cue_softc
*sc
)
729 struct cue_cdata
*cd
;
734 for (i
= 0; i
< CUE_TX_LIST_CNT
; i
++) {
735 c
= &cd
->cue_tx_chain
[i
];
739 if (c
->cue_xfer
== NULL
) {
740 c
->cue_xfer
= usbd_alloc_xfer(sc
->cue_udev
);
741 if (c
->cue_xfer
== NULL
)
743 c
->cue_buf
= usbd_alloc_buffer(c
->cue_xfer
, CUE_BUFSZ
);
744 if (c
->cue_buf
== NULL
) {
745 usbd_free_xfer(c
->cue_xfer
);
755 * A frame has been uploaded: pass the resulting mbuf chain up to
756 * the higher level protocols.
759 cue_rxeof(usbd_xfer_handle xfer
, usbd_private_handle priv
, usbd_status status
)
761 struct cue_chain
*c
= priv
;
762 struct cue_softc
*sc
= c
->cue_sc
;
763 struct ifnet
*ifp
= GET_IFP(sc
);
769 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc
->cue_dev
),
775 if (!(ifp
->if_flags
& IFF_RUNNING
))
778 if (status
!= USBD_NORMAL_COMPLETION
) {
779 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
)
782 if (usbd_ratecheck(&sc
->cue_rx_notice
)) {
783 printf("%s: %u usb errors on rx: %s\n",
784 USBDEVNAME(sc
->cue_dev
), sc
->cue_rx_errs
,
785 usbd_errstr(status
));
788 if (status
== USBD_STALLED
)
789 usbd_clear_endpoint_stall_async(sc
->cue_ep
[CUE_ENDPT_RX
]);
793 usbd_get_xfer_status(xfer
, NULL
, NULL
, &total_len
, NULL
);
795 memcpy(mtod(c
->cue_mbuf
, char *), c
->cue_buf
, total_len
);
798 len
= UGETW(mtod(m
, u_int8_t
*));
800 /* No errors; receive the packet. */
803 if (len
< sizeof(struct ether_header
)) {
809 m_adj(m
, sizeof(u_int16_t
));
810 m
->m_pkthdr
.len
= m
->m_len
= total_len
;
812 m
->m_pkthdr
.rcvif
= ifp
;
817 if (cue_newbuf(sc
, c
, NULL
) == ENOBUFS
) {
824 * Handle BPF listeners. Let the BPF user see the packet, but
825 * don't pass it up to the ether_input() layer unless it's
826 * a broadcast packet, multicast packet, matches our ethernet
827 * address or the interface is in promiscuous mode.
833 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc
->cue_dev
),
834 __func__
, m
->m_len
));
840 /* Setup new transfer. */
841 usbd_setup_xfer(c
->cue_xfer
, sc
->cue_ep
[CUE_ENDPT_RX
],
842 c
, c
->cue_buf
, CUE_BUFSZ
, USBD_SHORT_XFER_OK
| USBD_NO_COPY
,
843 USBD_NO_TIMEOUT
, cue_rxeof
);
844 usbd_transfer(c
->cue_xfer
);
846 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc
->cue_dev
),
851 * A frame was downloaded to the chip. It's safe for us to clean up
855 cue_txeof(usbd_xfer_handle xfer
, usbd_private_handle priv
,
858 struct cue_chain
*c
= priv
;
859 struct cue_softc
*sc
= c
->cue_sc
;
860 struct ifnet
*ifp
= GET_IFP(sc
);
868 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc
->cue_dev
),
872 ifp
->if_flags
&= ~IFF_OACTIVE
;
874 if (status
!= USBD_NORMAL_COMPLETION
) {
875 if (status
== USBD_NOT_STARTED
|| status
== USBD_CANCELLED
) {
880 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc
->cue_dev
),
881 usbd_errstr(status
));
882 if (status
== USBD_STALLED
)
883 usbd_clear_endpoint_stall_async(sc
->cue_ep
[CUE_ENDPT_TX
]);
890 m_freem(c
->cue_mbuf
);
893 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
902 struct cue_softc
*sc
= xsc
;
910 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
), __func__
));
912 /* Perform statistics update in process context. */
913 usb_add_task(sc
->cue_udev
, &sc
->cue_tick_task
, USB_TASKQ_DRIVER
);
917 cue_tick_task(void *xsc
)
919 struct cue_softc
*sc
= xsc
;
925 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
), __func__
));
929 ifp
->if_collisions
+= cue_csr_read_2(sc
, CUE_TX_SINGLECOLL
);
930 ifp
->if_collisions
+= cue_csr_read_2(sc
, CUE_TX_MULTICOLL
);
931 ifp
->if_collisions
+= cue_csr_read_2(sc
, CUE_TX_EXCESSCOLL
);
933 if (cue_csr_read_2(sc
, CUE_RX_FRAMEERR
))
938 cue_send(struct cue_softc
*sc
, struct mbuf
*m
, int idx
)
944 c
= &sc
->cue_cdata
.cue_tx_chain
[idx
];
947 * Copy the mbuf data into a contiguous buffer, leaving two
948 * bytes at the beginning to hold the frame length.
950 m_copydata(m
, 0, m
->m_pkthdr
.len
, c
->cue_buf
+ 2);
953 total_len
= m
->m_pkthdr
.len
+ 2;
955 DPRINTFN(10,("%s: %s: total_len=%d\n",
956 USBDEVNAME(sc
->cue_dev
), __func__
, total_len
));
958 /* The first two bytes are the frame length */
959 c
->cue_buf
[0] = (u_int8_t
)m
->m_pkthdr
.len
;
960 c
->cue_buf
[1] = (u_int8_t
)(m
->m_pkthdr
.len
>> 8);
963 usbd_setup_xfer(c
->cue_xfer
, sc
->cue_ep
[CUE_ENDPT_TX
],
964 c
, c
->cue_buf
, total_len
, USBD_NO_COPY
, 10000, cue_txeof
);
967 err
= usbd_transfer(c
->cue_xfer
);
968 if (err
!= USBD_IN_PROGRESS
) {
969 printf("%s: cue_send error=%s\n", USBDEVNAME(sc
->cue_dev
),
971 /* Stop the interface from process context. */
972 usb_add_task(sc
->cue_udev
, &sc
->cue_stop_task
,
977 sc
->cue_cdata
.cue_tx_cnt
++;
983 cue_start(struct ifnet
*ifp
)
985 struct cue_softc
*sc
= ifp
->if_softc
;
986 struct mbuf
*m_head
= NULL
;
991 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
),__func__
));
993 if (ifp
->if_flags
& IFF_OACTIVE
)
996 IFQ_POLL(&ifp
->if_snd
, m_head
);
1000 if (cue_send(sc
, m_head
, 0)) {
1001 ifp
->if_flags
|= IFF_OACTIVE
;
1005 IFQ_DEQUEUE(&ifp
->if_snd
, m_head
);
1009 * If there's a BPF listener, bounce a copy of this frame
1013 BPF_MTAP(ifp
, m_head
);
1016 ifp
->if_flags
|= IFF_OACTIVE
;
1019 * Set a timeout in case the chip goes out to lunch.
1027 struct cue_softc
*sc
= xsc
;
1028 struct ifnet
*ifp
= GET_IFP(sc
);
1030 const u_char
*eaddr
;
1035 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
),__func__
));
1037 if (ifp
->if_flags
& IFF_RUNNING
)
1043 * Cancel pending I/O and free all RX/TX buffers.
1049 /* Set advanced operation modes. */
1050 cue_csr_write_1(sc
, CUE_ADVANCED_OPMODES
,
1051 CUE_AOP_EMBED_RXLEN
| 0x03); /* 1 wait state */
1053 #if defined(__OpenBSD__)
1054 eaddr
= sc
->arpcom
.ac_enaddr
;
1055 #elif defined(__NetBSD__)
1056 eaddr
= CLLADDR(ifp
->if_sadl
);
1058 /* Set MAC address */
1059 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++)
1060 cue_csr_write_1(sc
, CUE_PAR0
- i
, eaddr
[i
]);
1062 /* Enable RX logic. */
1063 ctl
= CUE_ETHCTL_RX_ON
| CUE_ETHCTL_MCAST_ON
;
1064 if (ifp
->if_flags
& IFF_PROMISC
)
1065 ctl
|= CUE_ETHCTL_PROMISC
;
1066 cue_csr_write_1(sc
, CUE_ETHCTL
, ctl
);
1069 if (cue_tx_list_init(sc
) == ENOBUFS
) {
1070 printf("%s: tx list init failed\n", USBDEVNAME(sc
->cue_dev
));
1076 if (cue_rx_list_init(sc
) == ENOBUFS
) {
1077 printf("%s: rx list init failed\n", USBDEVNAME(sc
->cue_dev
));
1082 /* Load the multicast filter. */
1086 * Set the number of RX and TX buffers that we want
1087 * to reserve inside the ASIC.
1089 cue_csr_write_1(sc
, CUE_RX_BUFPKTS
, CUE_RX_FRAMES
);
1090 cue_csr_write_1(sc
, CUE_TX_BUFPKTS
, CUE_TX_FRAMES
);
1092 /* Set advanced operation modes. */
1093 cue_csr_write_1(sc
, CUE_ADVANCED_OPMODES
,
1094 CUE_AOP_EMBED_RXLEN
| 0x01); /* 1 wait state */
1096 /* Program the LED operation. */
1097 cue_csr_write_1(sc
, CUE_LEDCTL
, CUE_LEDCTL_FOLLOW_LINK
);
1099 if (sc
->cue_ep
[CUE_ENDPT_RX
] == NULL
) {
1100 if (cue_open_pipes(sc
)) {
1106 ifp
->if_flags
|= IFF_RUNNING
;
1107 ifp
->if_flags
&= ~IFF_OACTIVE
;
1111 usb_callout(sc
->cue_stat_ch
, hz
, cue_tick
, sc
);
1115 cue_open_pipes(struct cue_softc
*sc
)
1117 struct cue_chain
*c
;
1121 /* Open RX and TX pipes. */
1122 err
= usbd_open_pipe(sc
->cue_iface
, sc
->cue_ed
[CUE_ENDPT_RX
],
1123 USBD_EXCLUSIVE_USE
, &sc
->cue_ep
[CUE_ENDPT_RX
]);
1125 printf("%s: open rx pipe failed: %s\n",
1126 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1129 err
= usbd_open_pipe(sc
->cue_iface
, sc
->cue_ed
[CUE_ENDPT_TX
],
1130 USBD_EXCLUSIVE_USE
, &sc
->cue_ep
[CUE_ENDPT_TX
]);
1132 printf("%s: open tx pipe failed: %s\n",
1133 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1137 /* Start up the receive pipe. */
1138 for (i
= 0; i
< CUE_RX_LIST_CNT
; i
++) {
1139 c
= &sc
->cue_cdata
.cue_rx_chain
[i
];
1140 usbd_setup_xfer(c
->cue_xfer
, sc
->cue_ep
[CUE_ENDPT_RX
],
1141 c
, c
->cue_buf
, CUE_BUFSZ
,
1142 USBD_SHORT_XFER_OK
| USBD_NO_COPY
, USBD_NO_TIMEOUT
,
1144 usbd_transfer(c
->cue_xfer
);
1151 cue_ioctl(struct ifnet
*ifp
, u_long command
, void *data
)
1153 struct cue_softc
*sc
= ifp
->if_softc
;
1154 struct ifaddr
*ifa
= (struct ifaddr
*)data
;
1155 struct ifreq
*ifr
= (struct ifreq
*)data
;
1164 case SIOCINITIFADDR
:
1165 ifp
->if_flags
|= IFF_UP
;
1168 switch (ifa
->ifa_addr
->sa_family
) {
1171 #if defined(__NetBSD__)
1172 arp_ifinit(ifp
, ifa
);
1174 arp_ifinit(&sc
->arpcom
, ifa
);
1182 if (ifr
->ifr_mtu
< ETHERMIN
|| ifr
->ifr_mtu
> ETHERMTU
)
1184 else if ((error
= ifioctl_common(ifp
, command
, data
)) == ENETRESET
)
1189 if ((error
= ifioctl_common(ifp
, command
, data
)) != 0)
1191 if (ifp
->if_flags
& IFF_UP
) {
1192 if (ifp
->if_flags
& IFF_RUNNING
&&
1193 ifp
->if_flags
& IFF_PROMISC
&&
1194 !(sc
->cue_if_flags
& IFF_PROMISC
)) {
1195 CUE_SETBIT(sc
, CUE_ETHCTL
, CUE_ETHCTL_PROMISC
);
1197 } else if (ifp
->if_flags
& IFF_RUNNING
&&
1198 !(ifp
->if_flags
& IFF_PROMISC
) &&
1199 sc
->cue_if_flags
& IFF_PROMISC
) {
1200 CUE_CLRBIT(sc
, CUE_ETHCTL
, CUE_ETHCTL_PROMISC
);
1202 } else if (!(ifp
->if_flags
& IFF_RUNNING
))
1205 if (ifp
->if_flags
& IFF_RUNNING
)
1208 sc
->cue_if_flags
= ifp
->if_flags
;
1217 error
= ether_ioctl(ifp
, command
, data
);
1227 cue_watchdog(struct ifnet
*ifp
)
1229 struct cue_softc
*sc
= ifp
->if_softc
;
1230 struct cue_chain
*c
;
1234 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
),__func__
));
1240 printf("%s: watchdog timeout\n", USBDEVNAME(sc
->cue_dev
));
1243 c
= &sc
->cue_cdata
.cue_tx_chain
[0];
1244 usbd_get_xfer_status(c
->cue_xfer
, NULL
, NULL
, NULL
, &stat
);
1245 cue_txeof(c
->cue_xfer
, c
, stat
);
1247 if (IFQ_IS_EMPTY(&ifp
->if_snd
) == 0)
1253 * Stop the adapter and free any mbufs allocated to the
1257 cue_stop(struct cue_softc
*sc
)
1263 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc
->cue_dev
),__func__
));
1268 cue_csr_write_1(sc
, CUE_ETHCTL
, 0);
1270 usb_uncallout(sc
->cue_stat_ch
, cue_tick
, sc
);
1272 /* Stop transfers. */
1273 if (sc
->cue_ep
[CUE_ENDPT_RX
] != NULL
) {
1274 err
= usbd_abort_pipe(sc
->cue_ep
[CUE_ENDPT_RX
]);
1276 printf("%s: abort rx pipe failed: %s\n",
1277 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1279 err
= usbd_close_pipe(sc
->cue_ep
[CUE_ENDPT_RX
]);
1281 printf("%s: close rx pipe failed: %s\n",
1282 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1284 sc
->cue_ep
[CUE_ENDPT_RX
] = NULL
;
1287 if (sc
->cue_ep
[CUE_ENDPT_TX
] != NULL
) {
1288 err
= usbd_abort_pipe(sc
->cue_ep
[CUE_ENDPT_TX
]);
1290 printf("%s: abort tx pipe failed: %s\n",
1291 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1293 err
= usbd_close_pipe(sc
->cue_ep
[CUE_ENDPT_TX
]);
1295 printf("%s: close tx pipe failed: %s\n",
1296 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1298 sc
->cue_ep
[CUE_ENDPT_TX
] = NULL
;
1301 if (sc
->cue_ep
[CUE_ENDPT_INTR
] != NULL
) {
1302 err
= usbd_abort_pipe(sc
->cue_ep
[CUE_ENDPT_INTR
]);
1304 printf("%s: abort intr pipe failed: %s\n",
1305 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1307 err
= usbd_close_pipe(sc
->cue_ep
[CUE_ENDPT_INTR
]);
1309 printf("%s: close intr pipe failed: %s\n",
1310 USBDEVNAME(sc
->cue_dev
), usbd_errstr(err
));
1312 sc
->cue_ep
[CUE_ENDPT_INTR
] = NULL
;
1315 /* Free RX resources. */
1316 for (i
= 0; i
< CUE_RX_LIST_CNT
; i
++) {
1317 if (sc
->cue_cdata
.cue_rx_chain
[i
].cue_mbuf
!= NULL
) {
1318 m_freem(sc
->cue_cdata
.cue_rx_chain
[i
].cue_mbuf
);
1319 sc
->cue_cdata
.cue_rx_chain
[i
].cue_mbuf
= NULL
;
1321 if (sc
->cue_cdata
.cue_rx_chain
[i
].cue_xfer
!= NULL
) {
1322 usbd_free_xfer(sc
->cue_cdata
.cue_rx_chain
[i
].cue_xfer
);
1323 sc
->cue_cdata
.cue_rx_chain
[i
].cue_xfer
= NULL
;
1327 /* Free TX resources. */
1328 for (i
= 0; i
< CUE_TX_LIST_CNT
; i
++) {
1329 if (sc
->cue_cdata
.cue_tx_chain
[i
].cue_mbuf
!= NULL
) {
1330 m_freem(sc
->cue_cdata
.cue_tx_chain
[i
].cue_mbuf
);
1331 sc
->cue_cdata
.cue_tx_chain
[i
].cue_mbuf
= NULL
;
1333 if (sc
->cue_cdata
.cue_tx_chain
[i
].cue_xfer
!= NULL
) {
1334 usbd_free_xfer(sc
->cue_cdata
.cue_tx_chain
[i
].cue_xfer
);
1335 sc
->cue_cdata
.cue_tx_chain
[i
].cue_xfer
= NULL
;
1339 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);