]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/usb/if_kue.c
This commit was generated by cvs2svn to compensate for changes in r161655,
[FreeBSD/FreeBSD.git] / sys / dev / usb / if_kue.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  * Kawasaki LSI KL5KUSB101B USB to ethernet adapter driver.
38  *
39  * Written by Bill Paul <wpaul@ee.columbia.edu>
40  * Electrical Engineering Department
41  * Columbia University, New York City
42  */
43
44 /*
45  * The KLSI USB to ethernet adapter chip contains an USB serial interface,
46  * ethernet MAC and embedded microcontroller (called the QT Engine).
47  * The chip must have firmware loaded into it before it will operate.
48  * Packets are passed between the chip and host via bulk transfers.
49  * There is an interrupt endpoint mentioned in the software spec, however
50  * it's currently unused. This device is 10Mbps half-duplex only, hence
51  * there is no media selection logic. The MAC supports a 128 entry
52  * multicast filter, though the exact size of the filter can depend
53  * on the firmware. Curiously, while the software spec describes various
54  * ethernet statistics counters, my sample adapter and firmware combination
55  * claims not to support any statistics counters at all.
56  *
57  * Note that once we load the firmware in the device, we have to be
58  * careful not to load it again: if you restart your computer but
59  * leave the adapter attached to the USB controller, it may remain
60  * powered on and retain its firmware. In this case, we don't need
61  * to load the firmware a second time.
62  *
63  * Special thanks to Rob Furr for providing an ADS Technologies
64  * adapter for development and testing. No monkeys were harmed during
65  * the development of this driver.
66  */
67
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/sockio.h>
71 #include <sys/mbuf.h>
72 #include <sys/malloc.h>
73 #include <sys/kernel.h>
74 #include <sys/module.h>
75 #include <sys/socket.h>
76
77 #include <net/if.h>
78 #include <net/if_arp.h>
79 #include <net/ethernet.h>
80 #include <net/if_dl.h>
81 #include <net/if_media.h>
82 #include <net/if_types.h>
83
84 #include <net/bpf.h>
85
86 #include <sys/bus.h>
87 #include <machine/bus.h>
88 #if __FreeBSD_version < 500000
89 #include <machine/clock.h>
90 #endif
91
92 #include <dev/usb/usb.h>
93 #include <dev/usb/usbdi.h>
94 #include <dev/usb/usbdi_util.h>
95 #include <dev/usb/usbdivar.h>
96 #include "usbdevs.h"
97 #include <dev/usb/usb_ethersubr.h>
98
99 #include <dev/usb/if_kuereg.h>
100 #include <dev/usb/kue_fw.h>
101
102 MODULE_DEPEND(kue, usb, 1, 1, 1);
103 MODULE_DEPEND(kue, ether, 1, 1, 1);
104
105 /*
106  * Various supported device vendors/products.
107  */
108 Static struct kue_type kue_devs[] = {
109         { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 },
110         { USB_VENDOR_KLSI, USB_PRODUCT_AOX_USB101 },
111         { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT },
112         { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T },
113         { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 },
114         { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET },
115         { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 },
116         { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 },
117         { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 },
118         { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T },
119         { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C },
120         { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB },
121         { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T },
122         { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT },
123         { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BTN },
124         { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET3 },
125         { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT },
126         { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_URE450 },
127         { 0, 0 }
128 };
129
130 Static int kue_match(device_ptr_t);
131 Static int kue_attach(device_ptr_t);
132 Static int kue_detach(device_ptr_t);
133 Static void kue_shutdown(device_ptr_t);
134 Static int kue_encap(struct kue_softc *, struct mbuf *, int);
135 Static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
136 Static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
137 Static void kue_start(struct ifnet *);
138 Static void kue_rxstart(struct ifnet *);
139 Static int kue_ioctl(struct ifnet *, u_long, caddr_t);
140 Static void kue_init(void *);
141 Static void kue_stop(struct kue_softc *);
142 Static void kue_watchdog(struct ifnet *);
143
144 Static void kue_setmulti(struct kue_softc *);
145 Static void kue_reset(struct kue_softc *);
146
147 Static usbd_status kue_do_request(usbd_device_handle,
148                                   usb_device_request_t *, void *);
149 Static usbd_status kue_ctl(struct kue_softc *, int, u_int8_t,
150                            u_int16_t, char *, int);
151 Static usbd_status kue_setword(struct kue_softc *, u_int8_t, u_int16_t);
152 Static int kue_load_fw(struct kue_softc *);
153
154 Static device_method_t kue_methods[] = {
155         /* Device interface */
156         DEVMETHOD(device_probe,         kue_match),
157         DEVMETHOD(device_attach,        kue_attach),
158         DEVMETHOD(device_detach,        kue_detach),
159         DEVMETHOD(device_shutdown,      kue_shutdown),
160
161         { 0, 0 }
162 };
163
164 Static driver_t kue_driver = {
165         "kue",
166         kue_methods,
167         sizeof(struct kue_softc)
168 };
169
170 Static devclass_t kue_devclass;
171
172 DRIVER_MODULE(kue, uhub, kue_driver, kue_devclass, usbd_driver_load, 0);
173
174 /*
175  * We have a custom do_request function which is almost like the
176  * regular do_request function, except it has a much longer timeout.
177  * Why? Because we need to make requests over the control endpoint
178  * to download the firmware to the device, which can take longer
179  * than the default timeout.
180  */
181 Static usbd_status
182 kue_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
183 {
184         usbd_xfer_handle        xfer;
185         usbd_status             err;
186
187         xfer = usbd_alloc_xfer(dev);
188         usbd_setup_default_xfer(xfer, dev, 0, 500000, req,
189             data, UGETW(req->wLength), USBD_SHORT_XFER_OK, 0);
190         err = usbd_sync_transfer(xfer);
191         usbd_free_xfer(xfer);
192         return(err);
193 }
194
195 Static usbd_status
196 kue_setword(struct kue_softc *sc, u_int8_t breq, u_int16_t word)
197 {
198         usbd_device_handle      dev;
199         usb_device_request_t    req;
200         usbd_status             err;
201
202         if (sc->kue_dying)
203                 return(USBD_NORMAL_COMPLETION);
204
205         dev = sc->kue_udev;
206
207         KUE_LOCK(sc);
208
209         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
210
211         req.bRequest = breq;
212         USETW(req.wValue, word);
213         USETW(req.wIndex, 0);
214         USETW(req.wLength, 0);
215
216         err = kue_do_request(dev, &req, NULL);
217
218         KUE_UNLOCK(sc);
219
220         return(err);
221 }
222
223 Static usbd_status
224 kue_ctl(struct kue_softc *sc, int rw, u_int8_t breq, u_int16_t val,
225         char *data, int len)
226 {
227         usbd_device_handle      dev;
228         usb_device_request_t    req;
229         usbd_status             err;
230
231         dev = sc->kue_udev;
232
233         if (sc->kue_dying)
234                 return(USBD_NORMAL_COMPLETION);
235
236         KUE_LOCK(sc);
237
238         if (rw == KUE_CTL_WRITE)
239                 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
240         else
241                 req.bmRequestType = UT_READ_VENDOR_DEVICE;
242
243         req.bRequest = breq;
244         USETW(req.wValue, val);
245         USETW(req.wIndex, 0);
246         USETW(req.wLength, len);
247
248         err = kue_do_request(dev, &req, data);
249
250         KUE_UNLOCK(sc);
251
252         return(err);
253 }
254
255 Static int
256 kue_load_fw(struct kue_softc *sc)
257 {
258         usbd_status             err;
259         usb_device_descriptor_t *dd;
260         int                     hwrev;
261
262         dd = &sc->kue_udev->ddesc;
263         hwrev = UGETW(dd->bcdDevice);
264
265         /*
266          * First, check if we even need to load the firmware.
267          * If the device was still attached when the system was
268          * rebooted, it may already have firmware loaded in it.
269          * If this is the case, we don't need to do it again.
270          * And in fact, if we try to load it again, we'll hang,
271          * so we have to avoid this condition if we don't want
272          * to look stupid.
273          *
274          * We can test this quickly by checking the bcdRevision
275          * code. The NIC will return a different revision code if
276          * it's probed while the firmware is still loaded and
277          * running.
278          */
279         if (hwrev == 0x0202)
280                 return(0);
281
282         /* Load code segment */
283         err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
284             0, kue_code_seg, sizeof(kue_code_seg));
285         if (err) {
286                 printf("kue%d: failed to load code segment: %s\n",
287                     sc->kue_unit, usbd_errstr(err));
288                         return(ENXIO);
289         }
290
291         /* Load fixup segment */
292         err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
293             0, kue_fix_seg, sizeof(kue_fix_seg));
294         if (err) {
295                 printf("kue%d: failed to load fixup segment: %s\n",
296                     sc->kue_unit, usbd_errstr(err));
297                         return(ENXIO);
298         }
299
300         /* Send trigger command. */
301         err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
302             0, kue_trig_seg, sizeof(kue_trig_seg));
303         if (err) {
304                 printf("kue%d: failed to load trigger segment: %s\n",
305                     sc->kue_unit, usbd_errstr(err));
306                         return(ENXIO);
307         }
308
309         return(0);
310 }
311
312 Static void
313 kue_setmulti(struct kue_softc *sc)
314 {
315         struct ifnet            *ifp;
316         struct ifmultiaddr      *ifma;
317         int                     i = 0;
318
319         ifp = sc->kue_ifp;
320
321         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
322                 sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
323                 sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
324                 kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
325                 return;
326         }
327
328         sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI;
329
330         IF_ADDR_LOCK(ifp);
331 #if __FreeBSD_version >= 500000
332         TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
333 #else
334         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
335 #endif
336         {
337                 if (ifma->ifma_addr->sa_family != AF_LINK)
338                         continue;
339                 /*
340                  * If there are too many addresses for the
341                  * internal filter, switch over to allmulti mode.
342                  */
343                 if (i == KUE_MCFILTCNT(sc))
344                         break;
345                 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
346                     KUE_MCFILT(sc, i), ETHER_ADDR_LEN);
347                 i++;
348         }
349         IF_ADDR_UNLOCK(ifp);
350
351         if (i == KUE_MCFILTCNT(sc))
352                 sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
353         else {
354                 sc->kue_rxfilt |= KUE_RXFILT_MULTICAST;
355                 kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
356                     i, sc->kue_mcfilters, i * ETHER_ADDR_LEN);
357         }
358
359         kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
360
361         return;
362 }
363
364 /*
365  * Issue a SET_CONFIGURATION command to reset the MAC. This should be
366  * done after the firmware is loaded into the adapter in order to
367  * bring it into proper operation.
368  */
369 Static void
370 kue_reset(struct kue_softc *sc)
371 {
372         if (usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 0) ||
373             usbd_device2interface_handle(sc->kue_udev, KUE_IFACE_IDX,
374             &sc->kue_iface)) {
375                 printf("kue%d: getting interface handle failed\n",
376                     sc->kue_unit);
377         }
378
379         /* Wait a little while for the chip to get its brains in order. */
380         DELAY(1000);
381         return;
382 }
383
384 /*
385  * Probe for a KLSI chip.
386  */
387 USB_MATCH(kue)
388 {
389         USB_MATCH_START(kue, uaa);
390         struct kue_type                 *t;
391
392         if (!uaa->iface)
393                 return(UMATCH_NONE);
394
395         t = kue_devs;
396         while(t->kue_vid) {
397                 if (uaa->vendor == t->kue_vid &&
398                     uaa->product == t->kue_did) {
399                         return(UMATCH_VENDOR_PRODUCT);
400                 }
401                 t++;
402         }
403
404         return(UMATCH_NONE);
405 }
406
407 /*
408  * Attach the interface. Allocate softc structures, do
409  * setup and ethernet/BPF attach.
410  */
411 USB_ATTACH(kue)
412 {
413         USB_ATTACH_START(kue, sc, uaa);
414         char                    devinfo[1024];
415         struct ifnet            *ifp;
416         usbd_status             err;
417         usb_interface_descriptor_t      *id;
418         usb_endpoint_descriptor_t       *ed;
419         int                     i;
420
421         bzero(sc, sizeof(struct kue_softc));
422         sc->kue_dev = self;
423         sc->kue_iface = uaa->iface;
424         sc->kue_udev = uaa->device;
425         sc->kue_unit = device_get_unit(self);
426
427         id = usbd_get_interface_descriptor(uaa->iface);
428
429         usbd_devinfo(uaa->device, 0, devinfo);
430         device_set_desc_copy(self, devinfo);
431         printf("%s: %s\n", USBDEVNAME(self), devinfo);
432
433         /* Find endpoints. */
434         for (i = 0; i < id->bNumEndpoints; i++) {
435                 ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
436                 if (!ed) {
437                         printf("kue%d: couldn't get ep %d\n",
438                             sc->kue_unit, i);
439                         USB_ATTACH_ERROR_RETURN;
440                 }
441                 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
442                     UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
443                         sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
444                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
445                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
446                         sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
447                 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
448                            UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
449                         sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress;
450                 }
451         }
452
453 #if __FreeBSD_version >= 500000
454         mtx_init(&sc->kue_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
455             MTX_DEF | MTX_RECURSE);
456 #endif
457         KUE_LOCK(sc);
458
459         /* Load the firmware into the NIC. */
460         if (kue_load_fw(sc)) {
461                 KUE_UNLOCK(sc);
462 #if __FreeBSD_version >= 500000
463                 mtx_destroy(&sc->kue_mtx);
464 #endif
465                 USB_ATTACH_ERROR_RETURN;
466         }
467
468         /* Reset the adapter. */
469         kue_reset(sc);
470
471         /* Read ethernet descriptor */
472         err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
473             0, (char *)&sc->kue_desc, sizeof(sc->kue_desc));
474
475         sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
476             M_USBDEV, M_NOWAIT);
477
478         ifp = sc->kue_ifp = if_alloc(IFT_ETHER);
479         if (ifp == NULL) {
480                 printf("kue%d: can not if_alloc()\n", sc->kue_unit);
481                 KUE_UNLOCK(sc);
482 #if __FreeBSD_version >= 500000
483                 mtx_destroy(&sc->kue_mtx);
484 #endif
485                 USB_ATTACH_ERROR_RETURN;
486         }
487         ifp->if_softc = sc;
488         if_initname(ifp, "kue", sc->kue_unit);
489         ifp->if_mtu = ETHERMTU;
490         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
491             IFF_NEEDSGIANT;
492         ifp->if_ioctl = kue_ioctl;
493         ifp->if_start = kue_start;
494         ifp->if_watchdog = kue_watchdog;
495         ifp->if_init = kue_init;
496         ifp->if_baudrate = 10000000;
497         ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
498
499         sc->kue_qdat.ifp = ifp;
500         sc->kue_qdat.if_rxstart = kue_rxstart;
501
502         /*
503          * Call MI attach routine.
504          */
505 #if __FreeBSD_version >= 500000
506         ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
507 #else
508         ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
509 #endif
510         usb_register_netisr();
511         sc->kue_dying = 0;
512
513         KUE_UNLOCK(sc);
514
515         USB_ATTACH_SUCCESS_RETURN;
516 }
517
518 Static int
519 kue_detach(device_ptr_t dev)
520 {
521         struct kue_softc        *sc;
522         struct ifnet            *ifp;
523
524         sc = device_get_softc(dev);
525         KUE_LOCK(sc);
526         ifp = sc->kue_ifp;
527
528         sc->kue_dying = 1;
529
530         if (ifp != NULL)
531 #if __FreeBSD_version >= 500000
532                 ether_ifdetach(ifp);
533                 if_free(ifp);
534 #else
535                 ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
536 #endif
537
538         if (sc->kue_ep[KUE_ENDPT_TX] != NULL)
539                 usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]);
540         if (sc->kue_ep[KUE_ENDPT_RX] != NULL)
541                 usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]);
542         if (sc->kue_ep[KUE_ENDPT_INTR] != NULL)
543                 usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
544
545         if (sc->kue_mcfilters != NULL)
546                 free(sc->kue_mcfilters, M_USBDEV);
547
548         KUE_UNLOCK(sc);
549 #if __FreeBSD_version >= 500000
550         mtx_destroy(&sc->kue_mtx);
551 #endif
552
553         return(0);
554 }
555
556 Static void
557 kue_rxstart(struct ifnet *ifp)
558 {
559         struct kue_softc        *sc;
560         struct ue_chain *c;
561
562         sc = ifp->if_softc;
563         KUE_LOCK(sc);
564         c = &sc->kue_cdata.ue_rx_chain[sc->kue_cdata.ue_rx_prod];
565
566         c->ue_mbuf = usb_ether_newbuf();
567         if (c->ue_mbuf == NULL) {
568                 printf("%s: no memory for rx list "
569                     "-- packet dropped!\n", USBDEVNAME(sc->kue_dev));
570                 ifp->if_ierrors++;
571                 KUE_UNLOCK(sc);
572                 return;
573         }
574
575         /* Setup new transfer. */
576         usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
577             c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
578             USBD_NO_TIMEOUT, kue_rxeof);
579         usbd_transfer(c->ue_xfer);
580
581         KUE_UNLOCK(sc);
582
583         return;
584 }
585
586 /*
587  * A frame has been uploaded: pass the resulting mbuf chain up to
588  * the higher level protocols.
589  */
590 Static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
591                       usbd_status status)
592 {
593         struct kue_softc        *sc;
594         struct ue_chain *c;
595         struct mbuf             *m;
596         struct ifnet            *ifp;
597         int                     total_len = 0;
598         u_int16_t               len;
599
600         c = priv;
601         sc = c->ue_sc;
602         KUE_LOCK(sc);
603         ifp = sc->kue_ifp;
604
605         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
606                 KUE_UNLOCK(sc);
607                 return;
608         }
609
610         if (status != USBD_NORMAL_COMPLETION) {
611                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
612                         KUE_UNLOCK(sc);
613                         return;
614                 }
615                 if (usbd_ratecheck(&sc->kue_rx_notice))
616                         printf("kue%d: usb error on rx: %s\n", sc->kue_unit,
617                             usbd_errstr(status));
618                 if (status == USBD_STALLED)
619                         usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_RX]);
620                 goto done;
621         }
622
623         usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
624         m = c->ue_mbuf;
625         if (total_len <= 1)
626                 goto done;
627
628         len = *mtod(m, u_int16_t *);
629         m_adj(m, sizeof(u_int16_t));
630
631         /* No errors; receive the packet. */
632         total_len = len;
633
634         if (len < sizeof(struct ether_header)) {
635                 ifp->if_ierrors++;
636                 goto done;
637         }
638
639         ifp->if_ipackets++;
640         m->m_pkthdr.rcvif = (void *)&sc->kue_qdat;
641         m->m_pkthdr.len = m->m_len = total_len;
642
643         /* Put the packet on the special USB input queue. */
644         usb_ether_input(m);
645         KUE_UNLOCK(sc);
646
647         return;
648 done:
649
650         /* Setup new transfer. */
651         usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
652             c, mtod(c->ue_mbuf, char *), UE_BUFSZ, USBD_SHORT_XFER_OK,
653             USBD_NO_TIMEOUT, kue_rxeof);
654         usbd_transfer(c->ue_xfer);
655         KUE_UNLOCK(sc);
656
657         return;
658 }
659
660 /*
661  * A frame was downloaded to the chip. It's safe for us to clean up
662  * the list buffers.
663  */
664
665 Static void
666 kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
667 {
668         struct kue_softc        *sc;
669         struct ue_chain *c;
670         struct ifnet            *ifp;
671         usbd_status             err;
672
673         c = priv;
674         sc = c->ue_sc;
675         KUE_LOCK(sc);
676
677         ifp = sc->kue_ifp;
678         ifp->if_timer = 0;
679         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
680
681         if (status != USBD_NORMAL_COMPLETION) {
682                 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
683                         KUE_UNLOCK(sc);
684                         return;
685                 }
686                 printf("kue%d: usb error on tx: %s\n", sc->kue_unit,
687                     usbd_errstr(status));
688                 if (status == USBD_STALLED)
689                         usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]);
690                 KUE_UNLOCK(sc);
691                 return;
692         }
693
694         usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &err);
695
696         if (c->ue_mbuf != NULL) {
697                 c->ue_mbuf->m_pkthdr.rcvif = ifp;
698                 usb_tx_done(c->ue_mbuf);
699                 c->ue_mbuf = NULL;
700         }
701
702         if (err)
703                 ifp->if_oerrors++;
704         else
705                 ifp->if_opackets++;
706
707         KUE_UNLOCK(sc);
708
709         return;
710 }
711
712 Static int
713 kue_encap(struct kue_softc *sc, struct mbuf *m, int idx)
714 {
715         int                     total_len;
716         struct ue_chain *c;
717         usbd_status             err;
718
719         c = &sc->kue_cdata.ue_tx_chain[idx];
720
721         /*
722          * Copy the mbuf data into a contiguous buffer, leaving two
723          * bytes at the beginning to hold the frame length.
724          */
725         m_copydata(m, 0, m->m_pkthdr.len, c->ue_buf + 2);
726         c->ue_mbuf = m;
727
728         total_len = m->m_pkthdr.len + 2;
729         total_len += 64 - (total_len % 64);
730
731         /* Frame length is specified in the first 2 bytes of the buffer. */
732         c->ue_buf[0] = (u_int8_t)m->m_pkthdr.len;
733         c->ue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
734
735         usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_TX],
736             c, c->ue_buf, total_len, 0, 10000, kue_txeof);
737
738         /* Transmit */
739         err = usbd_transfer(c->ue_xfer);
740         if (err != USBD_IN_PROGRESS) {
741                 kue_stop(sc);
742                 return(EIO);
743         }
744
745         sc->kue_cdata.ue_tx_cnt++;
746
747         return(0);
748 }
749
750 Static void
751 kue_start(struct ifnet *ifp)
752 {
753         struct kue_softc        *sc;
754         struct mbuf             *m_head = NULL;
755
756         sc = ifp->if_softc;
757         KUE_LOCK(sc);
758
759         if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
760                 KUE_UNLOCK(sc);
761                 return;
762         }
763
764         IF_DEQUEUE(&ifp->if_snd, m_head);
765         if (m_head == NULL) {
766                 KUE_UNLOCK(sc);
767                 return;
768         }
769
770         if (kue_encap(sc, m_head, 0)) {
771                 IF_PREPEND(&ifp->if_snd, m_head);
772                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
773                 KUE_UNLOCK(sc);
774                 return;
775         }
776
777         /*
778          * If there's a BPF listener, bounce a copy of this frame
779          * to him.
780          */
781         BPF_MTAP(ifp, m_head);
782
783         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
784
785         /*
786          * Set a timeout in case the chip goes out to lunch.
787          */
788         ifp->if_timer = 5;
789         KUE_UNLOCK(sc);
790
791         return;
792 }
793
794 Static void
795 kue_init(void *xsc)
796 {
797         struct kue_softc        *sc = xsc;
798         struct ifnet            *ifp = sc->kue_ifp;
799         struct ue_chain *c;
800         usbd_status             err;
801         int                     i;
802
803         KUE_LOCK(sc);
804
805         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
806                 KUE_UNLOCK(sc);
807                 return;
808         }
809
810         /* Set MAC address */
811         kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC,
812             0, IF_LLADDR(sc->kue_ifp), ETHER_ADDR_LEN);
813
814         sc->kue_rxfilt = KUE_RXFILT_UNICAST|KUE_RXFILT_BROADCAST;
815
816          /* If we want promiscuous mode, set the allframes bit. */
817         if (ifp->if_flags & IFF_PROMISC)
818                 sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
819
820         kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
821
822         /* I'm not sure how to tune these. */
823 #ifdef notdef
824         /*
825          * Leave this one alone for now; setting it
826          * wrong causes lockups on some machines/controllers.
827          */
828         kue_setword(sc, KUE_CMD_SET_SOFS, 1);
829 #endif
830         kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64);
831
832         /* Init TX ring. */
833         if (usb_ether_tx_list_init(sc, &sc->kue_cdata,
834             sc->kue_udev) == ENOBUFS) {
835                 printf("kue%d: tx list init failed\n", sc->kue_unit);
836                 KUE_UNLOCK(sc);
837                 return;
838         }
839
840         /* Init RX ring. */
841         if (usb_ether_rx_list_init(sc, &sc->kue_cdata,
842             sc->kue_udev) == ENOBUFS) {
843                 printf("kue%d: rx list init failed\n", sc->kue_unit);
844                 KUE_UNLOCK(sc);
845                 return;
846         }
847
848         /* Load the multicast filter. */
849         kue_setmulti(sc);
850
851         /* Open RX and TX pipes. */
852         err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_RX],
853             USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_RX]);
854         if (err) {
855                 printf("kue%d: open rx pipe failed: %s\n",
856                     sc->kue_unit, usbd_errstr(err));
857                 KUE_UNLOCK(sc);
858                 return;
859         }
860
861         err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX],
862             USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_TX]);
863         if (err) {
864                 printf("kue%d: open tx pipe failed: %s\n",
865                     sc->kue_unit, usbd_errstr(err));
866                 KUE_UNLOCK(sc);
867                 return;
868         }
869
870         /* Start up the receive pipe. */
871         for (i = 0; i < UE_RX_LIST_CNT; i++) {
872                 c = &sc->kue_cdata.ue_rx_chain[i];
873                 usbd_setup_xfer(c->ue_xfer, sc->kue_ep[KUE_ENDPT_RX],
874                     c, mtod(c->ue_mbuf, char *), UE_BUFSZ,
875                 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof);
876                 usbd_transfer(c->ue_xfer);
877         }
878
879         ifp->if_drv_flags |= IFF_DRV_RUNNING;
880         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
881
882         KUE_UNLOCK(sc);
883
884         return;
885 }
886
887 Static int
888 kue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
889 {
890         struct kue_softc        *sc = ifp->if_softc;
891         int                     error = 0;
892
893         KUE_LOCK(sc);
894
895         switch(command) {
896         case SIOCSIFFLAGS:
897                 if (ifp->if_flags & IFF_UP) {
898                         if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
899                             ifp->if_flags & IFF_PROMISC &&
900                             !(sc->kue_if_flags & IFF_PROMISC)) {
901                                 sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
902                                 kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
903                                     sc->kue_rxfilt);
904                         } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
905                             !(ifp->if_flags & IFF_PROMISC) &&
906                             sc->kue_if_flags & IFF_PROMISC) {
907                                 sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
908                                 kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
909                                     sc->kue_rxfilt);
910                         } else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
911                                 kue_init(sc);
912                 } else {
913                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
914                                 kue_stop(sc);
915                 }
916                 sc->kue_if_flags = ifp->if_flags;
917                 error = 0;
918                 break;
919         case SIOCADDMULTI:
920         case SIOCDELMULTI:
921                 kue_setmulti(sc);
922                 error = 0;
923                 break;
924         default:
925                 error = ether_ioctl(ifp, command, data);
926                 break;
927         }
928
929         KUE_UNLOCK(sc);
930
931         return(error);
932 }
933
934 Static void
935 kue_watchdog(struct ifnet *ifp)
936 {
937         struct kue_softc        *sc;
938         struct ue_chain *c;
939         usbd_status             stat;
940
941         sc = ifp->if_softc;
942         KUE_LOCK(sc);
943         ifp->if_oerrors++;
944         printf("kue%d: watchdog timeout\n", sc->kue_unit);
945
946         c = &sc->kue_cdata.ue_tx_chain[0];
947         usbd_get_xfer_status(c->ue_xfer, NULL, NULL, NULL, &stat);
948         kue_txeof(c->ue_xfer, c, stat);
949
950         if (ifp->if_snd.ifq_head != NULL)
951                 kue_start(ifp);
952         KUE_UNLOCK(sc);
953
954         return;
955 }
956
957 /*
958  * Stop the adapter and free any mbufs allocated to the
959  * RX and TX lists.
960  */
961 Static void
962 kue_stop(struct kue_softc *sc)
963 {
964         usbd_status             err;
965         struct ifnet            *ifp;
966
967         KUE_LOCK(sc);
968         ifp = sc->kue_ifp;
969         ifp->if_timer = 0;
970
971         /* Stop transfers. */
972         if (sc->kue_ep[KUE_ENDPT_RX] != NULL) {
973                 err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]);
974                 if (err) {
975                         printf("kue%d: abort rx pipe failed: %s\n",
976                         sc->kue_unit, usbd_errstr(err));
977                 }
978                 err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]);
979                 if (err) {
980                         printf("kue%d: close rx pipe failed: %s\n",
981                         sc->kue_unit, usbd_errstr(err));
982                 }
983                 sc->kue_ep[KUE_ENDPT_RX] = NULL;
984         }
985
986         if (sc->kue_ep[KUE_ENDPT_TX] != NULL) {
987                 err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]);
988                 if (err) {
989                         printf("kue%d: abort tx pipe failed: %s\n",
990                         sc->kue_unit, usbd_errstr(err));
991                 }
992                 err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]);
993                 if (err) {
994                         printf("kue%d: close tx pipe failed: %s\n",
995                             sc->kue_unit, usbd_errstr(err));
996                 }
997                 sc->kue_ep[KUE_ENDPT_TX] = NULL;
998         }
999
1000         if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) {
1001                 err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
1002                 if (err) {
1003                         printf("kue%d: abort intr pipe failed: %s\n",
1004                         sc->kue_unit, usbd_errstr(err));
1005                 }
1006                 err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
1007                 if (err) {
1008                         printf("kue%d: close intr pipe failed: %s\n",
1009                             sc->kue_unit, usbd_errstr(err));
1010                 }
1011                 sc->kue_ep[KUE_ENDPT_INTR] = NULL;
1012         }
1013
1014         /* Free RX resources. */
1015         usb_ether_rx_list_free(&sc->kue_cdata);
1016         /* Free TX resources. */
1017         usb_ether_tx_list_free(&sc->kue_cdata);
1018
1019         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1020         KUE_UNLOCK(sc);
1021
1022         return;
1023 }
1024
1025 /*
1026  * Stop all chip I/O so that the kernel's probe routines don't
1027  * get confused by errant DMAs when rebooting.
1028  */
1029 Static void
1030 kue_shutdown(device_ptr_t dev)
1031 {
1032         struct kue_softc        *sc;
1033
1034         sc = device_get_softc(dev);
1035
1036         kue_stop(sc);
1037
1038         return;
1039 }