Merge from vendor branch DHCP:
[dragonfly.git] / sys / dev / netif / cue / if_cue.c
1 /*
2  * Copyright (c) 1997, 1998, 1999, 2000
3  *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $FreeBSD: src/sys/dev/usb/if_cue.c,v 1.45 2003/12/08 07:54:14 obrien Exp $
33  * $DragonFly: src/sys/dev/netif/cue/if_cue.c,v 1.15 2004/10/14 18:31:02 dillon Exp $
34  *
35  */
36
37 /*
38  * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate
39  * adapters and others.
40  *
41  * Written by Bill Paul <wpaul@ee.columbia.edu>
42  * Electrical Engineering Department
43  * Columbia University, New York City
44  */
45
46 /*
47  * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The
48  * RX filter uses a 512-bit multicast hash table, single perfect entry
49  * for the station address, and promiscuous mode. Unlike the ADMtek
50  * and KLSI chips, the CATC ASIC supports read and write combining
51  * mode where multiple packets can be transfered using a single bulk
52  * transaction, which helps performance a great deal.
53  */
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/sockio.h>
58 #include <sys/mbuf.h>
59 #include <sys/malloc.h>
60 #include <sys/kernel.h>
61 #include <sys/socket.h>
62
63 #include <net/if.h>
64 #include <net/if_arp.h>
65 #include <net/ethernet.h>
66 #include <net/if_dl.h>
67
68 #include <net/bpf.h>
69
70 #include <sys/bus.h>
71 #include <machine/bus.h>
72 #if defined(__DragonFly__) || __FreeBSD_version < 500000
73 #include <machine/clock.h>
74 #endif
75
76 #include <bus/usb/usb.h>
77 #include <bus/usb/usbdi.h>
78 #include <bus/usb/usbdi_util.h>
79 #include <bus/usb/usbdivar.h>
80 #include <bus/usb/usbdevs.h>
81 #include <bus/usb/usb_ethersubr.h>
82
83 #include "if_cuereg.h"
84
85 /*
86  * Various supported device vendors/products.
87  */
88 Static struct cue_type cue_devs[] = {
89         { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE },
90         { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 },
91         { USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK },
92         { 0, 0 }
93 };
94
95 Static struct usb_qdat cue_qdat;
96
97 Static int cue_match(device_ptr_t);
98 Static int cue_attach(device_ptr_t);
99 Static int cue_detach(device_ptr_t);
100
101 Static int cue_tx_list_init(struct cue_softc *);
102 Static int cue_rx_list_init(struct cue_softc *);
103 Static int cue_newbuf(struct cue_softc *, struct cue_chain *, struct mbuf *);
104 Static int cue_encap(struct cue_softc *, struct mbuf *, int);
105 Static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
106 Static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
107 Static void cue_tick(void *);
108 Static void cue_rxstart(struct ifnet *);
109 Static void cue_start(struct ifnet *);
110 Static int cue_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
111 Static void cue_init(void *);
112 Static void cue_stop(struct cue_softc *);
113 Static void cue_watchdog(struct ifnet *);
114 Static void cue_shutdown(device_ptr_t);
115
116 Static void cue_setmulti(struct cue_softc *);
117 Static uint32_t cue_mchash(const uint8_t *);
118 Static void cue_reset(struct cue_softc *);
119
120 Static int cue_csr_read_1(struct cue_softc *, int);
121 Static int cue_csr_write_1(struct cue_softc *, int, int);
122 Static int cue_csr_read_2(struct cue_softc *, int);
123 #ifdef notdef
124 Static int cue_csr_write_2(struct cue_softc *, int, int);
125 #endif
126 Static int cue_mem(struct cue_softc *, int, int, void *, int);
127 Static int cue_getmac(struct cue_softc *, void *);
128
129 Static device_method_t cue_methods[] = {
130         /* Device interface */
131         DEVMETHOD(device_probe,         cue_match),
132         DEVMETHOD(device_attach,        cue_attach),
133         DEVMETHOD(device_detach,        cue_detach),
134         DEVMETHOD(device_shutdown,      cue_shutdown),
135
136         { 0, 0 }
137 };
138
139 Static driver_t cue_driver = {
140         "cue",
141         cue_methods,
142         sizeof(struct cue_softc)
143 };
144
145 Static devclass_t cue_devclass;
146
147 DECLARE_DUMMY_MODULE(if_cue);
148 DRIVER_MODULE(cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0);
149 MODULE_DEPEND(cue, usb, 1, 1, 1);
150
151 #define CUE_SETBIT(sc, reg, x)                          \
152         cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
153
154 #define CUE_CLRBIT(sc, reg, x)                          \
155         cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
156
157 Static int
158 cue_csr_read_1(struct cue_softc *sc, int reg)
159 {
160         usb_device_request_t    req;
161         usbd_status             err;
162         u_int8_t                val = 0;
163
164         if (sc->cue_dying)
165                 return(0);
166
167         CUE_LOCK(sc);
168
169         req.bmRequestType = UT_READ_VENDOR_DEVICE;
170         req.bRequest = CUE_CMD_READREG;
171         USETW(req.wValue, 0);
172         USETW(req.wIndex, reg);
173         USETW(req.wLength, 1);
174
175         err = usbd_do_request(sc->cue_udev, &req, &val);
176
177         CUE_UNLOCK(sc);
178
179         if (err)
180                 return(0);
181
182         return(val);
183 }
184
185 Static int
186 cue_csr_read_2(struct cue_softc *sc, int reg)
187 {
188         usb_device_request_t    req;
189         usbd_status             err;
190         u_int16_t               val = 0;
191
192         if (sc->cue_dying)
193                 return(0);
194
195         CUE_LOCK(sc);
196
197         req.bmRequestType = UT_READ_VENDOR_DEVICE;
198         req.bRequest = CUE_CMD_READREG;
199         USETW(req.wValue, 0);
200         USETW(req.wIndex, reg);
201         USETW(req.wLength, 2);
202
203         err = usbd_do_request(sc->cue_udev, &req, &val);
204
205         CUE_UNLOCK(sc);
206
207         if (err)
208                 return(0);
209
210         return(val);
211 }
212
213 Static int
214 cue_csr_write_1(struct cue_softc *sc, int reg, int val)
215 {
216         usb_device_request_t    req;
217         usbd_status             err;
218
219         if (sc->cue_dying)
220                 return(0);
221
222         CUE_LOCK(sc);
223
224         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
225         req.bRequest = CUE_CMD_WRITEREG;
226         USETW(req.wValue, val);
227         USETW(req.wIndex, reg);
228         USETW(req.wLength, 0);
229
230         err = usbd_do_request(sc->cue_udev, &req, NULL);
231
232         CUE_UNLOCK(sc);
233
234         if (err)
235                 return(-1);
236
237         return(0);
238 }
239
240 #ifdef notdef
241 Static int
242 cue_csr_write_2(struct cue_softc *sc, int reg, int val)
243 {
244         usb_device_request_t    req;
245         usbd_status             err;
246
247         if (sc->cue_dying)
248                 return(0);
249
250         CUE_LOCK(sc);
251
252         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
253         req.bRequest = CUE_CMD_WRITEREG;
254         USETW(req.wValue, val);
255         USETW(req.wIndex, reg);
256         USETW(req.wLength, 0);
257
258         err = usbd_do_request(sc->cue_udev, &req, NULL);
259
260         CUE_UNLOCK(sc);
261
262         if (err)
263                 return(-1);
264
265         return(0);
266 }
267 #endif
268
269 Static int
270 cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len)
271 {
272         usb_device_request_t    req;
273         usbd_status             err;
274
275         if (sc->cue_dying)
276                 return(0);
277
278         CUE_LOCK(sc);
279
280         if (cmd == CUE_CMD_READSRAM)
281                 req.bmRequestType = UT_READ_VENDOR_DEVICE;
282         else
283                 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
284         req.bRequest = cmd;
285         USETW(req.wValue, 0);
286         USETW(req.wIndex, addr);
287         USETW(req.wLength, len);
288
289         err = usbd_do_request(sc->cue_udev, &req, buf);
290
291         CUE_UNLOCK(sc);
292
293         if (err)
294                 return(-1);
295
296         return(0);
297 }
298
299 Static int
300 cue_getmac(struct cue_softc *sc, void *buf)
301 {
302         usb_device_request_t    req;
303         usbd_status             err;
304
305         if (sc->cue_dying)
306                 return(0);
307
308         CUE_LOCK(sc);
309
310         req.bmRequestType = UT_READ_VENDOR_DEVICE;
311         req.bRequest = CUE_CMD_GET_MACADDR;
312         USETW(req.wValue, 0);
313         USETW(req.wIndex, 0);
314         USETW(req.wLength, ETHER_ADDR_LEN);
315
316         err = usbd_do_request(sc->cue_udev, &req, buf);
317
318         CUE_UNLOCK(sc);
319
320         if (err) {
321                 printf("cue%d: read MAC address failed\n", sc->cue_unit);
322                 return(-1);
323         }
324
325         return(0);
326 }
327
328 #define CUE_POLY        0xEDB88320
329 #define CUE_BITS        9
330
331 Static uint32_t
332 cue_mchash(const uint8_t *addr)
333 {
334         uint32_t crc;
335         int idx, bit;
336         uint8_t data;
337
338         /* Compute CRC for the address value. */
339         crc = 0xFFFFFFFF; /* initial value */
340
341         for (idx = 0; idx < 6; idx++) {
342                 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
343                         crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0);
344         }
345
346         return (crc & ((1 << CUE_BITS) - 1));
347 }
348
349 Static void
350 cue_setmulti(struct cue_softc *sc)
351 {
352         struct ifnet            *ifp;
353         struct ifmultiaddr      *ifma;
354         u_int32_t               h = 0, i;
355
356         ifp = &sc->arpcom.ac_if;
357
358         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
359                 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
360                         sc->cue_mctab[i] = 0xFF;
361                 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
362                     &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
363                 return;
364         }
365
366         /* first, zot all the existing hash bits */
367         for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
368                 sc->cue_mctab[i] = 0;
369
370         /* now program new ones */
371 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
372         TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
373 #else
374         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
375 #endif
376         {
377                 if (ifma->ifma_addr->sa_family != AF_LINK)
378                         continue;
379                 h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
380                 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
381         }
382
383         /*
384          * Also include the broadcast address in the filter
385          * so we can receive broadcast frames.
386          */
387         if (ifp->if_flags & IFF_BROADCAST) {
388                 h = cue_mchash(ifp->if_broadcastaddr);
389                 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
390         }
391
392         cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
393             &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
394
395         return;
396 }
397
398 Static void
399 cue_reset(struct cue_softc *sc)
400 {
401         usb_device_request_t    req;
402         usbd_status             err;
403
404         if (sc->cue_dying)
405                 return;
406
407         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
408         req.bRequest = CUE_CMD_RESET;
409         USETW(req.wValue, 0);
410         USETW(req.wIndex, 0);
411         USETW(req.wLength, 0);
412         err = usbd_do_request(sc->cue_udev, &req, NULL);
413         if (err)
414                 printf("cue%d: reset failed\n", sc->cue_unit);
415
416         /* Wait a little while for the chip to get its brains in order. */
417         DELAY(1000);
418         return;
419 }
420
421 /*
422  * Probe for a Pegasus chip.
423  */
424 USB_MATCH(cue)
425 {
426         USB_MATCH_START(cue, uaa);
427         struct cue_type                 *t;
428
429         if (!uaa->iface)
430                 return(UMATCH_NONE);
431
432         t = cue_devs;
433         while(t->cue_vid) {
434                 if (uaa->vendor == t->cue_vid &&
435                     uaa->product == t->cue_did) {
436                         return(UMATCH_VENDOR_PRODUCT);
437                 }
438                 t++;
439         }
440
441         return(UMATCH_NONE);
442 }
443
444 /*
445  * Attach the interface. Allocate softc structures, do ifmedia
446  * setup and ethernet/BPF attach.
447  */
448 USB_ATTACH(cue)
449 {
450         USB_ATTACH_START(cue, sc, uaa);
451         char                    devinfo[1024];
452         u_char                  eaddr[ETHER_ADDR_LEN];
453         struct ifnet            *ifp;
454         usb_interface_descriptor_t      *id;
455         usb_endpoint_descriptor_t       *ed;
456         int                     i;
457
458         bzero(sc, sizeof(struct cue_softc));
459         sc->cue_iface = uaa->iface;
460         sc->cue_udev = uaa->device;
461         sc->cue_unit = device_get_unit(self);
462         callout_init(&sc->cue_stat_timer);
463
464         if (usbd_set_config_no(sc->cue_udev, CUE_CONFIG_NO, 0)) {
465                 printf("cue%d: getting interface handle failed\n",
466                     sc->cue_unit);
467                 USB_ATTACH_ERROR_RETURN;
468         }
469
470         id = usbd_get_interface_descriptor(uaa->iface);
471
472         usbd_devinfo(uaa->device, 0, devinfo);
473         device_set_desc_copy(self, devinfo);
474         printf("%s: %s\n", USBDEVNAME(self), devinfo);
475
476         /* Find endpoints. */
477         for (i = 0; i < id->bNumEndpoints; i++) {
478                 ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
479                 if (!ed) {
480                         printf("cue%d: couldn't get ep %d\n",
481                             sc->cue_unit, i);
482                         USB_ATTACH_ERROR_RETURN;
483                 }
484                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
485                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
486                         sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress;
487                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
488                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
489                         sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress;
490                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
491                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
492                         sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress;
493                 }
494         }
495
496 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
497         mtx_init(&sc->cue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
498             MTX_DEF | MTX_RECURSE);
499 #endif
500         CUE_LOCK(sc);
501
502 #ifdef notdef
503         /* Reset the adapter. */
504         cue_reset(sc);
505 #endif
506         /*
507          * Get station address.
508          */
509         cue_getmac(sc, &eaddr);
510
511         ifp = &sc->arpcom.ac_if;
512         ifp->if_softc = sc;
513         if_initname(ifp, "cue", sc->cue_unit);
514         ifp->if_mtu = ETHERMTU;
515         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
516         ifp->if_ioctl = cue_ioctl;
517         ifp->if_start = cue_start;
518         ifp->if_watchdog = cue_watchdog;
519         ifp->if_init = cue_init;
520         ifp->if_baudrate = 10000000;
521         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
522
523         cue_qdat.ifp = ifp;
524         cue_qdat.if_rxstart = cue_rxstart;
525
526         /*
527          * Call MI attach routine.
528          */
529         ether_ifattach(ifp, eaddr);
530         usb_register_netisr();
531         sc->cue_dying = 0;
532
533         CUE_UNLOCK(sc);
534         USB_ATTACH_SUCCESS_RETURN;
535 }
536
537 Static int
538 cue_detach(device_ptr_t dev)
539 {
540         struct cue_softc        *sc;
541         struct ifnet            *ifp;
542
543         sc = device_get_softc(dev);
544         CUE_LOCK(sc);
545         ifp = &sc->arpcom.ac_if;
546
547         sc->cue_dying = 1;
548         callout_stop(&sc->cue_stat_timer);
549         ether_ifdetach(ifp);
550
551         if (sc->cue_ep[CUE_ENDPT_TX] != NULL)
552                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
553         if (sc->cue_ep[CUE_ENDPT_RX] != NULL)
554                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
555         if (sc->cue_ep[CUE_ENDPT_INTR] != NULL)
556                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
557
558         CUE_UNLOCK(sc);
559 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
560         mtx_destroy(&sc->cue_mtx);
561 #endif
562
563         return(0);
564 }
565
566 /*
567  * Initialize an RX descriptor and attach an MBUF cluster.
568  */
569 Static int
570 cue_newbuf(struct cue_softc *sc, struct cue_chain *c, struct mbuf *m)
571 {
572         struct mbuf             *m_new = NULL;
573
574         if (m == NULL) {
575                 MGETHDR(m_new, MB_DONTWAIT, MT_DATA);
576                 if (m_new == NULL) {
577                         printf("cue%d: no memory for rx list "
578                             "-- packet dropped!\n", sc->cue_unit);
579                         return(ENOBUFS);
580                 }
581
582                 MCLGET(m_new, MB_DONTWAIT);
583                 if (!(m_new->m_flags & M_EXT)) {
584                         printf("cue%d: no memory for rx list "
585                             "-- packet dropped!\n", sc->cue_unit);
586                         m_freem(m_new);
587                         return(ENOBUFS);
588                 }
589                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
590         } else {
591                 m_new = m;
592                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
593                 m_new->m_data = m_new->m_ext.ext_buf;
594         }
595
596         m_adj(m_new, ETHER_ALIGN);
597         c->cue_mbuf = m_new;
598
599         return(0);
600 }
601
602 Static int
603 cue_rx_list_init(struct cue_softc *sc)
604 {
605         struct cue_cdata        *cd;
606         struct cue_chain        *c;
607         int                     i;
608
609         cd = &sc->cue_cdata;
610         for (i = 0; i < CUE_RX_LIST_CNT; i++) {
611                 c = &cd->cue_rx_chain[i];
612                 c->cue_sc = sc;
613                 c->cue_idx = i;
614                 if (cue_newbuf(sc, c, NULL) == ENOBUFS)
615                         return(ENOBUFS);
616                 if (c->cue_xfer == NULL) {
617                         c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
618                         if (c->cue_xfer == NULL)
619                                 return(ENOBUFS);
620                 }
621         }
622
623         return(0);
624 }
625
626 Static int
627 cue_tx_list_init(struct cue_softc *sc)
628 {
629         struct cue_cdata        *cd;
630         struct cue_chain        *c;
631         int                     i;
632
633         cd = &sc->cue_cdata;
634         for (i = 0; i < CUE_TX_LIST_CNT; i++) {
635                 c = &cd->cue_tx_chain[i];
636                 c->cue_sc = sc;
637                 c->cue_idx = i;
638                 c->cue_mbuf = NULL;
639                 if (c->cue_xfer == NULL) {
640                         c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
641                         if (c->cue_xfer == NULL)
642                                 return(ENOBUFS);
643                 }
644                 c->cue_buf = malloc(CUE_BUFSZ, M_USBDEV, M_WAITOK);
645         }
646
647         return(0);
648 }
649
650 Static void
651 cue_rxstart(struct ifnet *ifp)
652 {
653         struct cue_softc        *sc;
654         struct cue_chain        *c;
655
656         sc = ifp->if_softc;
657         CUE_LOCK(sc);
658         c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod];
659
660         if (cue_newbuf(sc, c, NULL) == ENOBUFS) {
661                 ifp->if_ierrors++;
662                 CUE_UNLOCK(sc);
663                 return;
664         }
665
666         /* Setup new transfer. */
667         usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
668             c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
669             USBD_NO_TIMEOUT, cue_rxeof);
670         usbd_transfer(c->cue_xfer);
671         CUE_UNLOCK(sc);
672
673         return;
674 }
675
676 /*
677  * A frame has been uploaded: pass the resulting mbuf chain up to
678  * the higher level protocols.
679  */
680 Static void
681 cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
682 {
683         struct cue_softc        *sc;
684         struct cue_chain        *c;
685         struct mbuf             *m;
686         struct ifnet            *ifp;
687         int                     total_len = 0;
688         u_int16_t               len;
689
690         c = priv;
691         sc = c->cue_sc;
692         CUE_LOCK(sc);
693         ifp = &sc->arpcom.ac_if;
694
695         if (!(ifp->if_flags & IFF_RUNNING)) {
696                 CUE_UNLOCK(sc);
697                 return;
698         }
699
700         if (status != USBD_NORMAL_COMPLETION) {
701                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
702                         CUE_UNLOCK(sc);
703                         return;
704                 }
705                 if (usbd_ratecheck(&sc->cue_rx_notice))
706                         printf("cue%d: usb error on rx: %s\n", sc->cue_unit,
707                             usbd_errstr(status));
708                 if (status == USBD_STALLED)
709                         usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]);
710                 goto done;
711         }
712
713         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
714
715         m = c->cue_mbuf;
716         len = *mtod(m, u_int16_t *);
717
718         /* No errors; receive the packet. */
719         total_len = len;
720
721         if (len < sizeof(struct ether_header)) {
722                 ifp->if_ierrors++;
723                 goto done;
724         }
725
726         ifp->if_ipackets++;
727         m_adj(m, sizeof(u_int16_t));
728         m->m_pkthdr.rcvif = (struct ifnet *)&cue_qdat;
729         m->m_pkthdr.len = m->m_len = total_len;
730
731         /* Put the packet on the special USB input queue. */
732         usb_ether_input(m);
733         CUE_UNLOCK(sc);
734
735         return;
736 done:
737         /* Setup new transfer. */
738         usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
739             c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
740             USBD_NO_TIMEOUT, cue_rxeof);
741         usbd_transfer(c->cue_xfer);
742         CUE_UNLOCK(sc);
743
744         return;
745 }
746
747 /*
748  * A frame was downloaded to the chip. It's safe for us to clean up
749  * the list buffers.
750  */
751
752 Static void
753 cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
754 {
755         struct cue_softc        *sc;
756         struct cue_chain        *c;
757         struct ifnet            *ifp;
758         usbd_status             err;
759
760         c = priv;
761         sc = c->cue_sc;
762         CUE_LOCK(sc);
763         ifp = &sc->arpcom.ac_if;
764
765         if (status != USBD_NORMAL_COMPLETION) {
766                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
767                         CUE_UNLOCK(sc);
768                         return;
769                 }
770                 printf("cue%d: usb error on tx: %s\n", sc->cue_unit,
771                     usbd_errstr(status));
772                 if (status == USBD_STALLED)
773                         usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);
774                 CUE_UNLOCK(sc);
775                 return;
776         }
777
778         ifp->if_timer = 0;
779         ifp->if_flags &= ~IFF_OACTIVE;
780         usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &err);
781
782         if (c->cue_mbuf != NULL) {
783                 c->cue_mbuf->m_pkthdr.rcvif = ifp;
784                 usb_tx_done(c->cue_mbuf);
785                 c->cue_mbuf = NULL;
786         }
787
788         if (err)
789                 ifp->if_oerrors++;
790         else
791                 ifp->if_opackets++;
792
793         CUE_UNLOCK(sc);
794
795         return;
796 }
797
798 Static void
799 cue_tick(void *xsc)
800 {
801         struct cue_softc        *sc;
802         struct ifnet            *ifp;
803
804         sc = xsc;
805
806         if (sc == NULL)
807                 return;
808
809         CUE_LOCK(sc);
810
811         ifp = &sc->arpcom.ac_if;
812
813         ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL);
814         ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL);
815         ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL);
816
817         if (cue_csr_read_2(sc, CUE_RX_FRAMEERR))
818                 ifp->if_ierrors++;
819
820         callout_reset(&sc->cue_stat_timer, hz, cue_tick, sc);
821
822         CUE_UNLOCK(sc);
823
824         return;
825 }
826
827 Static int
828 cue_encap(struct cue_softc *sc, struct mbuf *m, int idx)
829 {
830         int                     total_len;
831         struct cue_chain        *c;
832         usbd_status             err;
833
834         c = &sc->cue_cdata.cue_tx_chain[idx];
835
836         /*
837          * Copy the mbuf data into a contiguous buffer, leaving two
838          * bytes at the beginning to hold the frame length.
839          */
840         m_copydata(m, 0, m->m_pkthdr.len, c->cue_buf + 2);
841         c->cue_mbuf = m;
842
843         total_len = m->m_pkthdr.len + 2;
844
845         /* The first two bytes are the frame length */
846         c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len;
847         c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
848
849         usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX],
850             c, c->cue_buf, total_len, 0, 10000, cue_txeof);
851
852         /* Transmit */
853         err = usbd_transfer(c->cue_xfer);
854         if (err != USBD_IN_PROGRESS) {
855                 cue_stop(sc);
856                 return(EIO);
857         }
858
859         sc->cue_cdata.cue_tx_cnt++;
860
861         return(0);
862 }
863
864 Static void
865 cue_start(struct ifnet *ifp)
866 {
867         struct cue_softc        *sc;
868         struct mbuf             *m_head = NULL;
869
870         sc = ifp->if_softc;
871         CUE_LOCK(sc);
872
873         if (ifp->if_flags & IFF_OACTIVE) {
874                 CUE_UNLOCK(sc);
875                 return;
876         }
877
878         IF_DEQUEUE(&ifp->if_snd, m_head);
879         if (m_head == NULL) {
880                 CUE_UNLOCK(sc);
881                 return;
882         }
883
884         if (cue_encap(sc, m_head, 0)) {
885                 IF_PREPEND(&ifp->if_snd, m_head);
886                 ifp->if_flags |= IFF_OACTIVE;
887                 CUE_UNLOCK(sc);
888                 return;
889         }
890
891         /*
892          * If there's a BPF listener, bounce a copy of this frame
893          * to him.
894          */
895         BPF_MTAP(ifp, m_head);
896
897         ifp->if_flags |= IFF_OACTIVE;
898
899         /*
900          * Set a timeout in case the chip goes out to lunch.
901          */
902         ifp->if_timer = 5;
903         CUE_UNLOCK(sc);
904
905         return;
906 }
907
908 Static void
909 cue_init(void *xsc)
910 {
911         struct cue_softc        *sc = xsc;
912         struct ifnet            *ifp = &sc->arpcom.ac_if;
913         struct cue_chain        *c;
914         usbd_status             err;
915         int                     i;
916
917         if (ifp->if_flags & IFF_RUNNING)
918                 return;
919
920         CUE_LOCK(sc);
921
922         /*
923          * Cancel pending I/O and free all RX/TX buffers.
924          */
925 #ifdef foo
926         cue_reset(sc);
927 #endif
928
929         /* Set MAC address */
930         for (i = 0; i < ETHER_ADDR_LEN; i++)
931                 cue_csr_write_1(sc, CUE_PAR0 - i, sc->arpcom.ac_enaddr[i]);
932
933         /* Enable RX logic. */
934         cue_csr_write_1(sc, CUE_ETHCTL, CUE_ETHCTL_RX_ON|CUE_ETHCTL_MCAST_ON);
935
936          /* If we want promiscuous mode, set the allframes bit. */
937         if (ifp->if_flags & IFF_PROMISC) {
938                 CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
939         } else {
940                 CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
941         }
942
943         /* Init TX ring. */
944         if (cue_tx_list_init(sc) == ENOBUFS) {
945                 printf("cue%d: tx list init failed\n", sc->cue_unit);
946                 CUE_UNLOCK(sc);
947                 return;
948         }
949
950         /* Init RX ring. */
951         if (cue_rx_list_init(sc) == ENOBUFS) {
952                 printf("cue%d: rx list init failed\n", sc->cue_unit);
953                 CUE_UNLOCK(sc);
954                 return;
955         }
956
957         /* Load the multicast filter. */
958         cue_setmulti(sc);
959
960         /*
961          * Set the number of RX and TX buffers that we want
962          * to reserve inside the ASIC.
963          */
964         cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES);
965         cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES);
966
967         /* Set advanced operation modes. */
968         cue_csr_write_1(sc, CUE_ADVANCED_OPMODES,
969             CUE_AOP_EMBED_RXLEN|0x01); /* 1 wait state */
970
971         /* Program the LED operation. */
972         cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK);
973
974         /* Open RX and TX pipes. */
975         err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX],
976             USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]);
977         if (err) {
978                 printf("cue%d: open rx pipe failed: %s\n",
979                     sc->cue_unit, usbd_errstr(err));
980                 CUE_UNLOCK(sc);
981                 return;
982         }
983         err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX],
984             USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]);
985         if (err) {
986                 printf("cue%d: open tx pipe failed: %s\n",
987                     sc->cue_unit, usbd_errstr(err));
988                 CUE_UNLOCK(sc);
989                 return;
990         }
991
992         /* Start up the receive pipe. */
993         for (i = 0; i < CUE_RX_LIST_CNT; i++) {
994                 c = &sc->cue_cdata.cue_rx_chain[i];
995                 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
996                     c, mtod(c->cue_mbuf, char *), CUE_BUFSZ,
997                     USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof);
998                 usbd_transfer(c->cue_xfer);
999         }
1000
1001         ifp->if_flags |= IFF_RUNNING;
1002         ifp->if_flags &= ~IFF_OACTIVE;
1003
1004         CUE_UNLOCK(sc);
1005
1006         callout_reset(&sc->cue_stat_timer, hz, cue_tick, sc);
1007 }
1008
1009 Static int
1010 cue_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
1011 {
1012         struct cue_softc        *sc = ifp->if_softc;
1013         int                     error = 0;
1014
1015         CUE_LOCK(sc);
1016
1017         switch(command) {
1018         case SIOCSIFFLAGS:
1019                 if (ifp->if_flags & IFF_UP) {
1020                         if (ifp->if_flags & IFF_RUNNING &&
1021                             ifp->if_flags & IFF_PROMISC &&
1022                             !(sc->cue_if_flags & IFF_PROMISC)) {
1023                                 CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1024                                 cue_setmulti(sc);
1025                         } else if (ifp->if_flags & IFF_RUNNING &&
1026                             !(ifp->if_flags & IFF_PROMISC) &&
1027                             sc->cue_if_flags & IFF_PROMISC) {
1028                                 CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC);
1029                                 cue_setmulti(sc);
1030                         } else if (!(ifp->if_flags & IFF_RUNNING))
1031                                 cue_init(sc);
1032                 } else {
1033                         if (ifp->if_flags & IFF_RUNNING)
1034                                 cue_stop(sc);
1035                 }
1036                 sc->cue_if_flags = ifp->if_flags;
1037                 error = 0;
1038                 break;
1039         case SIOCADDMULTI:
1040         case SIOCDELMULTI:
1041                 cue_setmulti(sc);
1042                 error = 0;
1043                 break;
1044         default:
1045                 error = ether_ioctl(ifp, command, data);
1046                 break;
1047         }
1048
1049         CUE_UNLOCK(sc);
1050
1051         return(error);
1052 }
1053
1054 Static void
1055 cue_watchdog(struct ifnet *ifp)
1056 {
1057         struct cue_softc        *sc;
1058         struct cue_chain        *c;
1059         usbd_status             stat;
1060
1061         sc = ifp->if_softc;
1062         CUE_LOCK(sc);
1063
1064         ifp->if_oerrors++;
1065         printf("cue%d: watchdog timeout\n", sc->cue_unit);
1066
1067         c = &sc->cue_cdata.cue_tx_chain[0];
1068         usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &stat);
1069         cue_txeof(c->cue_xfer, c, stat);
1070
1071         if (ifp->if_snd.ifq_head != NULL)
1072                 cue_start(ifp);
1073         CUE_UNLOCK(sc);
1074
1075         return;
1076 }
1077
1078 /*
1079  * Stop the adapter and free any mbufs allocated to the
1080  * RX and TX lists.
1081  */
1082 Static void
1083 cue_stop(struct cue_softc *sc)
1084 {
1085         usbd_status             err;
1086         struct ifnet            *ifp;
1087         int                     i;
1088
1089         CUE_LOCK(sc);
1090
1091         ifp = &sc->arpcom.ac_if;
1092         ifp->if_timer = 0;
1093
1094         cue_csr_write_1(sc, CUE_ETHCTL, 0);
1095         cue_reset(sc);
1096         callout_stop(&sc->cue_stat_timer);
1097
1098         /* Stop transfers. */
1099         if (sc->cue_ep[CUE_ENDPT_RX] != NULL) {
1100                 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1101                 if (err) {
1102                         printf("cue%d: abort rx pipe failed: %s\n",
1103                         sc->cue_unit, usbd_errstr(err));
1104                 }
1105                 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]);
1106                 if (err) {
1107                         printf("cue%d: close rx pipe failed: %s\n",
1108                         sc->cue_unit, usbd_errstr(err));
1109                 }
1110                 sc->cue_ep[CUE_ENDPT_RX] = NULL;
1111         }
1112
1113         if (sc->cue_ep[CUE_ENDPT_TX] != NULL) {
1114                 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1115                 if (err) {
1116                         printf("cue%d: abort tx pipe failed: %s\n",
1117                         sc->cue_unit, usbd_errstr(err));
1118                 }
1119                 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]);
1120                 if (err) {
1121                         printf("cue%d: close tx pipe failed: %s\n",
1122                             sc->cue_unit, usbd_errstr(err));
1123                 }
1124                 sc->cue_ep[CUE_ENDPT_TX] = NULL;
1125         }
1126
1127         if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) {
1128                 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1129                 if (err) {
1130                         printf("cue%d: abort intr pipe failed: %s\n",
1131                         sc->cue_unit, usbd_errstr(err));
1132                 }
1133                 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
1134                 if (err) {
1135                         printf("cue%d: close intr pipe failed: %s\n",
1136                             sc->cue_unit, usbd_errstr(err));
1137                 }
1138                 sc->cue_ep[CUE_ENDPT_INTR] = NULL;
1139         }
1140
1141         /* Free RX resources. */
1142         for (i = 0; i < CUE_RX_LIST_CNT; i++) {
1143                 if (sc->cue_cdata.cue_rx_chain[i].cue_buf != NULL) {
1144                         free(sc->cue_cdata.cue_rx_chain[i].cue_buf, M_USBDEV);
1145                         sc->cue_cdata.cue_rx_chain[i].cue_buf = NULL;
1146                 }
1147                 if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) {
1148                         m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf);
1149                         sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL;
1150                 }
1151                 if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) {
1152                         usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer);
1153                         sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL;
1154                 }
1155         }
1156
1157         /* Free TX resources. */
1158         for (i = 0; i < CUE_TX_LIST_CNT; i++) {
1159                 if (sc->cue_cdata.cue_tx_chain[i].cue_buf != NULL) {
1160                         free(sc->cue_cdata.cue_tx_chain[i].cue_buf, M_USBDEV);
1161                         sc->cue_cdata.cue_tx_chain[i].cue_buf = NULL;
1162                 }
1163                 if (sc->cue_cdata.cue_tx_chain[i].cue_mbuf != NULL) {
1164                         m_freem(sc->cue_cdata.cue_tx_chain[i].cue_mbuf);
1165                         sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL;
1166                 }
1167                 if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) {
1168                         usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer);
1169                         sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL;
1170                 }
1171         }
1172
1173         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1174         CUE_UNLOCK(sc);
1175
1176         return;
1177 }
1178
1179 /*
1180  * Stop all chip I/O so that the kernel's probe routines don't
1181  * get confused by errant DMAs when rebooting.
1182  */
1183 Static void
1184 cue_shutdown(device_ptr_t dev)
1185 {
1186         struct cue_softc        *sc;
1187
1188         sc = device_get_softc(dev);
1189
1190         CUE_LOCK(sc);
1191         cue_reset(sc);
1192         cue_stop(sc);
1193         CUE_UNLOCK(sc);
1194
1195         return;
1196 }