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