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