Remove some duplicate FreeBSD CVS IDs, move some IDs to better places.
[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.18 2005/02/21 18:40:36 joerg Exp $
34  */
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/socket.h>
61
62 #include <net/if.h>
63 #include <net/ifq_var.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 int cue_match(device_ptr_t);
96 Static int cue_attach(device_ptr_t);
97 Static int cue_detach(device_ptr_t);
98
99 Static int cue_tx_list_init(struct cue_softc *);
100 Static int cue_rx_list_init(struct cue_softc *);
101 Static int cue_newbuf(struct cue_softc *, struct cue_chain *, struct mbuf *);
102 Static int cue_encap(struct cue_softc *, struct mbuf *, int);
103 Static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
104 Static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
105 Static void cue_tick(void *);
106 Static void cue_rxstart(struct ifnet *);
107 Static void cue_start(struct ifnet *);
108 Static int cue_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
109 Static void cue_init(void *);
110 Static void cue_stop(struct cue_softc *);
111 Static void cue_watchdog(struct ifnet *);
112 Static void cue_shutdown(device_ptr_t);
113
114 Static void cue_setmulti(struct cue_softc *);
115 Static uint32_t cue_mchash(const uint8_t *);
116 Static void cue_reset(struct cue_softc *);
117
118 Static int cue_csr_read_1(struct cue_softc *, int);
119 Static int cue_csr_write_1(struct cue_softc *, int, int);
120 Static int cue_csr_read_2(struct cue_softc *, int);
121 #ifdef notdef
122 Static int cue_csr_write_2(struct cue_softc *, int, int);
123 #endif
124 Static int cue_mem(struct cue_softc *, int, int, void *, int);
125 Static int cue_getmac(struct cue_softc *, void *);
126
127 Static device_method_t cue_methods[] = {
128         /* Device interface */
129         DEVMETHOD(device_probe,         cue_match),
130         DEVMETHOD(device_attach,        cue_attach),
131         DEVMETHOD(device_detach,        cue_detach),
132         DEVMETHOD(device_shutdown,      cue_shutdown),
133
134         { 0, 0 }
135 };
136
137 Static driver_t cue_driver = {
138         "cue",
139         cue_methods,
140         sizeof(struct cue_softc)
141 };
142
143 Static devclass_t cue_devclass;
144
145 DECLARE_DUMMY_MODULE(if_cue);
146 DRIVER_MODULE(cue, uhub, cue_driver, cue_devclass, usbd_driver_load, 0);
147 MODULE_DEPEND(cue, usb, 1, 1, 1);
148
149 #define CUE_SETBIT(sc, reg, x)                          \
150         cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x))
151
152 #define CUE_CLRBIT(sc, reg, x)                          \
153         cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x))
154
155 Static int
156 cue_csr_read_1(struct cue_softc *sc, int reg)
157 {
158         usb_device_request_t    req;
159         usbd_status             err;
160         u_int8_t                val = 0;
161
162         if (sc->cue_dying)
163                 return(0);
164
165         CUE_LOCK(sc);
166
167         req.bmRequestType = UT_READ_VENDOR_DEVICE;
168         req.bRequest = CUE_CMD_READREG;
169         USETW(req.wValue, 0);
170         USETW(req.wIndex, reg);
171         USETW(req.wLength, 1);
172
173         err = usbd_do_request(sc->cue_udev, &req, &val);
174
175         CUE_UNLOCK(sc);
176
177         if (err)
178                 return(0);
179
180         return(val);
181 }
182
183 Static int
184 cue_csr_read_2(struct cue_softc *sc, int reg)
185 {
186         usb_device_request_t    req;
187         usbd_status             err;
188         u_int16_t               val = 0;
189
190         if (sc->cue_dying)
191                 return(0);
192
193         CUE_LOCK(sc);
194
195         req.bmRequestType = UT_READ_VENDOR_DEVICE;
196         req.bRequest = CUE_CMD_READREG;
197         USETW(req.wValue, 0);
198         USETW(req.wIndex, reg);
199         USETW(req.wLength, 2);
200
201         err = usbd_do_request(sc->cue_udev, &req, &val);
202
203         CUE_UNLOCK(sc);
204
205         if (err)
206                 return(0);
207
208         return(val);
209 }
210
211 Static int
212 cue_csr_write_1(struct cue_softc *sc, int reg, int val)
213 {
214         usb_device_request_t    req;
215         usbd_status             err;
216
217         if (sc->cue_dying)
218                 return(0);
219
220         CUE_LOCK(sc);
221
222         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
223         req.bRequest = CUE_CMD_WRITEREG;
224         USETW(req.wValue, val);
225         USETW(req.wIndex, reg);
226         USETW(req.wLength, 0);
227
228         err = usbd_do_request(sc->cue_udev, &req, NULL);
229
230         CUE_UNLOCK(sc);
231
232         if (err)
233                 return(-1);
234
235         return(0);
236 }
237
238 #ifdef notdef
239 Static int
240 cue_csr_write_2(struct cue_softc *sc, int reg, int val)
241 {
242         usb_device_request_t    req;
243         usbd_status             err;
244
245         if (sc->cue_dying)
246                 return(0);
247
248         CUE_LOCK(sc);
249
250         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
251         req.bRequest = CUE_CMD_WRITEREG;
252         USETW(req.wValue, val);
253         USETW(req.wIndex, reg);
254         USETW(req.wLength, 0);
255
256         err = usbd_do_request(sc->cue_udev, &req, NULL);
257
258         CUE_UNLOCK(sc);
259
260         if (err)
261                 return(-1);
262
263         return(0);
264 }
265 #endif
266
267 Static int
268 cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len)
269 {
270         usb_device_request_t    req;
271         usbd_status             err;
272
273         if (sc->cue_dying)
274                 return(0);
275
276         CUE_LOCK(sc);
277
278         if (cmd == CUE_CMD_READSRAM)
279                 req.bmRequestType = UT_READ_VENDOR_DEVICE;
280         else
281                 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
282         req.bRequest = cmd;
283         USETW(req.wValue, 0);
284         USETW(req.wIndex, addr);
285         USETW(req.wLength, len);
286
287         err = usbd_do_request(sc->cue_udev, &req, buf);
288
289         CUE_UNLOCK(sc);
290
291         if (err)
292                 return(-1);
293
294         return(0);
295 }
296
297 Static int
298 cue_getmac(struct cue_softc *sc, void *buf)
299 {
300         usb_device_request_t    req;
301         usbd_status             err;
302
303         if (sc->cue_dying)
304                 return(0);
305
306         CUE_LOCK(sc);
307
308         req.bmRequestType = UT_READ_VENDOR_DEVICE;
309         req.bRequest = CUE_CMD_GET_MACADDR;
310         USETW(req.wValue, 0);
311         USETW(req.wIndex, 0);
312         USETW(req.wLength, ETHER_ADDR_LEN);
313
314         err = usbd_do_request(sc->cue_udev, &req, buf);
315
316         CUE_UNLOCK(sc);
317
318         if (err) {
319                 printf("cue%d: read MAC address failed\n", sc->cue_unit);
320                 return(-1);
321         }
322
323         return(0);
324 }
325
326 #define CUE_POLY        0xEDB88320
327 #define CUE_BITS        9
328
329 Static uint32_t
330 cue_mchash(const uint8_t *addr)
331 {
332         uint32_t crc;
333         int idx, bit;
334         uint8_t data;
335
336         /* Compute CRC for the address value. */
337         crc = 0xFFFFFFFF; /* initial value */
338
339         for (idx = 0; idx < 6; idx++) {
340                 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
341                         crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0);
342         }
343
344         return (crc & ((1 << CUE_BITS) - 1));
345 }
346
347 Static void
348 cue_setmulti(struct cue_softc *sc)
349 {
350         struct ifnet            *ifp;
351         struct ifmultiaddr      *ifma;
352         u_int32_t               h = 0, i;
353
354         ifp = &sc->arpcom.ac_if;
355
356         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
357                 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
358                         sc->cue_mctab[i] = 0xFF;
359                 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
360                     &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
361                 return;
362         }
363
364         /* first, zot all the existing hash bits */
365         for (i = 0; i < CUE_MCAST_TABLE_LEN; i++)
366                 sc->cue_mctab[i] = 0;
367
368         /* now program new ones */
369 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
370         TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
371 #else
372         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
373 #endif
374         {
375                 if (ifma->ifma_addr->sa_family != AF_LINK)
376                         continue;
377                 h = cue_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
378                 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
379         }
380
381         /*
382          * Also include the broadcast address in the filter
383          * so we can receive broadcast frames.
384          */
385         if (ifp->if_flags & IFF_BROADCAST) {
386                 h = cue_mchash(ifp->if_broadcastaddr);
387                 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7);
388         }
389
390         cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR,
391             &sc->cue_mctab, CUE_MCAST_TABLE_LEN);
392
393         return;
394 }
395
396 Static void
397 cue_reset(struct cue_softc *sc)
398 {
399         usb_device_request_t    req;
400         usbd_status             err;
401
402         if (sc->cue_dying)
403                 return;
404
405         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
406         req.bRequest = CUE_CMD_RESET;
407         USETW(req.wValue, 0);
408         USETW(req.wIndex, 0);
409         USETW(req.wLength, 0);
410         err = usbd_do_request(sc->cue_udev, &req, NULL);
411         if (err)
412                 printf("cue%d: reset failed\n", sc->cue_unit);
413
414         /* Wait a little while for the chip to get its brains in order. */
415         DELAY(1000);
416         return;
417 }
418
419 /*
420  * Probe for a Pegasus chip.
421  */
422 USB_MATCH(cue)
423 {
424         USB_MATCH_START(cue, uaa);
425         struct cue_type                 *t;
426
427         if (!uaa->iface)
428                 return(UMATCH_NONE);
429
430         t = cue_devs;
431         while(t->cue_vid) {
432                 if (uaa->vendor == t->cue_vid &&
433                     uaa->product == t->cue_did) {
434                         return(UMATCH_VENDOR_PRODUCT);
435                 }
436                 t++;
437         }
438
439         return(UMATCH_NONE);
440 }
441
442 /*
443  * Attach the interface. Allocate softc structures, do ifmedia
444  * setup and ethernet/BPF attach.
445  */
446 USB_ATTACH(cue)
447 {
448         USB_ATTACH_START(cue, sc, uaa);
449         char                    devinfo[1024];
450         u_char                  eaddr[ETHER_ADDR_LEN];
451         struct ifnet            *ifp;
452         usb_interface_descriptor_t      *id;
453         usb_endpoint_descriptor_t       *ed;
454         int                     i;
455
456         bzero(sc, sizeof(struct cue_softc));
457         sc->cue_iface = uaa->iface;
458         sc->cue_udev = uaa->device;
459         sc->cue_unit = device_get_unit(self);
460         callout_init(&sc->cue_stat_timer);
461
462         if (usbd_set_config_no(sc->cue_udev, CUE_CONFIG_NO, 0)) {
463                 printf("cue%d: getting interface handle failed\n",
464                     sc->cue_unit);
465                 USB_ATTACH_ERROR_RETURN;
466         }
467
468         id = usbd_get_interface_descriptor(uaa->iface);
469
470         usbd_devinfo(uaa->device, 0, devinfo);
471         device_set_desc_copy(self, devinfo);
472         printf("%s: %s\n", USBDEVNAME(self), devinfo);
473
474         /* Find endpoints. */
475         for (i = 0; i < id->bNumEndpoints; i++) {
476                 ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
477                 if (!ed) {
478                         printf("cue%d: couldn't get ep %d\n",
479                             sc->cue_unit, i);
480                         USB_ATTACH_ERROR_RETURN;
481                 }
482                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
483                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
484                         sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress;
485                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
486                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
487                         sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress;
488                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
489                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
490                         sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress;
491                 }
492         }
493
494 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
495         mtx_init(&sc->cue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
496             MTX_DEF | MTX_RECURSE);
497 #endif
498         CUE_LOCK(sc);
499
500 #ifdef notdef
501         /* Reset the adapter. */
502         cue_reset(sc);
503 #endif
504         /*
505          * Get station address.
506          */
507         cue_getmac(sc, &eaddr);
508
509         ifp = &sc->arpcom.ac_if;
510         ifp->if_softc = sc;
511         if_initname(ifp, "cue", sc->cue_unit);
512         ifp->if_mtu = ETHERMTU;
513         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
514         ifp->if_ioctl = cue_ioctl;
515         ifp->if_start = cue_start;
516         ifp->if_watchdog = cue_watchdog;
517         ifp->if_init = cue_init;
518         ifp->if_baudrate = 10000000;
519         ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
520         ifq_set_ready(&ifp->if_snd);
521
522         /*
523          * Call MI attach routine.
524          */
525         ether_ifattach(ifp, eaddr);
526         usb_register_netisr();
527         sc->cue_dying = 0;
528
529         CUE_UNLOCK(sc);
530         USB_ATTACH_SUCCESS_RETURN;
531 }
532
533 Static int
534 cue_detach(device_ptr_t dev)
535 {
536         struct cue_softc        *sc;
537         struct ifnet            *ifp;
538
539         sc = device_get_softc(dev);
540         CUE_LOCK(sc);
541         ifp = &sc->arpcom.ac_if;
542
543         sc->cue_dying = 1;
544         callout_stop(&sc->cue_stat_timer);
545         ether_ifdetach(ifp);
546
547         if (sc->cue_ep[CUE_ENDPT_TX] != NULL)
548                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]);
549         if (sc->cue_ep[CUE_ENDPT_RX] != NULL)
550                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]);
551         if (sc->cue_ep[CUE_ENDPT_INTR] != NULL)
552                 usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]);
553
554         CUE_UNLOCK(sc);
555 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
556         mtx_destroy(&sc->cue_mtx);
557 #endif
558
559         return(0);
560 }
561
562 /*
563  * Initialize an RX descriptor and attach an MBUF cluster.
564  */
565 Static int
566 cue_newbuf(struct cue_softc *sc, struct cue_chain *c, struct mbuf *m)
567 {
568         struct mbuf             *m_new = NULL;
569
570         if (m == NULL) {
571                 MGETHDR(m_new, MB_DONTWAIT, MT_DATA);
572                 if (m_new == NULL) {
573                         printf("cue%d: no memory for rx list "
574                             "-- packet dropped!\n", sc->cue_unit);
575                         return(ENOBUFS);
576                 }
577
578                 MCLGET(m_new, MB_DONTWAIT);
579                 if (!(m_new->m_flags & M_EXT)) {
580                         printf("cue%d: no memory for rx list "
581                             "-- packet dropped!\n", sc->cue_unit);
582                         m_freem(m_new);
583                         return(ENOBUFS);
584                 }
585                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
586         } else {
587                 m_new = m;
588                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
589                 m_new->m_data = m_new->m_ext.ext_buf;
590         }
591
592         m_adj(m_new, ETHER_ALIGN);
593         c->cue_mbuf = m_new;
594
595         return(0);
596 }
597
598 Static int
599 cue_rx_list_init(struct cue_softc *sc)
600 {
601         struct cue_cdata        *cd;
602         struct cue_chain        *c;
603         int                     i;
604
605         cd = &sc->cue_cdata;
606         for (i = 0; i < CUE_RX_LIST_CNT; i++) {
607                 c = &cd->cue_rx_chain[i];
608                 c->cue_sc = sc;
609                 c->cue_idx = i;
610                 if (cue_newbuf(sc, c, NULL) == ENOBUFS)
611                         return(ENOBUFS);
612                 if (c->cue_xfer == NULL) {
613                         c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
614                         if (c->cue_xfer == NULL)
615                                 return(ENOBUFS);
616                 }
617         }
618
619         return(0);
620 }
621
622 Static int
623 cue_tx_list_init(struct cue_softc *sc)
624 {
625         struct cue_cdata        *cd;
626         struct cue_chain        *c;
627         int                     i;
628
629         cd = &sc->cue_cdata;
630         for (i = 0; i < CUE_TX_LIST_CNT; i++) {
631                 c = &cd->cue_tx_chain[i];
632                 c->cue_sc = sc;
633                 c->cue_idx = i;
634                 c->cue_mbuf = NULL;
635                 if (c->cue_xfer == NULL) {
636                         c->cue_xfer = usbd_alloc_xfer(sc->cue_udev);
637                         if (c->cue_xfer == NULL)
638                                 return(ENOBUFS);
639                 }
640                 c->cue_buf = malloc(CUE_BUFSZ, M_USBDEV, M_WAITOK);
641         }
642
643         return(0);
644 }
645
646 Static void
647 cue_rxstart(struct ifnet *ifp)
648 {
649         struct cue_softc        *sc;
650         struct cue_chain        *c;
651
652         sc = ifp->if_softc;
653         CUE_LOCK(sc);
654         c = &sc->cue_cdata.cue_rx_chain[sc->cue_cdata.cue_rx_prod];
655
656         if (cue_newbuf(sc, c, NULL) == ENOBUFS) {
657                 ifp->if_ierrors++;
658                 CUE_UNLOCK(sc);
659                 return;
660         }
661
662         /* Setup new transfer. */
663         usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
664             c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
665             USBD_NO_TIMEOUT, cue_rxeof);
666         usbd_transfer(c->cue_xfer);
667         CUE_UNLOCK(sc);
668
669         return;
670 }
671
672 /*
673  * A frame has been uploaded: pass the resulting mbuf chain up to
674  * the higher level protocols.
675  */
676 Static void
677 cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
678 {
679         struct cue_softc        *sc;
680         struct cue_chain        *c;
681         struct mbuf             *m;
682         struct ifnet            *ifp;
683         int                     total_len = 0;
684         u_int16_t               len;
685
686         c = priv;
687         sc = c->cue_sc;
688         CUE_LOCK(sc);
689         ifp = &sc->arpcom.ac_if;
690
691         if (!(ifp->if_flags & IFF_RUNNING)) {
692                 CUE_UNLOCK(sc);
693                 return;
694         }
695
696         if (status != USBD_NORMAL_COMPLETION) {
697                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
698                         CUE_UNLOCK(sc);
699                         return;
700                 }
701                 if (usbd_ratecheck(&sc->cue_rx_notice))
702                         printf("cue%d: usb error on rx: %s\n", sc->cue_unit,
703                             usbd_errstr(status));
704                 if (status == USBD_STALLED)
705                         usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_RX]);
706                 goto done;
707         }
708
709         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
710
711         m = c->cue_mbuf;
712         len = *mtod(m, u_int16_t *);
713
714         /* No errors; receive the packet. */
715         total_len = len;
716
717         if (len < sizeof(struct ether_header)) {
718                 ifp->if_ierrors++;
719                 goto done;
720         }
721
722         ifp->if_ipackets++;
723         m_adj(m, sizeof(u_int16_t));
724         m->m_pkthdr.rcvif = ifp;
725         m->m_pkthdr.len = m->m_len = total_len;
726
727         /* Put the packet on the special USB input queue. */
728         usb_ether_input(m);
729         cue_rxstart(ifp);
730
731         CUE_UNLOCK(sc);
732
733         return;
734 done:
735         /* Setup new transfer. */
736         usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX],
737             c, mtod(c->cue_mbuf, char *), CUE_BUFSZ, USBD_SHORT_XFER_OK,
738             USBD_NO_TIMEOUT, cue_rxeof);
739         usbd_transfer(c->cue_xfer);
740         CUE_UNLOCK(sc);
741
742         return;
743 }
744
745 /*
746  * A frame was downloaded to the chip. It's safe for us to clean up
747  * the list buffers.
748  */
749
750 Static void
751 cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
752 {
753         struct cue_softc        *sc;
754         struct cue_chain        *c;
755         struct ifnet            *ifp;
756         usbd_status             err;
757
758         c = priv;
759         sc = c->cue_sc;
760         CUE_LOCK(sc);
761         ifp = &sc->arpcom.ac_if;
762
763         if (status != USBD_NORMAL_COMPLETION) {
764                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
765                         CUE_UNLOCK(sc);
766                         return;
767                 }
768                 printf("cue%d: usb error on tx: %s\n", sc->cue_unit,
769                     usbd_errstr(status));
770                 if (status == USBD_STALLED)
771                         usbd_clear_endpoint_stall(sc->cue_ep[CUE_ENDPT_TX]);
772                 CUE_UNLOCK(sc);
773                 return;
774         }
775
776         ifp->if_timer = 0;
777         ifp->if_flags &= ~IFF_OACTIVE;
778         usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &err);
779
780         if (c->cue_mbuf != NULL) {
781                 m_freem(c->cue_mbuf);
782                 c->cue_mbuf = NULL;
783         }
784
785         if (err)
786                 ifp->if_oerrors++;
787         else
788                 ifp->if_opackets++;
789
790         if (!ifq_is_empty(&ifp->if_snd))
791                 (*ifp->if_start)(ifp);
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         m_head = ifq_poll(&ifp->if_snd);
879         if (m_head == NULL) {
880                 CUE_UNLOCK(sc);
881                 return;
882         }
883
884         if (cue_encap(sc, m_head, 0)) {
885                 ifp->if_flags |= IFF_OACTIVE;
886                 CUE_UNLOCK(sc);
887                 return;
888         }
889         m_head = ifq_dequeue(&ifp->if_snd);
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 (!ifq_is_empty(&ifp->if_snd))
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 }