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