Annotation of src/sys/dev/usb/if_kue.c, Revision 1.34
1.34 ! thorpej 1: /* $NetBSD: if_kue.c,v 1.33 2000/12/06 21:44:08 jdolecek 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:
72: /*
73: * TODO:
74: * only use kue_do_request for downloading firmware.
75: * more DPRINTF
76: * proper cleanup on errors
77: */
1.26 augustss 78: #if defined(__NetBSD__)
1.1 augustss 79: #include "opt_inet.h"
80: #include "opt_ns.h"
81: #include "bpfilter.h"
82: #include "rnd.h"
1.26 augustss 83: #elif defined(__OpenBSD__)
84: #include "bpfilter.h"
1.1 augustss 85: #endif
86:
87: #include <sys/param.h>
88: #include <sys/systm.h>
89: #include <sys/sockio.h>
90: #include <sys/mbuf.h>
91: #include <sys/malloc.h>
92: #include <sys/kernel.h>
93: #include <sys/socket.h>
94:
95: #if defined(__FreeBSD__)
96:
97: #include <net/ethernet.h>
98: #include <machine/clock.h> /* for DELAY */
99: #include <sys/bus.h>
100:
101: #elif defined(__NetBSD__) || defined(__OpenBSD__)
102:
103: #include <sys/device.h>
1.6 augustss 104: #if NRND > 0
105: #include <sys/rnd.h>
106: #endif
1.1 augustss 107:
108: #endif
109:
110: #include <net/if.h>
1.26 augustss 111: #if defined(__NetBSD__) || defined(__FreeBSD__)
1.1 augustss 112: #include <net/if_arp.h>
1.26 augustss 113: #endif
1.1 augustss 114: #include <net/if_dl.h>
115:
116: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.7 mycroft 117: #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
118: #else
119: #define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m))
1.1 augustss 120: #endif
121:
122: #if defined(__FreeBSD__) || NBPFILTER > 0
123: #include <net/bpf.h>
124: #endif
125:
1.26 augustss 126: #if defined(__NetBSD__)
127: #include <net/if_ether.h>
1.1 augustss 128: #ifdef INET
129: #include <netinet/in.h>
130: #include <netinet/if_inarp.h>
131: #endif
1.26 augustss 132: #endif /* defined (__NetBSD__) */
133:
134: #if defined(__OpenBSD__)
135: #ifdef INET
136: #include <netinet/in.h>
137: #include <netinet/in_systm.h>
138: #include <netinet/in_var.h>
139: #include <netinet/ip.h>
140: #include <netinet/if_ether.h>
141: #endif
142: #endif /* defined (__OpenBSD__) */
1.1 augustss 143:
1.26 augustss 144: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.1 augustss 145: #ifdef NS
146: #include <netns/ns.h>
147: #include <netns/ns_if.h>
148: #endif
149: #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
150:
151: #include <dev/usb/usb.h>
152: #include <dev/usb/usbdi.h>
153: #include <dev/usb/usbdi_util.h>
154: #include <dev/usb/usbdevs.h>
155:
156: #ifdef __FreeBSD__
157: #include <dev/usb/usb_ethersubr.h>
158: #endif
159:
160: #include <dev/usb/if_kuereg.h>
161: #include <dev/usb/kue_fw.h>
162:
163: #ifdef KUE_DEBUG
164: #define DPRINTF(x) if (kuedebug) logprintf x
165: #define DPRINTFN(n,x) if (kuedebug >= (n)) logprintf x
166: int kuedebug = 0;
167: #else
168: #define DPRINTF(x)
169: #define DPRINTFN(n,x)
170: #endif
171:
172: /*
173: * Various supported device vendors/products.
174: */
1.24 augustss 175: Static struct kue_type kue_devs[] = {
1.1 augustss 176: { USB_VENDOR_AOX, USB_PRODUCT_AOX_USB101 },
177: { USB_VENDOR_ADS, USB_PRODUCT_ADS_UBS10BT },
178: { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC10T },
179: { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_EA101 },
180: { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET },
181: { USB_VENDOR_PERACOM, USB_PRODUCT_PERACOM_ENET2 },
182: { USB_VENDOR_ENTREGA, USB_PRODUCT_ENTREGA_E45 },
183: { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C19250 },
1.9 hubertf 184: { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 },
1.1 augustss 185: { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_ETHER_USB_T },
186: { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DSB650C },
187: { USB_VENDOR_SMC, USB_PRODUCT_SMC_2102USB },
1.4 augustss 188: { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T },
1.23 augustss 189: { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT },
1.33 jdolecek 190: { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBETT },
1.1 augustss 191: { 0, 0 }
192: };
193:
194: USB_DECLARE_DRIVER(kue);
195:
1.29 augustss 196: Static int kue_tx_list_init(struct kue_softc *);
197: Static int kue_rx_list_init(struct kue_softc *);
198: Static int kue_newbuf(struct kue_softc *, struct kue_chain *,struct mbuf *);
199: Static int kue_send(struct kue_softc *, struct mbuf *, int);
200: Static int kue_open_pipes(struct kue_softc *);
201: Static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
202: Static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
203: Static void kue_start(struct ifnet *);
204: Static int kue_ioctl(struct ifnet *, u_long, caddr_t);
205: Static void kue_init(void *);
206: Static void kue_stop(struct kue_softc *);
207: Static void kue_watchdog(struct ifnet *);
208:
209: Static void kue_setmulti(struct kue_softc *);
210: Static void kue_reset(struct kue_softc *);
211:
212: Static usbd_status kue_ctl(struct kue_softc *, int, u_int8_t,
213: u_int16_t, void *, u_int32_t);
214: Static usbd_status kue_setword(struct kue_softc *, u_int8_t, u_int16_t);
215: Static int kue_is_warm(struct kue_softc *);
216: Static int kue_load_fw(struct kue_softc *);
1.1 augustss 217:
218: #if defined(__FreeBSD__)
219: #ifndef lint
220: static const char rcsid[] =
221: "$FreeBSD: src/sys/dev/usb/if_kue.c,v 1.14 2000/01/14 01:36:15 wpaul Exp $";
222: #endif
223:
1.29 augustss 224: Static void kue_rxstart(struct ifnet *);
225: Static void kue_shutdown(device_t);
1.1 augustss 226:
1.24 augustss 227: Static struct usb_qdat kue_qdat;
1.1 augustss 228:
1.24 augustss 229: Static device_method_t kue_methods[] = {
1.1 augustss 230: /* Device interface */
231: DEVMETHOD(device_probe, kue_match),
232: DEVMETHOD(device_attach, kue_attach),
233: DEVMETHOD(device_detach, kue_detach),
234: DEVMETHOD(device_shutdown, kue_shutdown),
235:
236: { 0, 0 }
237: };
238:
1.24 augustss 239: Static driver_t kue_driver = {
1.1 augustss 240: "kue",
241: kue_methods,
242: sizeof(struct kue_softc)
243: };
244:
1.24 augustss 245: Static devclass_t kue_devclass;
1.1 augustss 246:
247: DRIVER_MODULE(if_kue, uhub, kue_driver, kue_devclass, usbd_driver_load, 0);
248:
249: #endif /* __FreeBSD__ */
250:
1.18 augustss 251: #define KUE_DO_REQUEST(dev, req, data) \
252: usbd_do_request_flags(dev, req, data, USBD_NO_TSLEEP, NULL)
1.1 augustss 253:
1.24 augustss 254: Static usbd_status
1.29 augustss 255: kue_setword(struct kue_softc *sc, u_int8_t breq, u_int16_t word)
1.1 augustss 256: {
257: usb_device_request_t req;
258: usbd_status err;
259: int s;
260:
261: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
262:
263: req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
264: req.bRequest = breq;
265: USETW(req.wValue, word);
266: USETW(req.wIndex, 0);
267: USETW(req.wLength, 0);
268:
269: s = splusb();
1.18 augustss 270: err = KUE_DO_REQUEST(sc->kue_udev, &req, NULL);
1.1 augustss 271: splx(s);
272:
273: return (err);
274: }
275:
1.24 augustss 276: Static usbd_status
1.29 augustss 277: kue_ctl(struct kue_softc *sc, int rw, u_int8_t breq, u_int16_t val,
278: void *data, u_int32_t len)
1.1 augustss 279: {
280: usb_device_request_t req;
281: usbd_status err;
282: int s;
283:
284: DPRINTFN(10,("%s: %s: enter, len=%d\n", USBDEVNAME(sc->kue_dev),
285: __FUNCTION__, len));
286:
287: if (rw == KUE_CTL_WRITE)
288: req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
289: else
290: req.bmRequestType = UT_READ_VENDOR_DEVICE;
291:
292: req.bRequest = breq;
293: USETW(req.wValue, val);
294: USETW(req.wIndex, 0);
295: USETW(req.wLength, len);
296:
297: s = splusb();
1.18 augustss 298: err = KUE_DO_REQUEST(sc->kue_udev, &req, data);
1.1 augustss 299: splx(s);
300:
301: return (err);
302: }
303:
1.24 augustss 304: Static int
1.29 augustss 305: kue_is_warm(struct kue_softc *sc)
1.22 augustss 306: {
307: usbd_status err;
308: usb_device_request_t req;
309:
310: /* Just issue some random command. */
311: req.bmRequestType = UT_READ_VENDOR_DEVICE;
312: req.bRequest = KUE_CMD_GET_ETHER_DESCRIPTOR;
313: USETW(req.wValue, 0);
314: USETW(req.wIndex, 0);
315: USETW(req.wLength, sizeof(sc->kue_desc));
316:
317: err = usbd_do_request(sc->kue_udev, &req, &sc->kue_desc);
318:
319: return (!err);
320: }
321:
1.24 augustss 322: Static int
1.29 augustss 323: kue_load_fw(struct kue_softc *sc)
1.1 augustss 324: {
325: usbd_status err;
326:
327: DPRINTFN(1,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
328:
329: /*
330: * First, check if we even need to load the firmware.
331: * If the device was still attached when the system was
332: * rebooted, it may already have firmware loaded in it.
333: * If this is the case, we don't need to do it again.
334: * And in fact, if we try to load it again, we'll hang,
335: * so we have to avoid this condition if we don't want
336: * to look stupid.
337: *
1.17 augustss 338: * We can test this quickly by issuing a request that
339: * is only valid after firmware download.
1.1 augustss 340: */
1.22 augustss 341: if (kue_is_warm(sc)) {
1.1 augustss 342: printf("%s: warm boot, no firmware download\n",
343: USBDEVNAME(sc->kue_dev));
344: return (0);
345: }
346:
347: printf("%s: cold boot, downloading firmware\n",
348: USBDEVNAME(sc->kue_dev));
349:
350: /* Load code segment */
351: DPRINTFN(1,("%s: kue_load_fw: download code_seg\n",
352: USBDEVNAME(sc->kue_dev)));
353: err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
354: 0, kue_code_seg, sizeof(kue_code_seg));
355: if (err) {
356: printf("%s: failed to load code segment: %s\n",
357: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
358: return (EIO);
359: }
360:
361: /* Load fixup segment */
362: DPRINTFN(1,("%s: kue_load_fw: download fix_seg\n",
363: USBDEVNAME(sc->kue_dev)));
364: err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
365: 0, kue_fix_seg, sizeof(kue_fix_seg));
366: if (err) {
367: printf("%s: failed to load fixup segment: %s\n",
368: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
369: return (EIO);
370: }
371:
372: /* Send trigger command. */
373: DPRINTFN(1,("%s: kue_load_fw: download trig_seg\n",
374: USBDEVNAME(sc->kue_dev)));
375: err = kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SEND_SCAN,
376: 0, kue_trig_seg, sizeof(kue_trig_seg));
377: if (err) {
378: printf("%s: failed to load trigger segment: %s\n",
379: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
380: return (EIO);
381: }
382:
383: usbd_delay_ms(sc->kue_udev, 10);
384:
385: /*
386: * Reload device descriptor.
387: * Why? The chip without the firmware loaded returns
388: * one revision code. The chip with the firmware
389: * loaded and running returns a *different* revision
390: * code. This confuses the quirk mechanism, which is
391: * dependent on the revision data.
392: */
393: (void)usbd_reload_device_desc(sc->kue_udev);
394:
395: DPRINTFN(1,("%s: %s: done\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
396:
397: /* Reset the adapter. */
398: kue_reset(sc);
399:
400: return (0);
401: }
402:
1.24 augustss 403: Static void
1.29 augustss 404: kue_setmulti(struct kue_softc *sc)
1.1 augustss 405: {
406: struct ifnet *ifp = GET_IFP(sc);
407: #if defined(__FreeBSD__)
408: struct ifmultiaddr *ifma;
409: #elif defined(__NetBSD__) || defined(__OpenBSD__)
410: struct ether_multi *enm;
411: struct ether_multistep step;
412: #endif
413: int i;
414:
415: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
416:
417: if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
418: sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
419: sc->kue_rxfilt &= ~KUE_RXFILT_MULTICAST;
420: kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
421: return;
422: }
423:
424: sc->kue_rxfilt &= ~KUE_RXFILT_ALLMULTI;
425:
426: i = 0;
427: #if defined(__FreeBSD__)
428: for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
429: ifma = ifma->ifma_link.le_next) {
430: if (ifma->ifma_addr->sa_family != AF_LINK)
431: continue;
432: /*
433: * If there are too many addresses for the
434: * internal filter, switch over to allmulti mode.
435: */
436: if (i == KUE_MCFILTCNT(sc))
437: break;
438: bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
439: KUE_MCFILT(sc, i), ETHER_ADDR_LEN);
440: i++;
441: }
442: #elif defined(__NetBSD__) || defined(__OpenBSD__)
1.26 augustss 443: #if defined (__NetBSD__)
1.1 augustss 444: ETHER_FIRST_MULTI(step, &sc->kue_ec, enm);
1.26 augustss 445: #else
446: ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
447: #endif
1.1 augustss 448: while (enm != NULL) {
449: if (i == KUE_MCFILTCNT(sc))
450: break;
451: #if 0
452: if (memcmp(enm->enm_addrlo,
453: enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
454: ifp->if_flags |= IFF_ALLMULTI;
455: /* XXX what now? */
456: return;
457: }
458: #endif
459: memcpy(KUE_MCFILT(sc, i), enm->enm_addrlo, ETHER_ADDR_LEN);
460: ETHER_NEXT_MULTI(step, enm);
461: i++;
462: }
463: #endif
464:
465: if (i == KUE_MCFILTCNT(sc))
466: sc->kue_rxfilt |= KUE_RXFILT_ALLMULTI;
467: else {
468: sc->kue_rxfilt |= KUE_RXFILT_MULTICAST;
469: kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MCAST_FILTERS,
470: i, sc->kue_mcfilters, i * ETHER_ADDR_LEN);
471: }
472:
473: kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
474: }
475:
476: /*
477: * Issue a SET_CONFIGURATION command to reset the MAC. This should be
478: * done after the firmware is loaded into the adapter in order to
479: * bring it into proper operation.
480: */
1.24 augustss 481: Static void
1.29 augustss 482: kue_reset(struct kue_softc *sc)
1.1 augustss 483: {
484: usbd_status err;
485:
486: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
487:
1.31 augustss 488: err = usbd_set_config_no(sc->kue_udev, KUE_CONFIG_NO, 1);
1.1 augustss 489: if (err)
490: printf("%s: reset failed\n", USBDEVNAME(sc->kue_dev));
491:
492: /* Wait a little while for the chip to get its brains in order. */
493: usbd_delay_ms(sc->kue_udev, 10);
494: }
495:
496: /*
497: * Probe for a KLSI chip.
498: */
499: USB_MATCH(kue)
500: {
501: USB_MATCH_START(kue, uaa);
502: struct kue_type *t;
503:
504: DPRINTFN(25,("kue_match: enter\n"));
505:
506: if (uaa->iface != NULL)
507: return (UMATCH_NONE);
508:
509: for (t = kue_devs; t->kue_vid != 0; t++)
510: if (uaa->vendor == t->kue_vid && uaa->product == t->kue_did)
511: return (UMATCH_VENDOR_PRODUCT);
512:
513: return (UMATCH_NONE);
514: }
515:
516: /*
517: * Attach the interface. Allocate softc structures, do
518: * setup and ethernet/BPF attach.
519: */
520: USB_ATTACH(kue)
521: {
522: USB_ATTACH_START(kue, sc, uaa);
523: char devinfo[1024];
524: int s;
525: struct ifnet *ifp;
526: usbd_device_handle dev = uaa->device;
527: usbd_interface_handle iface;
528: usbd_status err;
529: usb_interface_descriptor_t *id;
530: usb_endpoint_descriptor_t *ed;
531: int i;
532:
533: #ifdef __FreeBSD__
534: bzero(sc, sizeof(struct kue_softc));
535: #endif
536:
537: DPRINTFN(5,(" : kue_attach: sc=%p, dev=%p", sc, dev));
538:
539: usbd_devinfo(dev, 0, devinfo);
540: USB_ATTACH_SETUP;
541: printf("%s: %s\n", USBDEVNAME(sc->kue_dev), devinfo);
542:
1.31 augustss 543: err = usbd_set_config_no(dev, KUE_CONFIG_NO, 1);
1.1 augustss 544: if (err) {
545: printf("%s: setting config no failed\n",
546: USBDEVNAME(sc->kue_dev));
547: USB_ATTACH_ERROR_RETURN;
548: }
549:
550: sc->kue_udev = dev;
551: sc->kue_product = uaa->product;
552: sc->kue_vendor = uaa->vendor;
553:
554: /* Load the firmware into the NIC. */
555: if (kue_load_fw(sc)) {
556: printf("%s: loading firmware failed\n",
557: USBDEVNAME(sc->kue_dev));
558: USB_ATTACH_ERROR_RETURN;
559: }
560:
561: err = usbd_device2interface_handle(dev, KUE_IFACE_IDX, &iface);
562: if (err) {
563: printf("%s: getting interface handle failed\n",
564: USBDEVNAME(sc->kue_dev));
565: USB_ATTACH_ERROR_RETURN;
566: }
567:
568: sc->kue_iface = iface;
569: id = usbd_get_interface_descriptor(iface);
570:
571: /* Find endpoints. */
572: for (i = 0; i < id->bNumEndpoints; i++) {
573: ed = usbd_interface2endpoint_descriptor(iface, i);
574: if (ed == NULL) {
575: printf("%s: couldn't get ep %d\n",
576: USBDEVNAME(sc->kue_dev), i);
577: USB_ATTACH_ERROR_RETURN;
578: }
579: if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1.12 augustss 580: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1.1 augustss 581: sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
582: } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1.12 augustss 583: UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1.1 augustss 584: sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
585: } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1.12 augustss 586: UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
1.1 augustss 587: sc->kue_ed[KUE_ENDPT_INTR] = ed->bEndpointAddress;
588: }
589: }
590:
591: if (sc->kue_ed[KUE_ENDPT_RX] == 0 || sc->kue_ed[KUE_ENDPT_TX] == 0) {
592: printf("%s: missing endpoint\n", USBDEVNAME(sc->kue_dev));
593: USB_ATTACH_ERROR_RETURN;
594: }
595:
596: /* Read ethernet descriptor */
597: err = kue_ctl(sc, KUE_CTL_READ, KUE_CMD_GET_ETHER_DESCRIPTOR,
1.18 augustss 598: 0, &sc->kue_desc, sizeof(sc->kue_desc));
1.1 augustss 599: if (err) {
600: printf("%s: could not read Ethernet descriptor\n",
601: USBDEVNAME(sc->kue_dev));
602: USB_ATTACH_ERROR_RETURN;
603: }
604:
605: sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN,
606: M_USBDEV, M_NOWAIT);
607: if (sc->kue_mcfilters == NULL) {
608: printf("%s: no memory for multicast filter buffer\n",
609: USBDEVNAME(sc->kue_dev));
610: USB_ATTACH_ERROR_RETURN;
611: }
612:
613: s = splimp();
614:
615: /*
616: * A KLSI chip was detected. Inform the world.
617: */
618: #if defined(__FreeBSD__)
619: printf("%s: Ethernet address: %6D\n", USBDEVNAME(sc->kue_dev),
620: sc->kue_desc.kue_macaddr, ":");
621:
622: bcopy(sc->kue_desc.kue_macaddr,
623: (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
624:
625: ifp = GET_IFP(sc);
626: ifp->if_softc = sc;
627: ifp->if_unit = sc->kue_unit;
628: ifp->if_name = "kue";
629: ifp->if_mtu = ETHERMTU;
630: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
631: ifp->if_ioctl = kue_ioctl;
632: ifp->if_output = ether_output;
633: ifp->if_start = kue_start;
634: ifp->if_watchdog = kue_watchdog;
635: ifp->if_init = kue_init;
636: ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
637:
638: kue_qdat.ifp = ifp;
639: kue_qdat.if_rxstart = kue_rxstart;
640:
641: /*
642: * Call MI attach routines.
643: */
644: if_attach(ifp);
645: ether_ifattach(ifp);
646: bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
647: usb_register_netisr();
648:
649: #elif defined(__NetBSD__) || defined(__OpenBSD__)
650:
651: printf("%s: Ethernet address %s\n", USBDEVNAME(sc->kue_dev),
652: ether_sprintf(sc->kue_desc.kue_macaddr));
653:
654: /* Initialize interface info.*/
655: ifp = GET_IFP(sc);
656: ifp->if_softc = sc;
657: ifp->if_mtu = ETHERMTU;
658: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
659: ifp->if_ioctl = kue_ioctl;
660: ifp->if_start = kue_start;
661: ifp->if_watchdog = kue_watchdog;
1.27 augustss 662: #if defined(__OpenBSD__)
663: ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
664: #endif
1.1 augustss 665: strncpy(ifp->if_xname, USBDEVNAME(sc->kue_dev), IFNAMSIZ);
666:
1.34 ! thorpej 667: IFQ_SET_READY(&ifp->if_snd);
! 668:
1.1 augustss 669: /* Attach the interface. */
670: if_attach(ifp);
1.26 augustss 671: Ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
1.6 augustss 672: #if NRND > 0
1.1 augustss 673: rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->kue_dev),
674: RND_TYPE_NET, 0);
675: #endif
676:
677: #endif /* __NetBSD__ */
1.8 augustss 678: sc->kue_attached = 1;
1.1 augustss 679: splx(s);
1.6 augustss 680:
681: usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->kue_udev,
682: USBDEV(sc->kue_dev));
683:
1.1 augustss 684: USB_ATTACH_SUCCESS_RETURN;
685: }
686:
687: USB_DETACH(kue)
688: {
689: USB_DETACH_START(kue, sc);
1.6 augustss 690: struct ifnet *ifp = GET_IFP(sc);
1.1 augustss 691: int s;
692:
1.6 augustss 693: s = splusb(); /* XXX why? */
1.1 augustss 694:
1.8 augustss 695: if (sc->kue_mcfilters != NULL) {
696: free(sc->kue_mcfilters, M_USBDEV);
697: sc->kue_mcfilters = NULL;
698: }
699:
700: if (!sc->kue_attached) {
701: /* Detached before attached finished, so just bail out. */
702: splx(s);
703: return (0);
704: }
705:
1.6 augustss 706: if (ifp->if_flags & IFF_RUNNING)
707: kue_stop(sc);
1.1 augustss 708:
1.5 thorpej 709: #if defined(__NetBSD__)
1.6 augustss 710: #if NRND > 0
711: rnd_detach_source(&sc->rnd_source);
1.5 thorpej 712: #endif
1.6 augustss 713: ether_ifdetach(ifp);
1.5 thorpej 714: #endif /* __NetBSD__ */
1.1 augustss 715:
1.6 augustss 716: if_detach(ifp);
717:
718: #ifdef DIAGNOSTIC
719: if (sc->kue_ep[KUE_ENDPT_TX] != NULL ||
720: sc->kue_ep[KUE_ENDPT_RX] != NULL ||
721: sc->kue_ep[KUE_ENDPT_INTR] != NULL)
722: printf("%s: detach has active endpoints\n",
723: USBDEVNAME(sc->kue_dev));
724: #endif
1.1 augustss 725:
1.8 augustss 726: sc->kue_attached = 0;
1.1 augustss 727: splx(s);
728:
729: return (0);
730: }
731:
732: #if defined(__NetBSD__) || defined(__OpenBSD__)
733: int
1.29 augustss 734: kue_activate(device_ptr_t self, enum devact act)
1.1 augustss 735: {
736: struct kue_softc *sc = (struct kue_softc *)self;
737:
738: DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
739:
740: switch (act) {
741: case DVACT_ACTIVATE:
742: return (EOPNOTSUPP);
743: break;
744:
745: case DVACT_DEACTIVATE:
1.26 augustss 746: #if defined(__NetBSD__)
1.5 thorpej 747: /* Deactivate the interface. */
748: if_deactivate(&sc->kue_ec.ec_if);
1.26 augustss 749: #endif
1.1 augustss 750: sc->kue_dying = 1;
751: break;
752: }
753: return (0);
754: }
755: #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
756:
757: /*
758: * Initialize an RX descriptor and attach an MBUF cluster.
759: */
1.24 augustss 760: Static int
1.29 augustss 761: kue_newbuf(struct kue_softc *sc, struct kue_chain *c, struct mbuf *m)
1.1 augustss 762: {
763: struct mbuf *m_new = NULL;
764:
765: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
766:
767: if (m == NULL) {
768: MGETHDR(m_new, M_DONTWAIT, MT_DATA);
769: if (m_new == NULL) {
770: printf("%s: no memory for rx list "
771: "-- packet dropped!\n", USBDEVNAME(sc->kue_dev));
772: return (ENOBUFS);
773: }
774:
775: MCLGET(m_new, M_DONTWAIT);
776: if (!(m_new->m_flags & M_EXT)) {
777: printf("%s: no memory for rx list "
778: "-- packet dropped!\n", USBDEVNAME(sc->kue_dev));
779: m_freem(m_new);
780: return (ENOBUFS);
781: }
782: m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
783: } else {
784: m_new = m;
785: m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
786: m_new->m_data = m_new->m_ext.ext_buf;
787: }
788:
789: c->kue_mbuf = m_new;
790:
791: return (0);
792: }
793:
1.24 augustss 794: Static int
1.29 augustss 795: kue_rx_list_init(struct kue_softc *sc)
1.1 augustss 796: {
797: struct kue_cdata *cd;
798: struct kue_chain *c;
799: int i;
800:
801: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
802:
803: cd = &sc->kue_cdata;
804: for (i = 0; i < KUE_RX_LIST_CNT; i++) {
805: c = &cd->kue_rx_chain[i];
806: c->kue_sc = sc;
807: c->kue_idx = i;
808: if (kue_newbuf(sc, c, NULL) == ENOBUFS)
809: return (ENOBUFS);
810: if (c->kue_xfer == NULL) {
811: c->kue_xfer = usbd_alloc_xfer(sc->kue_udev);
812: if (c->kue_xfer == NULL)
813: return (ENOBUFS);
814: c->kue_buf = usbd_alloc_buffer(c->kue_xfer, KUE_BUFSZ);
815: if (c->kue_buf == NULL)
816: return (ENOBUFS); /* XXX free xfer */
817: }
818: }
819:
820: return (0);
821: }
822:
1.24 augustss 823: Static int
1.29 augustss 824: kue_tx_list_init(struct kue_softc *sc)
1.1 augustss 825: {
826: struct kue_cdata *cd;
827: struct kue_chain *c;
828: int i;
829:
830: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev), __FUNCTION__));
831:
832: cd = &sc->kue_cdata;
833: for (i = 0; i < KUE_TX_LIST_CNT; i++) {
834: c = &cd->kue_tx_chain[i];
835: c->kue_sc = sc;
836: c->kue_idx = i;
837: c->kue_mbuf = NULL;
838: if (c->kue_xfer == NULL) {
839: c->kue_xfer = usbd_alloc_xfer(sc->kue_udev);
840: if (c->kue_xfer == NULL)
841: return (ENOBUFS);
842: c->kue_buf = usbd_alloc_buffer(c->kue_xfer, KUE_BUFSZ);
843: if (c->kue_buf == NULL)
844: return (ENOBUFS);
845: }
846: }
847:
848: return (0);
849: }
850:
851: #ifdef __FreeBSD__
1.24 augustss 852: Static void
1.29 augustss 853: kue_rxstart(struct ifnet *ifp)
1.1 augustss 854: {
855: struct kue_softc *sc;
856: struct kue_chain *c;
857:
858: sc = ifp->if_softc;
859: c = &sc->kue_cdata.kue_rx_chain[sc->kue_cdata.kue_rx_prod];
860:
861: if (kue_newbuf(sc, c, NULL) == ENOBUFS) {
862: ifp->if_ierrors++;
863: return;
864: }
865:
866: /* Setup new transfer. */
867: usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
868: c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
869: USBD_NO_TIMEOUT, kue_rxeof);
870: usbd_transfer(c->kue_xfer);
871: }
872: #endif
873:
874: /*
875: * A frame has been uploaded: pass the resulting mbuf chain up to
876: * the higher level protocols.
877: */
1.24 augustss 878: Static void
1.29 augustss 879: kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1.1 augustss 880: {
881: struct kue_chain *c = priv;
882: struct kue_softc *sc = c->kue_sc;
883: struct ifnet *ifp = GET_IFP(sc);
884: struct mbuf *m;
885: int total_len = 0;
886: #if defined(__NetBSD__) || defined(__OpenBSD__)
887: int s;
888: #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
889:
890: DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev),
891: __FUNCTION__, status));
892:
1.6 augustss 893: if (sc->kue_dying)
894: return;
895:
1.1 augustss 896: if (!(ifp->if_flags & IFF_RUNNING))
897: return;
898:
899: if (status != USBD_NORMAL_COMPLETION) {
900: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
901: return;
1.11 augustss 902: sc->kue_rx_errs++;
903: if (usbd_ratecheck(&sc->kue_rx_notice)) {
904: printf("%s: %u usb errors on rx: %s\n",
905: USBDEVNAME(sc->kue_dev), sc->kue_rx_errs,
906: usbd_errstr(status));
907: sc->kue_rx_errs = 0;
908: }
1.1 augustss 909: if (status == USBD_STALLED)
910: usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_RX]);
911: goto done;
912: }
913:
914: usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
915:
916: DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", USBDEVNAME(sc->kue_dev),
917: __FUNCTION__, total_len,
918: UGETW(mtod(c->kue_mbuf, u_int8_t *))));
919:
920: if (total_len <= 1)
921: goto done;
922:
1.18 augustss 923: m = c->kue_mbuf;
1.1 augustss 924: /* copy data to mbuf */
925: memcpy(mtod(m, char*), c->kue_buf, total_len);
926:
927: /* No errors; receive the packet. */
928: total_len = UGETW(mtod(m, u_int8_t *));
929: m_adj(m, sizeof(u_int16_t));
930:
931: if (total_len < sizeof(struct ether_header)) {
932: ifp->if_ierrors++;
933: goto done;
934: }
935:
936: ifp->if_ipackets++;
937: m->m_pkthdr.len = m->m_len = total_len;
938:
939: #if defined(__FreeBSD__)
940: m->m_pkthdr.rcvif = (struct ifnet *)&kue_qdat;
941: /* Put the packet on the special USB input queue. */
942: usb_ether_input(m);
943:
944: return;
945:
946: #elif defined(__NetBSD__) || defined(__OpenBSD__)
947: m->m_pkthdr.rcvif = ifp;
948:
949: s = splimp();
950:
951: /* XXX ugly */
952: if (kue_newbuf(sc, c, NULL) == ENOBUFS) {
953: ifp->if_ierrors++;
954: goto done1;
955: }
956:
1.10 augustss 957: #if NBPFILTER > 0
1.1 augustss 958: /*
959: * Handle BPF listeners. Let the BPF user see the packet, but
960: * don't pass it up to the ether_input() layer unless it's
961: * a broadcast packet, multicast packet, matches our ethernet
962: * address or the interface is in promiscuous mode.
963: */
1.30 thorpej 964: if (ifp->if_bpf)
1.27 augustss 965: BPF_MTAP(ifp, m);
1.10 augustss 966: #endif
1.1 augustss 967:
968: DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->kue_dev),
969: __FUNCTION__, m->m_len));
1.26 augustss 970: IF_INPUT(ifp, m);
1.1 augustss 971: done1:
972: splx(s);
973: #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
974:
975: done:
976:
977: /* Setup new transfer. */
978: usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
979: c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
980: USBD_NO_TIMEOUT, kue_rxeof);
981: usbd_transfer(c->kue_xfer);
982:
983: DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->kue_dev),
984: __FUNCTION__));
985: }
986:
987: /*
988: * A frame was downloaded to the chip. It's safe for us to clean up
989: * the list buffers.
990: */
991:
1.24 augustss 992: Static void
1.29 augustss 993: kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1.1 augustss 994: {
995: struct kue_chain *c = priv;
996: struct kue_softc *sc = c->kue_sc;
997: struct ifnet *ifp = GET_IFP(sc);
998: int s;
999:
1.6 augustss 1000: if (sc->kue_dying)
1001: return;
1002:
1.1 augustss 1003: s = splimp();
1004:
1005: DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->kue_dev),
1006: __FUNCTION__, status));
1007:
1008: ifp->if_timer = 0;
1009: ifp->if_flags &= ~IFF_OACTIVE;
1010:
1011: if (status != USBD_NORMAL_COMPLETION) {
1012: if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1013: splx(s);
1014: return;
1015: }
1016: ifp->if_oerrors++;
1017: printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->kue_dev),
1018: usbd_errstr(status));
1019: if (status == USBD_STALLED)
1020: usbd_clear_endpoint_stall(sc->kue_ep[KUE_ENDPT_TX]);
1021: splx(s);
1022: return;
1023: }
1024:
1025: ifp->if_opackets++;
1026:
1027: #if defined(__FreeBSD__)
1028: c->kue_mbuf->m_pkthdr.rcvif = ifp;
1029: usb_tx_done(c->kue_mbuf);
1030: c->kue_mbuf = NULL;
1031: #elif defined(__NetBSD__) || defined(__OpenBSD__)
1032: m_freem(c->kue_mbuf);
1033: c->kue_mbuf = NULL;
1034:
1.34 ! thorpej 1035: if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1 augustss 1036: kue_start(ifp);
1037: #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1038:
1039: splx(s);
1040: }
1041:
1.24 augustss 1042: Static int
1.29 augustss 1043: kue_send(struct kue_softc *sc, struct mbuf *m, int idx)
1.1 augustss 1044: {
1045: int total_len;
1046: struct kue_chain *c;
1047: usbd_status err;
1048:
1049: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1050:
1051: c = &sc->kue_cdata.kue_tx_chain[idx];
1052:
1053: /*
1054: * Copy the mbuf data into a contiguous buffer, leaving two
1055: * bytes at the beginning to hold the frame length.
1056: */
1057: m_copydata(m, 0, m->m_pkthdr.len, c->kue_buf + 2);
1058: c->kue_mbuf = m;
1059:
1060: total_len = m->m_pkthdr.len + 2;
1061: /* XXX what's this? */
1062: total_len += 64 - (total_len % 64);
1063:
1064: /* Frame length is specified in the first 2 bytes of the buffer. */
1065: c->kue_buf[0] = (u_int8_t)m->m_pkthdr.len;
1066: c->kue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8);
1067:
1068: usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_TX],
1.25 augustss 1069: c, c->kue_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, kue_txeof);
1.1 augustss 1070:
1071: /* Transmit */
1072: err = usbd_transfer(c->kue_xfer);
1073: if (err != USBD_IN_PROGRESS) {
1.28 augustss 1074: printf("%s: kue_send error=%s\n", USBDEVNAME(sc->kue_dev),
1075: usbd_errstr(err));
1.1 augustss 1076: kue_stop(sc);
1077: return (EIO);
1078: }
1079:
1080: sc->kue_cdata.kue_tx_cnt++;
1081:
1082: return (0);
1083: }
1084:
1.24 augustss 1085: Static void
1.29 augustss 1086: kue_start(struct ifnet *ifp)
1.1 augustss 1087: {
1088: struct kue_softc *sc = ifp->if_softc;
1089: struct mbuf *m_head = NULL;
1090:
1091: DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1092:
1.6 augustss 1093: if (sc->kue_dying)
1094: return;
1095:
1.1 augustss 1096: if (ifp->if_flags & IFF_OACTIVE)
1097: return;
1098:
1.34 ! thorpej 1099: IFQ_POLL(&ifp->if_snd, m_head);
1.1 augustss 1100: if (m_head == NULL)
1101: return;
1102:
1103: if (kue_send(sc, m_head, 0)) {
1104: ifp->if_flags |= IFF_OACTIVE;
1105: return;
1106: }
1107:
1.34 ! thorpej 1108: IFQ_DEQUEUE(&ifp->if_snd, m_head);
! 1109:
1.10 augustss 1110: #if NBPFILTER > 0
1.1 augustss 1111: /*
1112: * If there's a BPF listener, bounce a copy of this frame
1113: * to him.
1114: */
1115: if (ifp->if_bpf)
1.7 mycroft 1116: BPF_MTAP(ifp, m_head);
1.10 augustss 1117: #endif
1.1 augustss 1118:
1119: ifp->if_flags |= IFF_OACTIVE;
1120:
1121: /*
1122: * Set a timeout in case the chip goes out to lunch.
1123: */
1124: ifp->if_timer = 5;
1125: }
1126:
1.24 augustss 1127: Static void
1.29 augustss 1128: kue_init(void *xsc)
1.1 augustss 1129: {
1130: struct kue_softc *sc = xsc;
1131: struct ifnet *ifp = GET_IFP(sc);
1132: int s;
1133: u_char *eaddr;
1134:
1135: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1136:
1137: if (ifp->if_flags & IFF_RUNNING)
1138: return;
1139:
1140: s = splimp();
1141:
1.26 augustss 1142: #if defined(__FreeBSD__) || defined(__OpenBSD__)
1.1 augustss 1143: eaddr = sc->arpcom.ac_enaddr;
1.26 augustss 1144: #elif defined(__NetBSD__)
1.1 augustss 1145: eaddr = LLADDR(ifp->if_sadl);
1.26 augustss 1146: #endif /* defined(__NetBSD__) */
1.1 augustss 1147: /* Set MAC address */
1148: kue_ctl(sc, KUE_CTL_WRITE, KUE_CMD_SET_MAC, 0, eaddr, ETHER_ADDR_LEN);
1149:
1150: sc->kue_rxfilt = KUE_RXFILT_UNICAST | KUE_RXFILT_BROADCAST;
1151:
1152: /* If we want promiscuous mode, set the allframes bit. */
1153: if (ifp->if_flags & IFF_PROMISC)
1154: sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
1155:
1156: kue_setword(sc, KUE_CMD_SET_PKT_FILTER, sc->kue_rxfilt);
1157:
1158: /* I'm not sure how to tune these. */
1159: #if 0
1160: /*
1161: * Leave this one alone for now; setting it
1162: * wrong causes lockups on some machines/controllers.
1163: */
1164: kue_setword(sc, KUE_CMD_SET_SOFS, 1);
1165: #endif
1166: kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64);
1167:
1168: /* Init TX ring. */
1169: if (kue_tx_list_init(sc) == ENOBUFS) {
1170: printf("%s: tx list init failed\n", USBDEVNAME(sc->kue_dev));
1171: splx(s);
1172: return;
1173: }
1174:
1175: /* Init RX ring. */
1176: if (kue_rx_list_init(sc) == ENOBUFS) {
1177: printf("%s: rx list init failed\n", USBDEVNAME(sc->kue_dev));
1178: splx(s);
1179: return;
1180: }
1181:
1182: /* Load the multicast filter. */
1183: kue_setmulti(sc);
1184:
1185: if (sc->kue_ep[KUE_ENDPT_RX] == NULL) {
1186: if (kue_open_pipes(sc)) {
1187: splx(s);
1188: return;
1189: }
1190: }
1191:
1192: ifp->if_flags |= IFF_RUNNING;
1193: ifp->if_flags &= ~IFF_OACTIVE;
1194:
1195: splx(s);
1196: }
1197:
1.24 augustss 1198: Static int
1.29 augustss 1199: kue_open_pipes(struct kue_softc *sc)
1.1 augustss 1200: {
1201: usbd_status err;
1202: struct kue_chain *c;
1203: int i;
1204:
1205: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1206:
1207: /* Open RX and TX pipes. */
1208: err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_RX],
1209: USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_RX]);
1210: if (err) {
1211: printf("%s: open rx pipe failed: %s\n",
1212: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1213: return (EIO);
1214: }
1215:
1216: err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX],
1217: USBD_EXCLUSIVE_USE, &sc->kue_ep[KUE_ENDPT_TX]);
1218: if (err) {
1219: printf("%s: open tx pipe failed: %s\n",
1220: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1221: return (EIO);
1222: }
1223:
1224: /* Start up the receive pipe. */
1225: for (i = 0; i < KUE_RX_LIST_CNT; i++) {
1226: c = &sc->kue_cdata.kue_rx_chain[i];
1227: usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX],
1228: c, c->kue_buf, KUE_BUFSZ,
1229: USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
1230: kue_rxeof);
1231: DPRINTFN(5,("%s: %s: start read\n", USBDEVNAME(sc->kue_dev),
1232: __FUNCTION__));
1.18 augustss 1233: usbd_transfer(c->kue_xfer);
1.1 augustss 1234: }
1235:
1236: return (0);
1237: }
1238:
1.24 augustss 1239: Static int
1.29 augustss 1240: kue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1.1 augustss 1241: {
1242: struct kue_softc *sc = ifp->if_softc;
1243: #if defined(__NetBSD__) || defined(__OpenBSD__)
1244: struct ifaddr *ifa = (struct ifaddr *)data;
1245: struct ifreq *ifr = (struct ifreq *)data;
1246: #endif
1247: int s, error = 0;
1248:
1249: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1250:
1.6 augustss 1251: if (sc->kue_dying)
1252: return (EIO);
1253:
1.1 augustss 1254: s = splimp();
1255:
1256: switch(command) {
1257: #if defined(__FreeBSD__)
1258: case SIOCSIFADDR:
1259: case SIOCGIFADDR:
1260: case SIOCSIFMTU:
1261: error = ether_ioctl(ifp, command, data);
1262: break;
1263: #elif defined(__NetBSD__) || defined(__OpenBSD__)
1264: case SIOCSIFADDR:
1265: ifp->if_flags |= IFF_UP;
1266: kue_init(sc);
1267:
1268: switch (ifa->ifa_addr->sa_family) {
1269: #ifdef INET
1270: case AF_INET:
1.26 augustss 1271: #if defined(__NetBSD__)
1.1 augustss 1272: arp_ifinit(ifp, ifa);
1.26 augustss 1273: #else
1274: arp_ifinit(&sc->arpcom, ifa);
1275: #endif
1.1 augustss 1276: break;
1277: #endif /* INET */
1278: #ifdef NS
1279: case AF_NS:
1280: {
1281: struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
1282:
1283: if (ns_nullhost(*ina))
1284: ina->x_host = *(union ns_host *)
1285: LLADDR(ifp->if_sadl);
1286: else
1287: memcpy(LLADDR(ifp->if_sadl),
1288: ina->x_host.c_host,
1289: ifp->if_addrlen);
1290: break;
1291: }
1292: #endif /* NS */
1293: }
1294: break;
1295:
1296: case SIOCSIFMTU:
1297: if (ifr->ifr_mtu > ETHERMTU)
1298: error = EINVAL;
1299: else
1300: ifp->if_mtu = ifr->ifr_mtu;
1301: break;
1302:
1303: #endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
1304:
1305: case SIOCSIFFLAGS:
1306: if (ifp->if_flags & IFF_UP) {
1307: if (ifp->if_flags & IFF_RUNNING &&
1308: ifp->if_flags & IFF_PROMISC &&
1309: !(sc->kue_if_flags & IFF_PROMISC)) {
1310: sc->kue_rxfilt |= KUE_RXFILT_PROMISC;
1311: kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
1312: sc->kue_rxfilt);
1313: } else if (ifp->if_flags & IFF_RUNNING &&
1314: !(ifp->if_flags & IFF_PROMISC) &&
1315: sc->kue_if_flags & IFF_PROMISC) {
1316: sc->kue_rxfilt &= ~KUE_RXFILT_PROMISC;
1317: kue_setword(sc, KUE_CMD_SET_PKT_FILTER,
1318: sc->kue_rxfilt);
1319: } else if (!(ifp->if_flags & IFF_RUNNING))
1320: kue_init(sc);
1321: } else {
1322: if (ifp->if_flags & IFF_RUNNING)
1323: kue_stop(sc);
1324: }
1325: sc->kue_if_flags = ifp->if_flags;
1326: error = 0;
1327: break;
1328: case SIOCADDMULTI:
1329: case SIOCDELMULTI:
1330: kue_setmulti(sc);
1331: error = 0;
1332: break;
1333: default:
1334: error = EINVAL;
1335: break;
1336: }
1337:
1338: splx(s);
1339:
1340: return (error);
1341: }
1342:
1.24 augustss 1343: Static void
1.29 augustss 1344: kue_watchdog(struct ifnet *ifp)
1.1 augustss 1345: {
1346: struct kue_softc *sc = ifp->if_softc;
1347:
1348: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1.6 augustss 1349:
1350: if (sc->kue_dying)
1351: return;
1.1 augustss 1352:
1353: ifp->if_oerrors++;
1354: printf("%s: watchdog timeout\n", USBDEVNAME(sc->kue_dev));
1355:
1356: /*
1357: * The polling business is a kludge to avoid allowing the
1358: * USB code to call tsleep() in usbd_delay_ms(), which will
1359: * kill us since the watchdog routine is invoked from
1360: * interrupt context.
1361: */
1362: usbd_set_polling(sc->kue_udev, 1);
1363: kue_stop(sc);
1364: kue_init(sc);
1365: usbd_set_polling(sc->kue_udev, 0);
1366:
1.34 ! thorpej 1367: if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1 augustss 1368: kue_start(ifp);
1369: }
1370:
1371: /*
1372: * Stop the adapter and free any mbufs allocated to the
1373: * RX and TX lists.
1374: */
1.24 augustss 1375: Static void
1.29 augustss 1376: kue_stop(struct kue_softc *sc)
1.1 augustss 1377: {
1378: usbd_status err;
1379: struct ifnet *ifp;
1380: int i;
1381:
1382: DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1383:
1384: ifp = GET_IFP(sc);
1385: ifp->if_timer = 0;
1386:
1387: /* Stop transfers. */
1388: if (sc->kue_ep[KUE_ENDPT_RX] != NULL) {
1389: err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_RX]);
1390: if (err) {
1391: printf("%s: abort rx pipe failed: %s\n",
1392: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1393: }
1394: err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]);
1395: if (err) {
1396: printf("%s: close rx pipe failed: %s\n",
1397: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1398: }
1399: sc->kue_ep[KUE_ENDPT_RX] = NULL;
1400: }
1401:
1402: if (sc->kue_ep[KUE_ENDPT_TX] != NULL) {
1403: err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_TX]);
1404: if (err) {
1405: printf("%s: abort tx pipe failed: %s\n",
1406: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1407: }
1408: err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]);
1409: if (err) {
1410: printf("%s: close tx pipe failed: %s\n",
1411: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1412: }
1413: sc->kue_ep[KUE_ENDPT_TX] = NULL;
1414: }
1415:
1416: if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) {
1417: err = usbd_abort_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
1418: if (err) {
1419: printf("%s: abort intr pipe failed: %s\n",
1420: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1421: }
1422: err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]);
1423: if (err) {
1424: printf("%s: close intr pipe failed: %s\n",
1425: USBDEVNAME(sc->kue_dev), usbd_errstr(err));
1426: }
1427: sc->kue_ep[KUE_ENDPT_INTR] = NULL;
1428: }
1429:
1430: /* Free RX resources. */
1431: for (i = 0; i < KUE_RX_LIST_CNT; i++) {
1432: if (sc->kue_cdata.kue_rx_chain[i].kue_mbuf != NULL) {
1433: m_freem(sc->kue_cdata.kue_rx_chain[i].kue_mbuf);
1434: sc->kue_cdata.kue_rx_chain[i].kue_mbuf = NULL;
1435: }
1436: if (sc->kue_cdata.kue_rx_chain[i].kue_xfer != NULL) {
1437: usbd_free_xfer(sc->kue_cdata.kue_rx_chain[i].kue_xfer);
1438: sc->kue_cdata.kue_rx_chain[i].kue_xfer = NULL;
1439: }
1440: }
1441:
1442: /* Free TX resources. */
1443: for (i = 0; i < KUE_TX_LIST_CNT; i++) {
1444: if (sc->kue_cdata.kue_tx_chain[i].kue_mbuf != NULL) {
1445: m_freem(sc->kue_cdata.kue_tx_chain[i].kue_mbuf);
1446: sc->kue_cdata.kue_tx_chain[i].kue_mbuf = NULL;
1447: }
1448: if (sc->kue_cdata.kue_tx_chain[i].kue_xfer != NULL) {
1449: usbd_free_xfer(sc->kue_cdata.kue_tx_chain[i].kue_xfer);
1450: sc->kue_cdata.kue_tx_chain[i].kue_xfer = NULL;
1451: }
1452: }
1453:
1454: ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1455: }
1456:
1457: #ifdef __FreeBSD__
1458: /*
1459: * Stop all chip I/O so that the kernel's probe routines don't
1460: * get confused by errant DMAs when rebooting.
1461: */
1.24 augustss 1462: Static void
1.29 augustss 1463: kue_shutdown(device_t dev)
1.1 augustss 1464: {
1465: struct kue_softc *sc;
1466:
1467: sc = device_get_softc(dev);
1468:
1469: kue_stop(sc);
1470: }
1471: #endif
CVSweb <webmaster@jp.NetBSD.org>