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