Annotation of src/sys/dev/usb/if_kue.c, Revision 1.38
1.38 ! enami 1: /* $NetBSD: if_kue.c,v 1.37 2001/01/21 15:55:05 augustss Exp $ */
1.1 augustss 2: /*
3: * Copyright (c) 1997, 1998, 1999, 2000
4: * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed by Bill Paul.
17: * 4. Neither the name of the author nor the names of any co-contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31: * THE POSSIBILITY OF SUCH DAMAGE.
32: *
33: * $FreeBSD: src/sys/dev/usb/if_kue.c,v 1.14 2000/01/14 01:36:15 wpaul Exp $
34: */
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: /*
69: * Ported to NetBSD and somewhat rewritten by Lennart Augustsson.
70: */
71:
1.26 augustss 72: #if defined(__NetBSD__)
1.1 augustss 73: #include "opt_inet.h"
74: #include "opt_ns.h"
75: #include "bpfilter.h"
76: #include "rnd.h"
1.26 augustss 77: #elif defined(__OpenBSD__)
78: #include "bpfilter.h"
1.1 augustss 79: #endif
80:
81: #include <sys/param.h>
82: #include <sys/systm.h>
83: #include <sys/sockio.h>
84: #include <sys/mbuf.h>
85: #include <sys/malloc.h>
86: #include <sys/kernel.h>
87: #include <sys/socket.h>
1.37 augustss 88: #include <sys/device.h>
89: #include <sys/proc.h>
1.1 augustss 90:
1.6 augustss 91: #if NRND > 0
92: #include <sys/rnd.h>
93: #endif
1.1 augustss 94:
95: #include <net/if.h>
1.37 augustss 96: #if defined(__NetBSD__)
1.1 augustss 97: #include <net/if_arp.h>
1.26 augustss 98: #endif
1.1 augustss 99: #include <net/if_dl.h>
100:
1.37 augustss 101: #if NBPFILTER > 0
1.1 augustss 102: #include <net/bpf.h>
103: #endif
104:
1.26 augustss 105: #if defined(__NetBSD__)
106: #include <net/if_ether.h>
1.1 augustss 107: #ifdef INET
108: #include <netinet/in.h>
109: #include <netinet/if_inarp.h>
110: #endif
1.26 augustss 111: #endif /* defined (__NetBSD__) */
112:
113: #if defined(__OpenBSD__)
114: #ifdef INET
115: #include <netinet/in.h>
116: #include <netinet/in_systm.h>
117: #include <netinet/in_var.h>
118: #include <netinet/ip.h>
119: #include <netinet/if_ether.h>
120: #endif
121: #endif /* defined (__OpenBSD__) */
1.1 augustss 122:
123: #ifdef NS
124: #include <netns/ns.h>
125: #include <netns/ns_if.h>
126: #endif
127:
128: #include <dev/usb/usb.h>
129: #include <dev/usb/usbdi.h>
130: #include <dev/usb/usbdi_util.h>
131: #include <dev/usb/usbdevs.h>
132:
133: #include <dev/usb/if_kuereg.h>
134: #include <dev/usb/kue_fw.h>
135:
136: #ifdef KUE_DEBUG
137: #define DPRINTF(x) if (kuedebug) logprintf x
138: #define DPRINTFN(n,x) if (kuedebug >= (n)) logprintf x
139: int kuedebug = 0;
140: #else
141: #define DPRINTF(x)
142: #define DPRINTFN(n,x)
143: #endif
144:
145: /*
146: * Various supported device vendors/products.
147: */
1.35 jdolecek 148: Static const struct kue_type kue_devs[] = {
1.1 augustss 149: { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 },
150: { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT },
151: { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T },
152: { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 },
153: { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET },
154: { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 },
155: { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 },
156: { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 },
1.9 hubertf 157: { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 },
1.1 augustss 158: { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T },
159: { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C },
160: { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB },
1.4 augustss 161: { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T },
1.23 augustss 162: { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT },
1.33 jdolecek 163: { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT },
1.1 augustss 164: { 0, 0 }
165: };
166:
167: USB_DECLARE_DRIVER(kue);
168:
1.29 augustss 169: Static int kue_tx_list_init(struct kue_softc *);
170: Static int kue_rx_list_init(struct kue_softc *);
171: Static int kue_newbuf(struct kue_softc *, struct kue_chain *,struct mbuf *);
172: Static int kue_send(struct kue_softc *, struct mbuf *, int);
173: Static int kue_open_pipes(struct kue_softc *);
174: Static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
175: Static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
176: Static void kue_start(struct ifnet *);
177: Static int kue_ioctl(struct ifnet *, u_long, caddr_t);
178: Static void kue_init(void *);
179: Static void kue_stop(struct kue_softc *);
180: Static void kue_watchdog(struct ifnet *);
181:
182: Static void kue_setmulti(struct kue_softc *);
183: Static void kue_reset(struct kue_softc *);
184:
185: Static usbd_status kue_ctl(struct kue_softc *, int, u_int8_t,
1.37 augustss 186: u_int16_t, void *, u_int32_t);
1.29 augustss 187: Static usbd_status kue_setword(struct kue_softc *, u_int8_t, u_int16_t);
188: Static int kue_load_fw(struct kue_softc *);
1.1 augustss 189:
1.24 augustss 190: Static usbd_status
1.29 augustss 191: kue_setword(struct kue_softc *sc, u_int8_t breq, u_int16_t word)
1.1 augustss 192: {
193: usb_device_request_t req;
194:
195: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
196:
197: req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
198: req.bRequest = breq;
199: USETW(req.wValue, word);
200: USETW(req.wIndex, 0);
201: USETW(req.wLength, 0);
202:
1.37 augustss 203: return (usbd_do_request(sc->kue_udev, &req, NULL));
1.1 augustss 204: }
205:
1.24 augustss 206: Static usbd_status
1.29 augustss 207: kue_ctl(struct kue_softc *sc, int rw, u_int8_t breq, u_int16_t val,
1.37 augustss 208: void *data, u_int32_t len)
1.1 augustss 209: {
210: usb_device_request_t req;
211:
212: DPRINTFN(10,("%s: %s: enter, len=%d\n", USBDEVNAME(sc->kue_dev),
213: __FUNCTION__, len));
214:
215: if (rw == KUE_CTL_WRITE)
216: req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
217: else
218: req.bmRequestType = UT_READ_VENDOR_DEVICE;
219:
220: req.bRequest = breq;
221: USETW(req.wValue, val);
222: USETW(req.wIndex, 0);
223: USETW(req.wLength, len);
224:
1.37 augustss 225: return (usbd_do_request(sc->kue_udev, &req, data));
1.1 augustss 226: }
227:
1.24 augustss 228: Static int
1.29 augustss 229: kue_load_fw(struct kue_softc *sc)
1.1 augustss 230: {
1.36 augustss 231: usb_device_descriptor_t dd;
1.1 augustss 232: usbd_status err;
233:
234: DPRINTFN(1,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
235:
236: /*
237: * First, check if we even need to load the firmware.
238: * If the device was still attached when the system was
239: * rebooted, it may already have firmware loaded in it.
240: * If this is the case, we don't need to do it again.
241: * And in fact, if we try to load it again, we'll hang,
242: * so we have to avoid this condition if we don't want
243: * to look stupid.
244: *
1.36 augustss 245: * We can test this quickly by checking the bcdRevision
246: * code. The NIC will return a different revision code if
247: * it's probed while the firmware is still loaded and
248: * running.
249: */
250: if (usbd_get_device_desc(sc->kue_udev, &dd))
251: return (EIO);
252: if (UGETW(dd.bcdDevice) == KUE_WARM_REV) {
1.1 augustss 253: printf("%s: warm boot, no firmware download\n",
254: USBDEVNAME(sc->kue_dev));
255: return (0);
256: }
257:
258: printf("%s: cold boot, downloading firmware\n",
259: USBDEVNAME(sc->kue_dev));
260:
261: /* Load code segment */
262: DPRINTFN(1,("%s: kue_load_fw: download code_seg\n",
263: USBDEVNAME(sc->kue_dev)));
264: err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
1.37 augustss 265: 0, (void *)kue_code_seg, sizeof(kue_code_seg));
1.1 augustss 266: if (err) {
267: printf("%s: failed to load code segment: %s\n",
268: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
269: return (EIO);
270: }
271:
272: /* Load fixup segment */
273: DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n",
274: USBDEVNAME(sc->kue_dev)));
275: err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
1.37 augustss 276: 0, (void *)kue_fix_seg, sizeof(kue_fix_seg));
1.1 augustss 277: if (err) {
278: printf("%s: failed to load fixup segment: %s\n",
279: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
280: return (EIO);
281: }
282:
283: /* Send trigger command. */
284: DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n",
285: USBDEVNAME(sc->kue_dev)));
286: err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
1.37 augustss 287: 0, (void *)kue_trig_seg, sizeof(kue_trig_seg));
1.1 augustss 288: if (err) {
289: printf("%s: failed to load trigger segment: %s\n",
290: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
291: return (EIO);
292: }
293:
294: usbd_delay_ms(sc->kue_udev, 10);
295:
296: /*
297: * Reload device descriptor.
298: * Why? The chip without the firmware loaded returns
299: * one revision code. The chip with the firmware
300: * loaded and running returns a *different* revision
301: * code. This confuses the quirk mechanism, which is
302: * dependent on the revision data.
303: */
304: (void)usbd_reload_device_desc(sc->kue_udev);
305:
306: DPRINTFN(1,("%s: %s: done\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
307:
308: /* Reset the adapter. */
309: kue_reset(sc);
310:
311: return (0);
312: }
313:
1.24 augustss 314: Static void
1.29 augustss 315: kue_setmulti(struct kue_softc *sc)
1.1 augustss 316: {
317: struct ifnet *ifp = GET_IFP(sc);
318: struct ether_multi *enm;
319: struct ether_multistep step;
320: int i;
321:
322: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
323:
1.38 ! enami 324: if (ifp->if_flags & IFF_PROMISC) {
! 325: allmulti:
! 326: ifp->if_flags |= IFF_ALLMULTI;
1.1 augustss 327: sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
328: sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
329: kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
330: return;
331: }
332:
333: sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI;
334:
335: i = 0;
1.26 augustss 336: #if defined (__NetBSD__)
1.1 augustss 337: ETHER_FIRST_MULTI(step, &sc->kue_ec, enm);
1.26 augustss 338: #else
339: ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
340: #endif
1.1 augustss 341: while (enm != NULL) {
1.38 ! enami 342: if (i == KUE_MCFILTCNT(sc) ||
! 343: memcmp(enm->enm_addrlo, enm->enm_addrhi,
! 344: ETHER_ADDR_LEN) != 0)
! 345: goto allmulti;
! 346:
1.1 augustss 347: memcpy(KUE_MCFILT(sc, i), enm->enm_addrlo, ETHER_ADDR_LEN);
348: ETHER_NEXT_MULTI(step, enm);
349: i++;
350: }
351:
1.38 ! enami 352: ifp->if_flags &= ~IFF_ALLMULTI;
! 353:
! 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);
1.1 augustss 357:
358: kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
359: }
360:
361: /*
362: * Issue a SET_CONFIGURATION command to reset the MAC. This should be
363: * done after the firmware is loaded into the adapter in order to
364: * bring it into proper operation.
365: */
1.24 augustss 366: Static void
1.29 augustss 367: kue_reset(struct kue_softc *sc)
1.1 augustss 368: {
369: usbd_status err;
370:
371: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
372:
1.31 augustss 373: err = usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 1);
1.1 augustss 374: if (err)
375: printf("%s: reset failed\n", USBDEVNAME(sc->kue_dev));
376:
377: /* Wait a little while for the chip to get its brains in order. */
378: usbd_delay_ms(sc->kue_udev, 10);
379: }
380:
381: /*
382: * Probe for a KLSI chip.
383: */
384: USB_MATCH(kue)
385: {
386: USB_MATCH_START(kue, uaa);
1.35 jdolecek 387: const struct kue_type *t;
1.1 augustss 388:
389: DPRINTFN(25,("kue_match: enter\n"));
390:
391: if (uaa->iface != NULL)
392: return (UMATCH_NONE);
393:
394: for (t = kue_devs; t->kue_vid != 0; t++)
395: if (uaa->vendor == t->kue_vid && uaa->product == t->kue_did)
396: return (UMATCH_VENDOR_PRODUCT);
397:
398: return (UMATCH_NONE);
399: }
400:
401: /*
402: * Attach the interface. Allocate softc structures, do
403: * setup and ethernet/BPF attach.
404: */
405: USB_ATTACH(kue)
406: {
407: USB_ATTACH_START(kue, sc, uaa);
408: char devinfo[1024];
409: int s;
410: struct ifnet *ifp;
411: usbd_device_handle dev = uaa->device;
412: usbd_interface_handle iface;
413: usbd_status err;
414: usb_interface_descriptor_t *id;
415: usb_endpoint_descriptor_t *ed;
416: int i;
417:
418: DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev));
419:
420: usbd_devinfo(dev, 0, devinfo);
421: USB_ATTACH_SETUP;
422: printf("%s: %s\n", USBDEVNAME(sc->kue_dev), devinfo);
423:
1.31 augustss 424: err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1);
1.1 augustss 425: if (err) {
426: printf("%s: setting config no failed\n",
427: USBDEVNAME(sc->kue_dev));
428: USB_ATTACH_ERROR_RETURN;
429: }
430:
431: sc->kue_udev = dev;
432: sc->kue_product = uaa->product;
433: sc->kue_vendor = uaa->vendor;
434:
435: /* Load the firmware into the NIC. */
436: if (kue_load_fw(sc)) {
437: printf("%s: loading firmware failed\n",
438: USBDEVNAME(sc->kue_dev));
439: USB_ATTACH_ERROR_RETURN;
440: }
441:
442: err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &iface);
443: if (err) {
444: printf("%s: getting interface handle failed\n",
445: USBDEVNAME(sc->kue_dev));
446: USB_ATTACH_ERROR_RETURN;
447: }
448:
449: sc->kue_iface = iface;
450: id = usbd_get_interface_descriptor(iface);
451:
452: /* Find endpoints. */
453: for (i = 0; i < id->bNumEndpoints; i++) {
454: ed = usbd_interface2endpoint_descriptor(iface, i);
455: if (ed == NULL) {
456: printf("%s: couldn't get ep %d\n",
457: USBDEVNAME(sc->kue_dev), i);
458: USB_ATTACH_ERROR_RETURN;
459: }
460: if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1.12 augustss 461: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1.1 augustss 462: sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
463: } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1.12 augustss 464: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1.1 augustss 465: sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
466: } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1.12 augustss 467: UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
1.1 augustss 468: sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress;
469: }
470: }
471:
472: if (sc->kue_ed[KUE_ENDPT_RX] == 0 || sc->kue_ed[KUE_ENDPT_TX] == 0) {
473: printf("%s: missing endpoint\n", USBDEVNAME(sc->kue_dev));
474: USB_ATTACH_ERROR_RETURN;
475: }
476:
477: /* Read ethernet descriptor */
478: err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
1.18 augustss 479: 0, &sc->kue_desc, sizeof(sc->kue_desc));
1.1 augustss 480: if (err) {
481: printf("%s: could not read Ethernet descriptor\n",
482: USBDEVNAME(sc->kue_dev));
483: USB_ATTACH_ERROR_RETURN;
484: }
485:
486: sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
487: M_USBDEV, M_NOWAIT);
488: if (sc->kue_mcfilters == NULL) {
489: printf("%s: no memory for multicast filter buffer\n",
490: USBDEVNAME(sc->kue_dev));
491: USB_ATTACH_ERROR_RETURN;
492: }
493:
494: s = splimp();
495:
496: /*
497: * A KLSI chip was detected. Inform the world.
498: */
499: printf("%s: Ethernet address %s\n", USBDEVNAME(sc->kue_dev),
500: ether_sprintf(sc->kue_desc.kue_macaddr));
501:
502: /* Initialize interface info.*/
503: ifp = GET_IFP(sc);
504: ifp->if_softc = sc;
505: ifp->if_mtu = ETHERMTU;
506: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
507: ifp->if_ioctl = kue_ioctl;
508: ifp->if_start = kue_start;
509: ifp->if_watchdog = kue_watchdog;
1.27 augustss 510: #if defined(__OpenBSD__)
511: ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
512: #endif
1.1 augustss 513: strncpy(ifp->if_xname, USBDEVNAME(sc->kue_dev), IFNAMSIZ);
514:
1.34 thorpej 515: IFQ_SET_READY(&ifp->if_snd);
516:
1.1 augustss 517: /* Attach the interface. */
518: if_attach(ifp);
1.26 augustss 519: Ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
1.6 augustss 520: #if NRND > 0
1.1 augustss 521: rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->kue_dev),
522: RND_TYPE_NET, 0);
523: #endif
524:
1.8 augustss 525: sc->kue_attached = 1;
1.1 augustss 526: splx(s);
1.6 augustss 527:
528: usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->kue_udev,
529: USBDEV(sc->kue_dev));
530:
1.1 augustss 531: USB_ATTACH_SUCCESS_RETURN;
532: }
533:
534: USB_DETACH(kue)
535: {
536: USB_DETACH_START(kue, sc);
1.6 augustss 537: struct ifnet *ifp = GET_IFP(sc);
1.1 augustss 538: int s;
539:
1.6 augustss 540: s = splusb(); /* XXX why? */
1.1 augustss 541:
1.8 augustss 542: if (sc->kue_mcfilters != NULL) {
543: free(sc->kue_mcfilters, M_USBDEV);
544: sc->kue_mcfilters = NULL;
545: }
546:
547: if (!sc->kue_attached) {
548: /* Detached before attached finished, so just bail out. */
549: splx(s);
550: return (0);
551: }
552:
1.6 augustss 553: if (ifp->if_flags & IFF_RUNNING)
554: kue_stop(sc);
1.1 augustss 555:
1.5 thorpej 556: #if defined(__NetBSD__)
1.6 augustss 557: #if NRND > 0
558: rnd_detach_source(&sc->rnd_source);
1.5 thorpej 559: #endif
1.6 augustss 560: ether_ifdetach(ifp);
1.5 thorpej 561: #endif /* __NetBSD__ */
1.1 augustss 562:
1.6 augustss 563: if_detach(ifp);
564:
565: #ifdef DIAGNOSTIC
566: if (sc->kue_ep[KUE_ENDPT_TX] != NULL ||
567: sc->kue_ep[KUE_ENDPT_RX] != NULL ||
568: sc->kue_ep[KUE_ENDPT_INTR] != NULL)
569: printf("%s: detach has active endpoints\n",
570: USBDEVNAME(sc->kue_dev));
571: #endif
1.1 augustss 572:
1.8 augustss 573: sc->kue_attached = 0;
1.1 augustss 574: splx(s);
575:
576: return (0);
577: }
578:
579: int
1.29 augustss 580: kue_activate(device_ptr_t self, enum devact act)
1.1 augustss 581: {
582: struct kue_softc *sc = (struct kue_softc *)self;
583:
584: DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
585:
586: switch (act) {
587: case DVACT_ACTIVATE:
588: return (EOPNOTSUPP);
589: break;
590:
591: case DVACT_DEACTIVATE:
1.26 augustss 592: #if defined(__NetBSD__)
1.5 thorpej 593: /* Deactivate the interface. */
594: if_deactivate(&sc->kue_ec.ec_if);
1.26 augustss 595: #endif
1.1 augustss 596: sc->kue_dying = 1;
597: break;
598: }
599: return (0);
600: }
601:
602: /*
603: * Initialize an RX descriptor and attach an MBUF cluster.
604: */
1.24 augustss 605: Static int
1.29 augustss 606: kue_newbuf(struct kue_softc *sc, struct kue_chain *c, struct mbuf *m)
1.1 augustss 607: {
608: struct mbuf *m_new = NULL;
609:
610: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
611:
612: if (m == NULL) {
613: MGETHDR(m_new, M_DONTWAIT, MT_DATA);
614: if (m_new == NULL) {
615: printf("%s: no memory for rx list "
616: "-- packet dropped!\n", USBDEVNAME(sc->kue_dev));
617: return (ENOBUFS);
618: }
619:
620: MCLGET(m_new, M_DONTWAIT);
621: if (!(m_new->m_flags & M_EXT)) {
622: printf("%s: no memory for rx list "
623: "-- packet dropped!\n", USBDEVNAME(sc->kue_dev));
624: m_freem(m_new);
625: return (ENOBUFS);
626: }
627: m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
628: } else {
629: m_new = m;
630: m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
631: m_new->m_data = m_new->m_ext.ext_buf;
632: }
633:
634: c->kue_mbuf = m_new;
635:
636: return (0);
637: }
638:
1.24 augustss 639: Static int
1.29 augustss 640: kue_rx_list_init(struct kue_softc *sc)
1.1 augustss 641: {
642: struct kue_cdata *cd;
643: struct kue_chain *c;
644: int i;
645:
646: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
647:
648: cd = &sc->kue_cdata;
649: for (i = 0; i < KUE_RX_LIST_CNT; i++) {
650: c = &cd->kue_rx_chain[i];
651: c->kue_sc = sc;
652: c->kue_idx = i;
653: if (kue_newbuf(sc, c, NULL) == ENOBUFS)
654: return (ENOBUFS);
655: if (c->kue_xfer == NULL) {
656: c->kue_xfer = usbd_alloc_xfer(sc->kue_udev);
657: if (c->kue_xfer == NULL)
658: return (ENOBUFS);
659: c->kue_buf = usbd_alloc_buffer(c->kue_xfer, KUE_BUFSZ);
660: if (c->kue_buf == NULL)
661: return (ENOBUFS); /* XXX free xfer */
662: }
663: }
664:
665: return (0);
666: }
667:
1.24 augustss 668: Static int
1.29 augustss 669: kue_tx_list_init(struct kue_softc *sc)
1.1 augustss 670: {
671: struct kue_cdata *cd;
672: struct kue_chain *c;
673: int i;
674:
675: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
676:
677: cd = &sc->kue_cdata;
678: for (i = 0; i < KUE_TX_LIST_CNT; i++) {
679: c = &cd->kue_tx_chain[i];
680: c->kue_sc = sc;
681: c->kue_idx = i;
682: c->kue_mbuf = NULL;
683: if (c->kue_xfer == NULL) {
684: c->kue_xfer = usbd_alloc_xfer(sc->kue_udev);
685: if (c->kue_xfer == NULL)
686: return (ENOBUFS);
687: c->kue_buf = usbd_alloc_buffer(c->kue_xfer, KUE_BUFSZ);
688: if (c->kue_buf == NULL)
689: return (ENOBUFS);
690: }
691: }
692:
693: return (0);
694: }
695:
696: /*
697: * A frame has been uploaded: pass the resulting mbuf chain up to
698: * the higher level protocols.
699: */
1.24 augustss 700: Static void
1.29 augustss 701: kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1.1 augustss 702: {
703: struct kue_chain *c = priv;
704: struct kue_softc *sc = c->kue_sc;
705: struct ifnet *ifp = GET_IFP(sc);
706: struct mbuf *m;
707: int total_len = 0;
708: int s;
709:
710: DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev),
711: __FUNCTION__, status));
712:
1.6 augustss 713: if (sc->kue_dying)
714: return;
715:
1.1 augustss 716: if (!(ifp->if_flags & IFF_RUNNING))
717: return;
718:
719: if (status != USBD_NORMAL_COMPLETION) {
720: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
721: return;
1.11 augustss 722: sc->kue_rx_errs++;
723: if (usbd_ratecheck(&sc->kue_rx_notice)) {
724: printf("%s: %u usb errors on rx: %s\n",
725: USBDEVNAME(sc->kue_dev), sc->kue_rx_errs,
726: usbd_errstr(status));
727: sc->kue_rx_errs = 0;
728: }
1.1 augustss 729: if (status == USBD_STALLED)
730: usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_RX]);
731: goto done;
732: }
733:
734: usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
735:
736: DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", USBDEVNAME(sc->kue_dev),
737: __FUNCTION__, total_len,
738: UGETW(mtod(c->kue_mbuf, u_int8_t *))));
739:
740: if (total_len <= 1)
741: goto done;
742:
1.18 augustss 743: m = c->kue_mbuf;
1.1 augustss 744: /* copy data to mbuf */
745: memcpy(mtod(m, char*), c->kue_buf, total_len);
746:
747: /* No errors; receive the packet. */
748: total_len = UGETW(mtod(m, u_int8_t *));
749: m_adj(m, sizeof(u_int16_t));
750:
751: if (total_len < sizeof(struct ether_header)) {
752: ifp->if_ierrors++;
753: goto done;
754: }
755:
756: ifp->if_ipackets++;
757: m->m_pkthdr.len = m->m_len = total_len;
758:
759: m->m_pkthdr.rcvif = ifp;
760:
761: s = splimp();
762:
763: /* XXX ugly */
764: if (kue_newbuf(sc, c, NULL) == ENOBUFS) {
765: ifp->if_ierrors++;
766: goto done1;
767: }
768:
1.10 augustss 769: #if NBPFILTER > 0
1.1 augustss 770: /*
771: * Handle BPF listeners. Let the BPF user see the packet, but
772: * don't pass it up to the ether_input() layer unless it's
773: * a broadcast packet, multicast packet, matches our ethernet
774: * address or the interface is in promiscuous mode.
775: */
1.30 thorpej 776: if (ifp->if_bpf)
1.37 augustss 777: bpf_mtap(ifp->if_bpf, m);
1.10 augustss 778: #endif
1.1 augustss 779:
780: DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->kue_dev),
781: __FUNCTION__, m->m_len));
1.26 augustss 782: IF_INPUT(ifp, m);
1.1 augustss 783: done1:
784: splx(s);
785:
786: done:
787:
788: /* Setup new transfer. */
789: usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
790: c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
791: USBD_NO_TIMEOUT, kue_rxeof);
792: usbd_transfer(c->kue_xfer);
793:
794: DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->kue_dev),
795: __FUNCTION__));
796: }
797:
798: /*
799: * A frame was downloaded to the chip. It's safe for us to clean up
800: * the list buffers.
801: */
802:
1.24 augustss 803: Static void
1.29 augustss 804: kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1.1 augustss 805: {
806: struct kue_chain *c = priv;
807: struct kue_softc *sc = c->kue_sc;
808: struct ifnet *ifp = GET_IFP(sc);
809: int s;
810:
1.6 augustss 811: if (sc->kue_dying)
812: return;
813:
1.1 augustss 814: s = splimp();
815:
816: DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev),
817: __FUNCTION__, status));
818:
819: ifp->if_timer = 0;
820: ifp->if_flags &= ~IFF_OACTIVE;
821:
822: if (status != USBD_NORMAL_COMPLETION) {
823: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
824: splx(s);
825: return;
826: }
827: ifp->if_oerrors++;
828: printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->kue_dev),
829: usbd_errstr(status));
830: if (status == USBD_STALLED)
831: usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]);
832: splx(s);
833: return;
834: }
835:
836: ifp->if_opackets++;
837:
838: m_freem(c->kue_mbuf);
839: c->kue_mbuf = NULL;
840:
1.34 thorpej 841: if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1 augustss 842: kue_start(ifp);
843:
844: splx(s);
845: }
846:
1.24 augustss 847: Static int
1.29 augustss 848: kue_send(struct kue_softc *sc, struct mbuf *m, int idx)
1.1 augustss 849: {
850: int total_len;
851: struct kue_chain *c;
852: usbd_status err;
853:
854: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
855:
856: c = &sc->kue_cdata.kue_tx_chain[idx];
857:
858: /*
859: * Copy the mbuf data into a contiguous buffer, leaving two
860: * bytes at the beginning to hold the frame length.
861: */
862: m_copydata(m, 0, m->m_pkthdr.len, c->kue_buf + 2);
863: c->kue_mbuf = m;
864:
865: total_len = m->m_pkthdr.len + 2;
866: /* XXX what's this? */
867: total_len += 64 - (total_len % 64);
868:
869: /* Frame length is specified in the first 2 bytes of the buffer. */
870: c->kue_buf[0] = (u_int8_t)m->m_pkthdr.len;
871: c->kue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
872:
873: usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_TX],
1.37 augustss 874: c, c->kue_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT,
875: kue_txeof);
1.1 augustss 876:
877: /* Transmit */
878: err = usbd_transfer(c->kue_xfer);
879: if (err != USBD_IN_PROGRESS) {
1.28 augustss 880: printf("%s: kue_send error=%s\n", USBDEVNAME(sc->kue_dev),
881: usbd_errstr(err));
1.1 augustss 882: kue_stop(sc);
883: return (EIO);
884: }
885:
886: sc->kue_cdata.kue_tx_cnt++;
887:
888: return (0);
889: }
890:
1.24 augustss 891: Static void
1.29 augustss 892: kue_start(struct ifnet *ifp)
1.1 augustss 893: {
894: struct kue_softc *sc = ifp->if_softc;
895: struct mbuf *m_head = NULL;
896:
897: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
898:
1.6 augustss 899: if (sc->kue_dying)
900: return;
901:
1.1 augustss 902: if (ifp->if_flags & IFF_OACTIVE)
903: return;
904:
1.34 thorpej 905: IFQ_POLL(&ifp->if_snd, m_head);
1.1 augustss 906: if (m_head == NULL)
907: return;
908:
909: if (kue_send(sc, m_head, 0)) {
910: ifp->if_flags |= IFF_OACTIVE;
911: return;
912: }
913:
1.34 thorpej 914: IFQ_DEQUEUE(&ifp->if_snd, m_head);
915:
1.10 augustss 916: #if NBPFILTER > 0
1.1 augustss 917: /*
918: * If there's a BPF listener, bounce a copy of this frame
919: * to him.
920: */
921: if (ifp->if_bpf)
1.37 augustss 922: bpf_mtap(ifp->if_bpf, m_head);
1.10 augustss 923: #endif
1.1 augustss 924:
925: ifp->if_flags |= IFF_OACTIVE;
926:
927: /*
928: * Set a timeout in case the chip goes out to lunch.
929: */
1.37 augustss 930: ifp->if_timer = 6;
1.1 augustss 931: }
932:
1.24 augustss 933: Static void
1.29 augustss 934: kue_init(void *xsc)
1.1 augustss 935: {
936: struct kue_softc *sc = xsc;
937: struct ifnet *ifp = GET_IFP(sc);
938: int s;
939: u_char *eaddr;
940:
941: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
942:
943: if (ifp->if_flags & IFF_RUNNING)
944: return;
945:
946: s = splimp();
947:
1.37 augustss 948: #if defined(__NetBSD__)
949: eaddr = LLADDR(ifp->if_sadl);
950: #else
1.1 augustss 951: eaddr = sc->arpcom.ac_enaddr;
1.26 augustss 952: #endif /* defined(__NetBSD__) */
1.1 augustss 953: /* Set MAC address */
954: kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN);
955:
956: sc->kue_rxfilt = KUE_RXFILT_UNICAST | KUE_RXFILT_BROADCAST;
957:
958: /* If we want promiscuous mode, set the allframes bit. */
959: if (ifp->if_flags & IFF_PROMISC)
960: sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
961:
962: kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
963:
964: /* I'm not sure how to tune these. */
965: #if 0
966: /*
967: * Leave this one alone for now; setting it
968: * wrong causes lockups on some machines/controllers.
969: */
970: kue_setword(sc, KUE_CMD_SET_SOFS, 1);
971: #endif
972: kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64);
973:
974: /* Init TX ring. */
975: if (kue_tx_list_init(sc) == ENOBUFS) {
976: printf("%s: tx list init failed\n", USBDEVNAME(sc->kue_dev));
977: splx(s);
978: return;
979: }
980:
981: /* Init RX ring. */
982: if (kue_rx_list_init(sc) == ENOBUFS) {
983: printf("%s: rx list init failed\n", USBDEVNAME(sc->kue_dev));
984: splx(s);
985: return;
986: }
987:
988: /* Load the multicast filter. */
989: kue_setmulti(sc);
990:
991: if (sc->kue_ep[KUE_ENDPT_RX] == NULL) {
992: if (kue_open_pipes(sc)) {
993: splx(s);
994: return;
995: }
996: }
997:
998: ifp->if_flags |= IFF_RUNNING;
999: ifp->if_flags &= ~IFF_OACTIVE;
1000:
1001: splx(s);
1002: }
1003:
1.24 augustss 1004: Static int
1.29 augustss 1005: kue_open_pipes(struct kue_softc *sc)
1.1 augustss 1006: {
1007: usbd_status err;
1008: struct kue_chain *c;
1009: int i;
1010:
1011: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1012:
1013: /* Open RX and TX pipes. */
1014: err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_RX],
1015: USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_RX]);
1016: if (err) {
1017: printf("%s: open rx pipe failed: %s\n",
1018: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1019: return (EIO);
1020: }
1021:
1022: err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX],
1023: USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_TX]);
1024: if (err) {
1025: printf("%s: open tx pipe failed: %s\n",
1026: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1027: return (EIO);
1028: }
1029:
1030: /* Start up the receive pipe. */
1031: for (i = 0; i < KUE_RX_LIST_CNT; i++) {
1032: c = &sc->kue_cdata.kue_rx_chain[i];
1033: usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
1034: c, c->kue_buf, KUE_BUFSZ,
1035: USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1036: kue_rxeof);
1037: DPRINTFN(5,("%s: %s: start read\n", USBDEVNAME(sc->kue_dev),
1038: __FUNCTION__));
1.18 augustss 1039: usbd_transfer(c->kue_xfer);
1.1 augustss 1040: }
1041:
1042: return (0);
1043: }
1044:
1.24 augustss 1045: Static int
1.29 augustss 1046: kue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1.1 augustss 1047: {
1048: struct kue_softc *sc = ifp->if_softc;
1049: struct ifaddr *ifa = (struct ifaddr *)data;
1050: struct ifreq *ifr = (struct ifreq *)data;
1051: int s, error = 0;
1052:
1053: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1054:
1.6 augustss 1055: if (sc->kue_dying)
1056: return (EIO);
1057:
1.37 augustss 1058: #ifdef DIAGNOSTIC
1059: if (!curproc) {
1060: printf("%s: no proc!!\n", USBDEVNAME(sc->kue_dev));
1061: return EIO;
1062: }
1063: #endif
1064:
1.1 augustss 1065: s = splimp();
1066:
1067: switch(command) {
1068: case SIOCSIFADDR:
1069: ifp->if_flags |= IFF_UP;
1070: kue_init(sc);
1071:
1072: switch (ifa->ifa_addr->sa_family) {
1073: #ifdef INET
1074: case AF_INET:
1.26 augustss 1075: #if defined(__NetBSD__)
1.1 augustss 1076: arp_ifinit(ifp, ifa);
1.26 augustss 1077: #else
1078: arp_ifinit(&sc->arpcom, ifa);
1079: #endif
1.1 augustss 1080: break;
1081: #endif /* INET */
1082: #ifdef NS
1083: case AF_NS:
1084: {
1085: struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1086:
1087: if (ns_nullhost(*ina))
1088: ina->x_host = *(union ns_host *)
1089: LLADDR(ifp->if_sadl);
1090: else
1091: memcpy(LLADDR(ifp->if_sadl),
1092: ina->x_host.c_host,
1093: ifp->if_addrlen);
1094: break;
1095: }
1096: #endif /* NS */
1097: }
1098: break;
1099:
1100: case SIOCSIFMTU:
1101: if (ifr->ifr_mtu > ETHERMTU)
1102: error = EINVAL;
1103: else
1104: ifp->if_mtu = ifr->ifr_mtu;
1105: break;
1106:
1107: case SIOCSIFFLAGS:
1108: if (ifp->if_flags & IFF_UP) {
1109: if (ifp->if_flags & IFF_RUNNING &&
1110: ifp->if_flags & IFF_PROMISC &&
1111: !(sc->kue_if_flags & IFF_PROMISC)) {
1112: sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
1113: kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
1114: sc->kue_rxfilt);
1115: } else if (ifp->if_flags & IFF_RUNNING &&
1116: !(ifp->if_flags & IFF_PROMISC) &&
1117: sc->kue_if_flags & IFF_PROMISC) {
1118: sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
1119: kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
1120: sc->kue_rxfilt);
1121: } else if (!(ifp->if_flags & IFF_RUNNING))
1122: kue_init(sc);
1123: } else {
1124: if (ifp->if_flags & IFF_RUNNING)
1125: kue_stop(sc);
1126: }
1127: sc->kue_if_flags = ifp->if_flags;
1128: error = 0;
1129: break;
1130: case SIOCADDMULTI:
1131: case SIOCDELMULTI:
1132: kue_setmulti(sc);
1133: error = 0;
1134: break;
1135: default:
1136: error = EINVAL;
1137: break;
1138: }
1139:
1140: splx(s);
1141:
1142: return (error);
1143: }
1144:
1.24 augustss 1145: Static void
1.29 augustss 1146: kue_watchdog(struct ifnet *ifp)
1.1 augustss 1147: {
1148: struct kue_softc *sc = ifp->if_softc;
1.37 augustss 1149: struct kue_chain *c;
1150: usbd_status stat;
1151: int s;
1.1 augustss 1152:
1153: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1.6 augustss 1154:
1155: if (sc->kue_dying)
1156: return;
1.1 augustss 1157:
1158: ifp->if_oerrors++;
1159: printf("%s: watchdog timeout\n", USBDEVNAME(sc->kue_dev));
1160:
1.37 augustss 1161: s = splusb();
1162: c = &sc->kue_cdata.kue_tx_chain[0];
1163: usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat);
1164: kue_txeof(c->kue_xfer, c, stat);
1.1 augustss 1165:
1.34 thorpej 1166: if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1 augustss 1167: kue_start(ifp);
1.37 augustss 1168: splx(s);
1.1 augustss 1169: }
1170:
1171: /*
1172: * Stop the adapter and free any mbufs allocated to the
1173: * RX and TX lists.
1174: */
1.24 augustss 1175: Static void
1.29 augustss 1176: kue_stop(struct kue_softc *sc)
1.1 augustss 1177: {
1178: usbd_status err;
1179: struct ifnet *ifp;
1180: int i;
1181:
1182: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1183:
1184: ifp = GET_IFP(sc);
1185: ifp->if_timer = 0;
1186:
1187: /* Stop transfers. */
1188: if (sc->kue_ep[KUE_ENDPT_RX] != NULL) {
1189: err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]);
1190: if (err) {
1191: printf("%s: abort rx pipe failed: %s\n",
1192: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1193: }
1194: err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]);
1195: if (err) {
1196: printf("%s: close rx pipe failed: %s\n",
1197: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1198: }
1199: sc->kue_ep[KUE_ENDPT_RX] = NULL;
1200: }
1201:
1202: if (sc->kue_ep[KUE_ENDPT_TX] != NULL) {
1203: err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]);
1204: if (err) {
1205: printf("%s: abort tx pipe failed: %s\n",
1206: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1207: }
1208: err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]);
1209: if (err) {
1210: printf("%s: close tx pipe failed: %s\n",
1211: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1212: }
1213: sc->kue_ep[KUE_ENDPT_TX] = NULL;
1214: }
1215:
1216: if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) {
1217: err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
1218: if (err) {
1219: printf("%s: abort intr pipe failed: %s\n",
1220: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1221: }
1222: err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
1223: if (err) {
1224: printf("%s: close intr pipe failed: %s\n",
1225: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1226: }
1227: sc->kue_ep[KUE_ENDPT_INTR] = NULL;
1228: }
1229:
1230: /* Free RX resources. */
1231: for (i = 0; i < KUE_RX_LIST_CNT; i++) {
1232: if (sc->kue_cdata.kue_rx_chain[i].kue_mbuf != NULL) {
1233: m_freem(sc->kue_cdata.kue_rx_chain[i].kue_mbuf);
1234: sc->kue_cdata.kue_rx_chain[i].kue_mbuf = NULL;
1235: }
1236: if (sc->kue_cdata.kue_rx_chain[i].kue_xfer != NULL) {
1237: usbd_free_xfer(sc->kue_cdata.kue_rx_chain[i].kue_xfer);
1238: sc->kue_cdata.kue_rx_chain[i].kue_xfer = NULL;
1239: }
1240: }
1241:
1242: /* Free TX resources. */
1243: for (i = 0; i < KUE_TX_LIST_CNT; i++) {
1244: if (sc->kue_cdata.kue_tx_chain[i].kue_mbuf != NULL) {
1245: m_freem(sc->kue_cdata.kue_tx_chain[i].kue_mbuf);
1246: sc->kue_cdata.kue_tx_chain[i].kue_mbuf = NULL;
1247: }
1248: if (sc->kue_cdata.kue_tx_chain[i].kue_xfer != NULL) {
1249: usbd_free_xfer(sc->kue_cdata.kue_tx_chain[i].kue_xfer);
1250: sc->kue_cdata.kue_tx_chain[i].kue_xfer = NULL;
1251: }
1252: }
1253:
1254: ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1255: }
CVSweb <webmaster@jp.NetBSD.org>