if_kue.c revision 1.30 1 /* $NetBSD: if_kue.c,v 1.30 2000/10/01 23:32:45 thorpej Exp $ */
2 /*
3 * Copyright (c) 1997, 1998, 1999, 2000
4 * Bill Paul <wpaul (at) 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 (at) 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 */
78 #if defined(__NetBSD__)
79 #include "opt_inet.h"
80 #include "opt_ns.h"
81 #include "bpfilter.h"
82 #include "rnd.h"
83 #elif defined(__OpenBSD__)
84 #include "bpfilter.h"
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>
104 #if NRND > 0
105 #include <sys/rnd.h>
106 #endif
107
108 #endif
109
110 #include <net/if.h>
111 #if defined(__NetBSD__) || defined(__FreeBSD__)
112 #include <net/if_arp.h>
113 #endif
114 #include <net/if_dl.h>
115
116 #if defined(__NetBSD__) || defined(__OpenBSD__)
117 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
118 #else
119 #define BPF_MTAP(ifp, m) bpf_mtap((ifp), (m))
120 #endif
121
122 #if defined(__FreeBSD__) || NBPFILTER > 0
123 #include <net/bpf.h>
124 #endif
125
126 #if defined(__NetBSD__)
127 #include <net/if_ether.h>
128 #ifdef INET
129 #include <netinet/in.h>
130 #include <netinet/if_inarp.h>
131 #endif
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__) */
143
144 #if defined(__NetBSD__) || defined(__OpenBSD__)
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 */
175 Static struct kue_type kue_devs[] = {
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 },
184 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3C460 },
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 },
188 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_USB10T },
189 { USB_VENDOR_KLSI, USB_PRODUCT_KLSI_DUH3E10BT },
190 { 0, 0 }
191 };
192
193 USB_DECLARE_DRIVER(kue);
194
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 *);
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
223 Static void kue_rxstart(struct ifnet *);
224 Static void kue_shutdown(device_t);
225
226 Static struct usb_qdat kue_qdat;
227
228 Static device_method_t kue_methods[] = {
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
238 Static driver_t kue_driver = {
239 "kue",
240 kue_methods,
241 sizeof(struct kue_softc)
242 };
243
244 Static devclass_t kue_devclass;
245
246 DRIVER_MODULE(if_kue, uhub, kue_driver, kue_devclass, usbd_driver_load, 0);
247
248 #endif /* __FreeBSD__ */
249
250 #define KUE_DO_REQUEST(dev, req, data) \
251 usbd_do_request_flags(dev, req, data, USBD_NO_TSLEEP, NULL)
252
253 Static usbd_status
254 kue_setword(struct kue_softc *sc, u_int8_t breq, u_int16_t word)
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();
269 err = KUE_DO_REQUEST(sc->kue_udev, &req, NULL);
270 splx(s);
271
272 return (err);
273 }
274
275 Static usbd_status
276 kue_ctl(struct kue_softc *sc, int rw, u_int8_t breq, u_int16_t val,
277 void *data, u_int32_t len)
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();
297 err = KUE_DO_REQUEST(sc->kue_udev, &req, data);
298 splx(s);
299
300 return (err);
301 }
302
303 Static int
304 kue_is_warm(struct kue_softc *sc)
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
321 Static int
322 kue_load_fw(struct kue_softc *sc)
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 *
337 * We can test this quickly by issuing a request that
338 * is only valid after firmware download.
339 */
340 if (kue_is_warm(sc)) {
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
402 Static void
403 kue_setmulti(struct kue_softc *sc)
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__)
442 #if defined (__NetBSD__)
443 ETHER_FIRST_MULTI(step, &sc->kue_ec, enm);
444 #else
445 ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
446 #endif
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 */
480 Static void
481 kue_reset(struct kue_softc *sc)
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 &&
579 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
580 sc->kue_ed[KUE_ENDPT_RX] = ed->bEndpointAddress;
581 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
582 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
583 sc->kue_ed[KUE_ENDPT_TX] = ed->bEndpointAddress;
584 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
585 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
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,
597 0, &sc->kue_desc, sizeof(sc->kue_desc));
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;
661 #if defined(__OpenBSD__)
662 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
663 #endif
664 strncpy(ifp->if_xname, USBDEVNAME(sc->kue_dev), IFNAMSIZ);
665
666 /* Attach the interface. */
667 if_attach(ifp);
668 Ether_ifattach(ifp, sc->kue_desc.kue_macaddr);
669
670 #if NBPFILTER > 0
671 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB,
672 sizeof(struct ether_header));
673 #endif
674 #if NRND > 0
675 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->kue_dev),
676 RND_TYPE_NET, 0);
677 #endif
678
679 #endif /* __NetBSD__ */
680 sc->kue_attached = 1;
681 splx(s);
682
683 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->kue_udev,
684 USBDEV(sc->kue_dev));
685
686 USB_ATTACH_SUCCESS_RETURN;
687 }
688
689 USB_DETACH(kue)
690 {
691 USB_DETACH_START(kue, sc);
692 struct ifnet *ifp = GET_IFP(sc);
693 int s;
694
695 s = splusb(); /* XXX why? */
696
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
708 if (ifp->if_flags & IFF_RUNNING)
709 kue_stop(sc);
710
711 #if defined(__NetBSD__)
712 #if NRND > 0
713 rnd_detach_source(&sc->rnd_source);
714 #endif
715 #if NBPFILTER > 0
716 bpfdetach(ifp);
717 #endif
718 ether_ifdetach(ifp);
719 #endif /* __NetBSD__ */
720
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
730
731 sc->kue_attached = 0;
732 splx(s);
733
734 return (0);
735 }
736
737 #if defined(__NetBSD__) || defined(__OpenBSD__)
738 int
739 kue_activate(device_ptr_t self, enum devact act)
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:
751 #if defined(__NetBSD__)
752 /* Deactivate the interface. */
753 if_deactivate(&sc->kue_ec.ec_if);
754 #endif
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 */
765 Static int
766 kue_newbuf(struct kue_softc *sc, struct kue_chain *c, struct mbuf *m)
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
799 Static int
800 kue_rx_list_init(struct kue_softc *sc)
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
828 Static int
829 kue_tx_list_init(struct kue_softc *sc)
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__
857 Static void
858 kue_rxstart(struct ifnet *ifp)
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 */
883 Static void
884 kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
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
898 if (sc->kue_dying)
899 return;
900
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;
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 }
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
928 m = c->kue_mbuf;
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
962 #if NBPFILTER > 0
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 */
969 if (ifp->if_bpf)
970 BPF_MTAP(ifp, m);
971 #endif
972
973 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->kue_dev),
974 __FUNCTION__, m->m_len));
975 IF_INPUT(ifp, m);
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
997 Static void
998 kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
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
1005 if (sc->kue_dying)
1006 return;
1007
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
1047 Static int
1048 kue_send(struct kue_softc *sc, struct mbuf *m, int idx)
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],
1074 c, c->kue_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, kue_txeof);
1075
1076 /* Transmit */
1077 err = usbd_transfer(c->kue_xfer);
1078 if (err != USBD_IN_PROGRESS) {
1079 printf("%s: kue_send error=%s\n", USBDEVNAME(sc->kue_dev),
1080 usbd_errstr(err));
1081 kue_stop(sc);
1082 return (EIO);
1083 }
1084
1085 sc->kue_cdata.kue_tx_cnt++;
1086
1087 return (0);
1088 }
1089
1090 Static void
1091 kue_start(struct ifnet *ifp)
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
1098 if (sc->kue_dying)
1099 return;
1100
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
1114 #if NBPFILTER > 0
1115 /*
1116 * If there's a BPF listener, bounce a copy of this frame
1117 * to him.
1118 */
1119 if (ifp->if_bpf)
1120 BPF_MTAP(ifp, m_head);
1121 #endif
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
1131 Static void
1132 kue_init(void *xsc)
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
1146 #if defined(__FreeBSD__) || defined(__OpenBSD__)
1147 eaddr = sc->arpcom.ac_enaddr;
1148 #elif defined(__NetBSD__)
1149 eaddr = LLADDR(ifp->if_sadl);
1150 #endif /* defined(__NetBSD__) */
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
1202 Static int
1203 kue_open_pipes(struct kue_softc *sc)
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__));
1237 usbd_transfer(c->kue_xfer);
1238 }
1239
1240 return (0);
1241 }
1242
1243 Static int
1244 kue_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
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
1255 if (sc->kue_dying)
1256 return (EIO);
1257
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:
1275 #if defined(__NetBSD__)
1276 arp_ifinit(ifp, ifa);
1277 #else
1278 arp_ifinit(&sc->arpcom, ifa);
1279 #endif
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
1347 Static void
1348 kue_watchdog(struct ifnet *ifp)
1349 {
1350 struct kue_softc *sc = ifp->if_softc;
1351
1352 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->kue_dev),__FUNCTION__));
1353
1354 if (sc->kue_dying)
1355 return;
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 */
1379 Static void
1380 kue_stop(struct kue_softc *sc)
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 */
1466 Static void
1467 kue_shutdown(device_t dev)
1468 {
1469 struct kue_softc *sc;
1470
1471 sc = device_get_softc(dev);
1472
1473 kue_stop(sc);
1474 }
1475 #endif
1476