1 /* $NetBSD: if_cue.c,v 1.57 2010/01/19 22:07:43 pooka Exp $ */ 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_cue.c,v 1.4 2000/01/16 22:45:06 wpaul Exp $ 34 */ 35 36 /* 37 * CATC USB-EL1210A USB to ethernet driver. Used in the CATC Netmate 38 * adapters and others. 39 * 40 * Written by Bill Paul <wpaul@ee.columbia.edu> 41 * Electrical Engineering Department 42 * Columbia University, New York City 43 */ 44 45 /* 46 * The CATC USB-EL1210A provides USB ethernet support at 10Mbps. The 47 * RX filter uses a 512-bit multicast hash table, single perfect entry 48 * for the station address, and promiscuous mode. Unlike the ADMtek 49 * and KLSI chips, the CATC ASIC supports read and write combining 50 * mode where multiple packets can be transfered using a single bulk 51 * transaction, which helps performance a great deal. 52 */ 53 54 /* 55 * Ported to NetBSD and somewhat rewritten by Lennart Augustsson. 56 */ 57 58 #include <sys/cdefs.h> 59 __KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.57 2010/01/19 22:07:43 pooka Exp $"); 60 61 #if defined(__NetBSD__) 62 #include "opt_inet.h" 63 #include "rnd.h" 64 #elif defined(__OpenBSD__) 65 include "bpfilter.h" 66 #endif /* defined(__OpenBSD__) */ 67 68 #include <sys/param.h> 69 #include <sys/systm.h> 70 #if !defined(__OpenBSD__) 71 #include <sys/callout.h> 72 #endif 73 #include <sys/sockio.h> 74 #include <sys/mbuf.h> 75 #include <sys/malloc.h> 76 #include <sys/kernel.h> 77 #include <sys/socket.h> 78 79 #include <sys/device.h> 80 #if NRND > 0 81 #include <sys/rnd.h> 82 #endif 83 84 #include <net/if.h> 85 #if defined(__NetBSD__) 86 #include <net/if_arp.h> 87 #endif 88 #include <net/if_dl.h> 89 90 #include <net/bpf.h> 91 92 #if defined(__NetBSD__) 93 #include <net/if_ether.h> 94 #ifdef INET 95 #include <netinet/in.h> 96 #include <netinet/if_inarp.h> 97 #endif 98 #endif /* defined(__NetBSD__) */ 99 100 #if defined(__OpenBSD__) 101 #ifdef INET 102 #include <netinet/in.h> 103 #include <netinet/in_systm.h> 104 #include <netinet/in_var.h> 105 #include <netinet/ip.h> 106 #include <netinet/if_ether.h> 107 #endif 108 #endif /* defined(__OpenBSD__) */ 109 110 111 #include <dev/usb/usb.h> 112 #include <dev/usb/usbdi.h> 113 #include <dev/usb/usbdi_util.h> 114 #include <dev/usb/usbdevs.h> 115 116 #include <dev/usb/if_cuereg.h> 117 118 #ifdef CUE_DEBUG 119 #define DPRINTF(x) if (cuedebug) logprintf x 120 #define DPRINTFN(n,x) if (cuedebug >= (n)) logprintf x 121 int cuedebug = 0; 122 #else 123 #define DPRINTF(x) 124 #define DPRINTFN(n,x) 125 #endif 126 127 /* 128 * Various supported device vendors/products. 129 */ 130 Static struct usb_devno cue_devs[] = { 131 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE }, 132 { USB_VENDOR_CATC, USB_PRODUCT_CATC_NETMATE2 }, 133 { USB_VENDOR_SMARTBRIDGES, USB_PRODUCT_SMARTBRIDGES_SMARTLINK }, 134 /* Belkin F5U111 adapter covered by NETMATE entry */ 135 }; 136 #define cue_lookup(v, p) (usb_lookup(cue_devs, v, p)) 137 138 USB_DECLARE_DRIVER(cue); 139 140 Static int cue_open_pipes(struct cue_softc *); 141 Static int cue_tx_list_init(struct cue_softc *); 142 Static int cue_rx_list_init(struct cue_softc *); 143 Static int cue_newbuf(struct cue_softc *, struct cue_chain *, struct mbuf *); 144 Static int cue_send(struct cue_softc *, struct mbuf *, int); 145 Static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 146 Static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 147 Static void cue_tick(void *); 148 Static void cue_tick_task(void *); 149 Static void cue_start(struct ifnet *); 150 Static int cue_ioctl(struct ifnet *, u_long, void *); 151 Static void cue_init(void *); 152 Static void cue_stop(struct cue_softc *); 153 Static void cue_watchdog(struct ifnet *); 154 155 Static void cue_setmulti(struct cue_softc *); 156 Static u_int32_t cue_crc(const char *); 157 Static void cue_reset(struct cue_softc *); 158 159 Static int cue_csr_read_1(struct cue_softc *, int); 160 Static int cue_csr_write_1(struct cue_softc *, int, int); 161 Static int cue_csr_read_2(struct cue_softc *, int); 162 #if 0 163 Static int cue_csr_write_2(struct cue_softc *, int, int); 164 #endif 165 Static int cue_mem(struct cue_softc *, int, int, void *, int); 166 Static int cue_getmac(struct cue_softc *, void *); 167 168 #define CUE_SETBIT(sc, reg, x) \ 169 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) | (x)) 170 171 #define CUE_CLRBIT(sc, reg, x) \ 172 cue_csr_write_1(sc, reg, cue_csr_read_1(sc, reg) & ~(x)) 173 174 Static int 175 cue_csr_read_1(struct cue_softc *sc, int reg) 176 { 177 usb_device_request_t req; 178 usbd_status err; 179 u_int8_t val = 0; 180 181 if (sc->cue_dying) 182 return (0); 183 184 req.bmRequestType = UT_READ_VENDOR_DEVICE; 185 req.bRequest = CUE_CMD_READREG; 186 USETW(req.wValue, 0); 187 USETW(req.wIndex, reg); 188 USETW(req.wLength, 1); 189 190 err = usbd_do_request(sc->cue_udev, &req, &val); 191 192 if (err) { 193 DPRINTF(("%s: cue_csr_read_1: reg=0x%x err=%s\n", 194 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); 195 return (0); 196 } 197 198 DPRINTFN(10,("%s: cue_csr_read_1 reg=0x%x val=0x%x\n", 199 USBDEVNAME(sc->cue_dev), reg, val)); 200 201 return (val); 202 } 203 204 Static int 205 cue_csr_read_2(struct cue_softc *sc, int reg) 206 { 207 usb_device_request_t req; 208 usbd_status err; 209 uWord val; 210 211 if (sc->cue_dying) 212 return (0); 213 214 req.bmRequestType = UT_READ_VENDOR_DEVICE; 215 req.bRequest = CUE_CMD_READREG; 216 USETW(req.wValue, 0); 217 USETW(req.wIndex, reg); 218 USETW(req.wLength, 2); 219 220 err = usbd_do_request(sc->cue_udev, &req, &val); 221 222 DPRINTFN(10,("%s: cue_csr_read_2 reg=0x%x val=0x%x\n", 223 USBDEVNAME(sc->cue_dev), reg, UGETW(val))); 224 225 if (err) { 226 DPRINTF(("%s: cue_csr_read_2: reg=0x%x err=%s\n", 227 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); 228 return (0); 229 } 230 231 return (UGETW(val)); 232 } 233 234 Static int 235 cue_csr_write_1(struct cue_softc *sc, int reg, int val) 236 { 237 usb_device_request_t req; 238 usbd_status err; 239 240 if (sc->cue_dying) 241 return (0); 242 243 DPRINTFN(10,("%s: cue_csr_write_1 reg=0x%x val=0x%x\n", 244 USBDEVNAME(sc->cue_dev), reg, val)); 245 246 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 247 req.bRequest = CUE_CMD_WRITEREG; 248 USETW(req.wValue, val); 249 USETW(req.wIndex, reg); 250 USETW(req.wLength, 0); 251 252 err = usbd_do_request(sc->cue_udev, &req, NULL); 253 254 if (err) { 255 DPRINTF(("%s: cue_csr_write_1: reg=0x%x err=%s\n", 256 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); 257 return (-1); 258 } 259 260 DPRINTFN(20,("%s: cue_csr_write_1, after reg=0x%x val=0x%x\n", 261 USBDEVNAME(sc->cue_dev), reg, cue_csr_read_1(sc, reg))); 262 263 return (0); 264 } 265 266 #if 0 267 Static int 268 cue_csr_write_2(struct cue_softc *sc, int reg, int aval) 269 { 270 usb_device_request_t req; 271 usbd_status err; 272 uWord val; 273 int s; 274 275 if (sc->cue_dying) 276 return (0); 277 278 DPRINTFN(10,("%s: cue_csr_write_2 reg=0x%x val=0x%x\n", 279 USBDEVNAME(sc->cue_dev), reg, aval)); 280 281 USETW(val, aval); 282 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 283 req.bRequest = CUE_CMD_WRITEREG; 284 USETW(req.wValue, val); 285 USETW(req.wIndex, reg); 286 USETW(req.wLength, 0); 287 288 err = usbd_do_request(sc->cue_udev, &req, NULL); 289 290 if (err) { 291 DPRINTF(("%s: cue_csr_write_2: reg=0x%x err=%s\n", 292 USBDEVNAME(sc->cue_dev), reg, usbd_errstr(err))); 293 return (-1); 294 } 295 296 return (0); 297 } 298 #endif 299 300 Static int 301 cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len) 302 { 303 usb_device_request_t req; 304 usbd_status err; 305 306 DPRINTFN(10,("%s: cue_mem cmd=0x%x addr=0x%x len=%d\n", 307 USBDEVNAME(sc->cue_dev), cmd, addr, len)); 308 309 if (cmd == CUE_CMD_READSRAM) 310 req.bmRequestType = UT_READ_VENDOR_DEVICE; 311 else 312 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 313 req.bRequest = cmd; 314 USETW(req.wValue, 0); 315 USETW(req.wIndex, addr); 316 USETW(req.wLength, len); 317 318 err = usbd_do_request(sc->cue_udev, &req, buf); 319 320 if (err) { 321 DPRINTF(("%s: cue_csr_mem: addr=0x%x err=%s\n", 322 USBDEVNAME(sc->cue_dev), addr, usbd_errstr(err))); 323 return (-1); 324 } 325 326 return (0); 327 } 328 329 Static int 330 cue_getmac(struct cue_softc *sc, void *buf) 331 { 332 usb_device_request_t req; 333 usbd_status err; 334 335 DPRINTFN(10,("%s: cue_getmac\n", USBDEVNAME(sc->cue_dev))); 336 337 req.bmRequestType = UT_READ_VENDOR_DEVICE; 338 req.bRequest = CUE_CMD_GET_MACADDR; 339 USETW(req.wValue, 0); 340 USETW(req.wIndex, 0); 341 USETW(req.wLength, ETHER_ADDR_LEN); 342 343 err = usbd_do_request(sc->cue_udev, &req, buf); 344 345 if (err) { 346 printf("%s: read MAC address failed\n",USBDEVNAME(sc->cue_dev)); 347 return (-1); 348 } 349 350 return (0); 351 } 352 353 #define CUE_POLY 0xEDB88320 354 #define CUE_BITS 9 355 356 Static u_int32_t 357 cue_crc(const char *addr) 358 { 359 u_int32_t idx, bit, data, crc; 360 361 /* Compute CRC for the address value. */ 362 crc = 0xFFFFFFFF; /* initial value */ 363 364 for (idx = 0; idx < 6; idx++) { 365 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) 366 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0); 367 } 368 369 return (crc & ((1 << CUE_BITS) - 1)); 370 } 371 372 Static void 373 cue_setmulti(struct cue_softc *sc) 374 { 375 struct ifnet *ifp; 376 struct ether_multi *enm; 377 struct ether_multistep step; 378 u_int32_t h, i; 379 380 ifp = GET_IFP(sc); 381 382 DPRINTFN(2,("%s: cue_setmulti if_flags=0x%x\n", 383 USBDEVNAME(sc->cue_dev), ifp->if_flags)); 384 385 if (ifp->if_flags & IFF_PROMISC) { 386 allmulti: 387 ifp->if_flags |= IFF_ALLMULTI; 388 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) 389 sc->cue_mctab[i] = 0xFF; 390 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, 391 &sc->cue_mctab, CUE_MCAST_TABLE_LEN); 392 return; 393 } 394 395 /* first, zot all the existing hash bits */ 396 for (i = 0; i < CUE_MCAST_TABLE_LEN; i++) 397 sc->cue_mctab[i] = 0; 398 399 /* now program new ones */ 400 #if defined(__NetBSD__) 401 ETHER_FIRST_MULTI(step, &sc->cue_ec, enm); 402 #else 403 ETHER_FIRST_MULTI(step, &sc->arpcom, enm); 404 #endif 405 while (enm != NULL) { 406 if (memcmp(enm->enm_addrlo, 407 enm->enm_addrhi, ETHER_ADDR_LEN) != 0) 408 goto allmulti; 409 410 h = cue_crc(enm->enm_addrlo); 411 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); 412 ETHER_NEXT_MULTI(step, enm); 413 } 414 415 ifp->if_flags &= ~IFF_ALLMULTI; 416 417 /* 418 * Also include the broadcast address in the filter 419 * so we can receive broadcast frames. 420 */ 421 if (ifp->if_flags & IFF_BROADCAST) { 422 h = cue_crc(etherbroadcastaddr); 423 sc->cue_mctab[h >> 3] |= 1 << (h & 0x7); 424 } 425 426 cue_mem(sc, CUE_CMD_WRITESRAM, CUE_MCAST_TABLE_ADDR, 427 &sc->cue_mctab, CUE_MCAST_TABLE_LEN); 428 } 429 430 Static void 431 cue_reset(struct cue_softc *sc) 432 { 433 usb_device_request_t req; 434 usbd_status err; 435 436 DPRINTFN(2,("%s: cue_reset\n", USBDEVNAME(sc->cue_dev))); 437 438 if (sc->cue_dying) 439 return; 440 441 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 442 req.bRequest = CUE_CMD_RESET; 443 USETW(req.wValue, 0); 444 USETW(req.wIndex, 0); 445 USETW(req.wLength, 0); 446 447 err = usbd_do_request(sc->cue_udev, &req, NULL); 448 449 if (err) 450 printf("%s: reset failed\n", USBDEVNAME(sc->cue_dev)); 451 452 /* Wait a little while for the chip to get its brains in order. */ 453 usbd_delay_ms(sc->cue_udev, 1); 454 } 455 456 /* 457 * Probe for a CATC chip. 458 */ 459 USB_MATCH(cue) 460 { 461 USB_MATCH_START(cue, uaa); 462 463 return (cue_lookup(uaa->vendor, uaa->product) != NULL ? 464 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 465 } 466 467 /* 468 * Attach the interface. Allocate softc structures, do ifmedia 469 * setup and ethernet/BPF attach. 470 */ 471 USB_ATTACH(cue) 472 { 473 USB_ATTACH_START(cue, sc, uaa); 474 char *devinfop; 475 int s; 476 u_char eaddr[ETHER_ADDR_LEN]; 477 usbd_device_handle dev = uaa->device; 478 usbd_interface_handle iface; 479 usbd_status err; 480 struct ifnet *ifp; 481 usb_interface_descriptor_t *id; 482 usb_endpoint_descriptor_t *ed; 483 int i; 484 485 DPRINTFN(5,(" : cue_attach: sc=%p, dev=%p", sc, dev)); 486 487 sc->cue_dev = self; 488 489 aprint_naive("\n"); 490 aprint_normal("\n"); 491 492 devinfop = usbd_devinfo_alloc(dev, 0); 493 aprint_normal_dev(self, "%s\n", devinfop); 494 usbd_devinfo_free(devinfop); 495 496 err = usbd_set_config_no(dev, CUE_CONFIG_NO, 1); 497 if (err) { 498 aprint_error_dev(self, "setting config no failed\n"); 499 USB_ATTACH_ERROR_RETURN; 500 } 501 502 sc->cue_udev = dev; 503 sc->cue_product = uaa->product; 504 sc->cue_vendor = uaa->vendor; 505 506 usb_init_task(&sc->cue_tick_task, cue_tick_task, sc); 507 usb_init_task(&sc->cue_stop_task, (void (*)(void *))cue_stop, sc); 508 509 err = usbd_device2interface_handle(dev, CUE_IFACE_IDX, &iface); 510 if (err) { 511 aprint_error_dev(self, "getting interface handle failed\n"); 512 USB_ATTACH_ERROR_RETURN; 513 } 514 515 sc->cue_iface = iface; 516 id = usbd_get_interface_descriptor(iface); 517 518 /* Find endpoints. */ 519 for (i = 0; i < id->bNumEndpoints; i++) { 520 ed = usbd_interface2endpoint_descriptor(iface, i); 521 if (ed == NULL) { 522 aprint_error_dev(self, "couldn't get ep %d\n", i); 523 USB_ATTACH_ERROR_RETURN; 524 } 525 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 526 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 527 sc->cue_ed[CUE_ENDPT_RX] = ed->bEndpointAddress; 528 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 529 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 530 sc->cue_ed[CUE_ENDPT_TX] = ed->bEndpointAddress; 531 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 532 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 533 sc->cue_ed[CUE_ENDPT_INTR] = ed->bEndpointAddress; 534 } 535 } 536 537 #if 0 538 /* Reset the adapter. */ 539 cue_reset(sc); 540 #endif 541 /* 542 * Get station address. 543 */ 544 cue_getmac(sc, &eaddr); 545 546 s = splnet(); 547 548 /* 549 * A CATC chip was detected. Inform the world. 550 */ 551 aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr)); 552 553 /* Initialize interface info.*/ 554 ifp = GET_IFP(sc); 555 ifp->if_softc = sc; 556 ifp->if_mtu = ETHERMTU; 557 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 558 ifp->if_ioctl = cue_ioctl; 559 ifp->if_start = cue_start; 560 ifp->if_watchdog = cue_watchdog; 561 #if defined(__OpenBSD__) 562 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 563 #endif 564 strncpy(ifp->if_xname, USBDEVNAME(sc->cue_dev), IFNAMSIZ); 565 566 IFQ_SET_READY(&ifp->if_snd); 567 568 /* Attach the interface. */ 569 if_attach(ifp); 570 Ether_ifattach(ifp, eaddr); 571 #if NRND > 0 572 rnd_attach_source(&sc->rnd_source, USBDEVNAME(sc->cue_dev), 573 RND_TYPE_NET, 0); 574 #endif 575 576 usb_callout_init(sc->cue_stat_ch); 577 578 sc->cue_attached = 1; 579 splx(s); 580 581 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cue_udev, 582 USBDEV(sc->cue_dev)); 583 584 USB_ATTACH_SUCCESS_RETURN; 585 } 586 587 USB_DETACH(cue) 588 { 589 USB_DETACH_START(cue, sc); 590 struct ifnet *ifp = GET_IFP(sc); 591 int s; 592 593 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__)); 594 595 usb_uncallout(sc->cue_stat_ch, cue_tick, sc); 596 /* 597 * Remove any pending task. It cannot be executing because it run 598 * in the same thread as detach. 599 */ 600 usb_rem_task(sc->cue_udev, &sc->cue_tick_task); 601 usb_rem_task(sc->cue_udev, &sc->cue_stop_task); 602 603 if (!sc->cue_attached) { 604 /* Detached before attached finished, so just bail out. */ 605 return (0); 606 } 607 608 s = splusb(); 609 610 if (ifp->if_flags & IFF_RUNNING) 611 cue_stop(sc); 612 613 #if defined(__NetBSD__) 614 #if NRND > 0 615 rnd_detach_source(&sc->rnd_source); 616 #endif 617 ether_ifdetach(ifp); 618 #endif /* __NetBSD__ */ 619 620 if_detach(ifp); 621 622 #ifdef DIAGNOSTIC 623 if (sc->cue_ep[CUE_ENDPT_TX] != NULL || 624 sc->cue_ep[CUE_ENDPT_RX] != NULL || 625 sc->cue_ep[CUE_ENDPT_INTR] != NULL) 626 aprint_debug_dev(self, "detach has active endpoints\n"); 627 #endif 628 629 sc->cue_attached = 0; 630 splx(s); 631 632 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cue_udev, 633 USBDEV(sc->cue_dev)); 634 635 return (0); 636 } 637 638 int 639 cue_activate(device_ptr_t self, enum devact act) 640 { 641 struct cue_softc *sc = device_private(self); 642 643 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__)); 644 645 switch (act) { 646 case DVACT_DEACTIVATE: 647 /* Deactivate the interface. */ 648 if_deactivate(&sc->cue_ec.ec_if); 649 sc->cue_dying = 1; 650 return 0; 651 default: 652 return EOPNOTSUPP; 653 } 654 } 655 656 /* 657 * Initialize an RX descriptor and attach an MBUF cluster. 658 */ 659 Static int 660 cue_newbuf(struct cue_softc *sc, struct cue_chain *c, struct mbuf *m) 661 { 662 struct mbuf *m_new = NULL; 663 664 if (m == NULL) { 665 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 666 if (m_new == NULL) { 667 printf("%s: no memory for rx list " 668 "-- packet dropped!\n", USBDEVNAME(sc->cue_dev)); 669 return (ENOBUFS); 670 } 671 672 MCLGET(m_new, M_DONTWAIT); 673 if (!(m_new->m_flags & M_EXT)) { 674 printf("%s: no memory for rx list " 675 "-- packet dropped!\n", USBDEVNAME(sc->cue_dev)); 676 m_freem(m_new); 677 return (ENOBUFS); 678 } 679 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 680 } else { 681 m_new = m; 682 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 683 m_new->m_data = m_new->m_ext.ext_buf; 684 } 685 686 m_adj(m_new, ETHER_ALIGN); 687 c->cue_mbuf = m_new; 688 689 return (0); 690 } 691 692 Static int 693 cue_rx_list_init(struct cue_softc *sc) 694 { 695 struct cue_cdata *cd; 696 struct cue_chain *c; 697 int i; 698 699 cd = &sc->cue_cdata; 700 for (i = 0; i < CUE_RX_LIST_CNT; i++) { 701 c = &cd->cue_rx_chain[i]; 702 c->cue_sc = sc; 703 c->cue_idx = i; 704 if (cue_newbuf(sc, c, NULL) == ENOBUFS) 705 return (ENOBUFS); 706 if (c->cue_xfer == NULL) { 707 c->cue_xfer = usbd_alloc_xfer(sc->cue_udev); 708 if (c->cue_xfer == NULL) 709 return (ENOBUFS); 710 c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ); 711 if (c->cue_buf == NULL) { 712 usbd_free_xfer(c->cue_xfer); 713 return (ENOBUFS); 714 } 715 } 716 } 717 718 return (0); 719 } 720 721 Static int 722 cue_tx_list_init(struct cue_softc *sc) 723 { 724 struct cue_cdata *cd; 725 struct cue_chain *c; 726 int i; 727 728 cd = &sc->cue_cdata; 729 for (i = 0; i < CUE_TX_LIST_CNT; i++) { 730 c = &cd->cue_tx_chain[i]; 731 c->cue_sc = sc; 732 c->cue_idx = i; 733 c->cue_mbuf = NULL; 734 if (c->cue_xfer == NULL) { 735 c->cue_xfer = usbd_alloc_xfer(sc->cue_udev); 736 if (c->cue_xfer == NULL) 737 return (ENOBUFS); 738 c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ); 739 if (c->cue_buf == NULL) { 740 usbd_free_xfer(c->cue_xfer); 741 return (ENOBUFS); 742 } 743 } 744 } 745 746 return (0); 747 } 748 749 /* 750 * A frame has been uploaded: pass the resulting mbuf chain up to 751 * the higher level protocols. 752 */ 753 Static void 754 cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 755 { 756 struct cue_chain *c = priv; 757 struct cue_softc *sc = c->cue_sc; 758 struct ifnet *ifp = GET_IFP(sc); 759 struct mbuf *m; 760 int total_len = 0; 761 u_int16_t len; 762 int s; 763 764 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev), 765 __func__, status)); 766 767 if (sc->cue_dying) 768 return; 769 770 if (!(ifp->if_flags & IFF_RUNNING)) 771 return; 772 773 if (status != USBD_NORMAL_COMPLETION) { 774 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 775 return; 776 sc->cue_rx_errs++; 777 if (usbd_ratecheck(&sc->cue_rx_notice)) { 778 printf("%s: %u usb errors on rx: %s\n", 779 USBDEVNAME(sc->cue_dev), sc->cue_rx_errs, 780 usbd_errstr(status)); 781 sc->cue_rx_errs = 0; 782 } 783 if (status == USBD_STALLED) 784 usbd_clear_endpoint_stall_async(sc->cue_ep[CUE_ENDPT_RX]); 785 goto done; 786 } 787 788 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 789 790 memcpy(mtod(c->cue_mbuf, char *), c->cue_buf, total_len); 791 792 m = c->cue_mbuf; 793 len = UGETW(mtod(m, u_int8_t *)); 794 795 /* No errors; receive the packet. */ 796 total_len = len; 797 798 if (len < sizeof(struct ether_header)) { 799 ifp->if_ierrors++; 800 goto done; 801 } 802 803 ifp->if_ipackets++; 804 m_adj(m, sizeof(u_int16_t)); 805 m->m_pkthdr.len = m->m_len = total_len; 806 807 m->m_pkthdr.rcvif = ifp; 808 809 s = splnet(); 810 811 /* XXX ugly */ 812 if (cue_newbuf(sc, c, NULL) == ENOBUFS) { 813 ifp->if_ierrors++; 814 goto done1; 815 } 816 817 /* 818 * Handle BPF listeners. Let the BPF user see the packet, but 819 * don't pass it up to the ether_input() layer unless it's 820 * a broadcast packet, multicast packet, matches our ethernet 821 * address or the interface is in promiscuous mode. 822 */ 823 if (ifp->if_bpf) 824 bpf_ops->bpf_mtap(ifp->if_bpf, m); 825 826 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->cue_dev), 827 __func__, m->m_len)); 828 IF_INPUT(ifp, m); 829 done1: 830 splx(s); 831 832 done: 833 /* Setup new transfer. */ 834 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX], 835 c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 836 USBD_NO_TIMEOUT, cue_rxeof); 837 usbd_transfer(c->cue_xfer); 838 839 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->cue_dev), 840 __func__)); 841 } 842 843 /* 844 * A frame was downloaded to the chip. It's safe for us to clean up 845 * the list buffers. 846 */ 847 Static void 848 cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, 849 usbd_status status) 850 { 851 struct cue_chain *c = priv; 852 struct cue_softc *sc = c->cue_sc; 853 struct ifnet *ifp = GET_IFP(sc); 854 int s; 855 856 if (sc->cue_dying) 857 return; 858 859 s = splnet(); 860 861 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev), 862 __func__, status)); 863 864 ifp->if_timer = 0; 865 ifp->if_flags &= ~IFF_OACTIVE; 866 867 if (status != USBD_NORMAL_COMPLETION) { 868 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 869 splx(s); 870 return; 871 } 872 ifp->if_oerrors++; 873 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cue_dev), 874 usbd_errstr(status)); 875 if (status == USBD_STALLED) 876 usbd_clear_endpoint_stall_async(sc->cue_ep[CUE_ENDPT_TX]); 877 splx(s); 878 return; 879 } 880 881 ifp->if_opackets++; 882 883 m_freem(c->cue_mbuf); 884 c->cue_mbuf = NULL; 885 886 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 887 cue_start(ifp); 888 889 splx(s); 890 } 891 892 Static void 893 cue_tick(void *xsc) 894 { 895 struct cue_softc *sc = xsc; 896 897 if (sc == NULL) 898 return; 899 900 if (sc->cue_dying) 901 return; 902 903 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__)); 904 905 /* Perform statistics update in process context. */ 906 usb_add_task(sc->cue_udev, &sc->cue_tick_task, USB_TASKQ_DRIVER); 907 } 908 909 Static void 910 cue_tick_task(void *xsc) 911 { 912 struct cue_softc *sc = xsc; 913 struct ifnet *ifp; 914 915 if (sc->cue_dying) 916 return; 917 918 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__)); 919 920 ifp = GET_IFP(sc); 921 922 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL); 923 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL); 924 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL); 925 926 if (cue_csr_read_2(sc, CUE_RX_FRAMEERR)) 927 ifp->if_ierrors++; 928 } 929 930 Static int 931 cue_send(struct cue_softc *sc, struct mbuf *m, int idx) 932 { 933 int total_len; 934 struct cue_chain *c; 935 usbd_status err; 936 937 c = &sc->cue_cdata.cue_tx_chain[idx]; 938 939 /* 940 * Copy the mbuf data into a contiguous buffer, leaving two 941 * bytes at the beginning to hold the frame length. 942 */ 943 m_copydata(m, 0, m->m_pkthdr.len, c->cue_buf + 2); 944 c->cue_mbuf = m; 945 946 total_len = m->m_pkthdr.len + 2; 947 948 DPRINTFN(10,("%s: %s: total_len=%d\n", 949 USBDEVNAME(sc->cue_dev), __func__, total_len)); 950 951 /* The first two bytes are the frame length */ 952 c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len; 953 c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); 954 955 /* XXX 10000 */ 956 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX], 957 c, c->cue_buf, total_len, USBD_NO_COPY, 10000, cue_txeof); 958 959 /* Transmit */ 960 err = usbd_transfer(c->cue_xfer); 961 if (err != USBD_IN_PROGRESS) { 962 printf("%s: cue_send error=%s\n", USBDEVNAME(sc->cue_dev), 963 usbd_errstr(err)); 964 /* Stop the interface from process context. */ 965 usb_add_task(sc->cue_udev, &sc->cue_stop_task, 966 USB_TASKQ_DRIVER); 967 return (EIO); 968 } 969 970 sc->cue_cdata.cue_tx_cnt++; 971 972 return (0); 973 } 974 975 Static void 976 cue_start(struct ifnet *ifp) 977 { 978 struct cue_softc *sc = ifp->if_softc; 979 struct mbuf *m_head = NULL; 980 981 if (sc->cue_dying) 982 return; 983 984 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 985 986 if (ifp->if_flags & IFF_OACTIVE) 987 return; 988 989 IFQ_POLL(&ifp->if_snd, m_head); 990 if (m_head == NULL) 991 return; 992 993 if (cue_send(sc, m_head, 0)) { 994 ifp->if_flags |= IFF_OACTIVE; 995 return; 996 } 997 998 IFQ_DEQUEUE(&ifp->if_snd, m_head); 999 1000 /* 1001 * If there's a BPF listener, bounce a copy of this frame 1002 * to him. 1003 */ 1004 if (ifp->if_bpf) 1005 bpf_ops->bpf_mtap(ifp->if_bpf, m_head); 1006 1007 ifp->if_flags |= IFF_OACTIVE; 1008 1009 /* 1010 * Set a timeout in case the chip goes out to lunch. 1011 */ 1012 ifp->if_timer = 5; 1013 } 1014 1015 Static void 1016 cue_init(void *xsc) 1017 { 1018 struct cue_softc *sc = xsc; 1019 struct ifnet *ifp = GET_IFP(sc); 1020 int i, s, ctl; 1021 const u_char *eaddr; 1022 1023 if (sc->cue_dying) 1024 return; 1025 1026 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 1027 1028 if (ifp->if_flags & IFF_RUNNING) 1029 return; 1030 1031 s = splnet(); 1032 1033 /* 1034 * Cancel pending I/O and free all RX/TX buffers. 1035 */ 1036 #if 1 1037 cue_reset(sc); 1038 #endif 1039 1040 /* Set advanced operation modes. */ 1041 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, 1042 CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */ 1043 1044 #if defined(__OpenBSD__) 1045 eaddr = sc->arpcom.ac_enaddr; 1046 #elif defined(__NetBSD__) 1047 eaddr = CLLADDR(ifp->if_sadl); 1048 #endif 1049 /* Set MAC address */ 1050 for (i = 0; i < ETHER_ADDR_LEN; i++) 1051 cue_csr_write_1(sc, CUE_PAR0 - i, eaddr[i]); 1052 1053 /* Enable RX logic. */ 1054 ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON; 1055 if (ifp->if_flags & IFF_PROMISC) 1056 ctl |= CUE_ETHCTL_PROMISC; 1057 cue_csr_write_1(sc, CUE_ETHCTL, ctl); 1058 1059 /* Init TX ring. */ 1060 if (cue_tx_list_init(sc) == ENOBUFS) { 1061 printf("%s: tx list init failed\n", USBDEVNAME(sc->cue_dev)); 1062 splx(s); 1063 return; 1064 } 1065 1066 /* Init RX ring. */ 1067 if (cue_rx_list_init(sc) == ENOBUFS) { 1068 printf("%s: rx list init failed\n", USBDEVNAME(sc->cue_dev)); 1069 splx(s); 1070 return; 1071 } 1072 1073 /* Load the multicast filter. */ 1074 cue_setmulti(sc); 1075 1076 /* 1077 * Set the number of RX and TX buffers that we want 1078 * to reserve inside the ASIC. 1079 */ 1080 cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES); 1081 cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES); 1082 1083 /* Set advanced operation modes. */ 1084 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, 1085 CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */ 1086 1087 /* Program the LED operation. */ 1088 cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK); 1089 1090 if (sc->cue_ep[CUE_ENDPT_RX] == NULL) { 1091 if (cue_open_pipes(sc)) { 1092 splx(s); 1093 return; 1094 } 1095 } 1096 1097 ifp->if_flags |= IFF_RUNNING; 1098 ifp->if_flags &= ~IFF_OACTIVE; 1099 1100 splx(s); 1101 1102 usb_callout(sc->cue_stat_ch, hz, cue_tick, sc); 1103 } 1104 1105 Static int 1106 cue_open_pipes(struct cue_softc *sc) 1107 { 1108 struct cue_chain *c; 1109 usbd_status err; 1110 int i; 1111 1112 /* Open RX and TX pipes. */ 1113 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX], 1114 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]); 1115 if (err) { 1116 printf("%s: open rx pipe failed: %s\n", 1117 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1118 return (EIO); 1119 } 1120 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX], 1121 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]); 1122 if (err) { 1123 printf("%s: open tx pipe failed: %s\n", 1124 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1125 return (EIO); 1126 } 1127 1128 /* Start up the receive pipe. */ 1129 for (i = 0; i < CUE_RX_LIST_CNT; i++) { 1130 c = &sc->cue_cdata.cue_rx_chain[i]; 1131 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX], 1132 c, c->cue_buf, CUE_BUFSZ, 1133 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 1134 cue_rxeof); 1135 usbd_transfer(c->cue_xfer); 1136 } 1137 1138 return (0); 1139 } 1140 1141 Static int 1142 cue_ioctl(struct ifnet *ifp, u_long command, void *data) 1143 { 1144 struct cue_softc *sc = ifp->if_softc; 1145 struct ifaddr *ifa = (struct ifaddr *)data; 1146 struct ifreq *ifr = (struct ifreq *)data; 1147 int s, error = 0; 1148 1149 if (sc->cue_dying) 1150 return (EIO); 1151 1152 s = splnet(); 1153 1154 switch(command) { 1155 case SIOCINITIFADDR: 1156 ifp->if_flags |= IFF_UP; 1157 cue_init(sc); 1158 1159 switch (ifa->ifa_addr->sa_family) { 1160 #ifdef INET 1161 case AF_INET: 1162 #if defined(__NetBSD__) 1163 arp_ifinit(ifp, ifa); 1164 #else 1165 arp_ifinit(&sc->arpcom, ifa); 1166 #endif 1167 break; 1168 #endif /* INET */ 1169 } 1170 break; 1171 1172 case SIOCSIFMTU: 1173 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) 1174 error = EINVAL; 1175 else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET) 1176 error = 0; 1177 break; 1178 1179 case SIOCSIFFLAGS: 1180 if ((error = ifioctl_common(ifp, command, data)) != 0) 1181 break; 1182 if (ifp->if_flags & IFF_UP) { 1183 if (ifp->if_flags & IFF_RUNNING && 1184 ifp->if_flags & IFF_PROMISC && 1185 !(sc->cue_if_flags & IFF_PROMISC)) { 1186 CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); 1187 cue_setmulti(sc); 1188 } else if (ifp->if_flags & IFF_RUNNING && 1189 !(ifp->if_flags & IFF_PROMISC) && 1190 sc->cue_if_flags & IFF_PROMISC) { 1191 CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); 1192 cue_setmulti(sc); 1193 } else if (!(ifp->if_flags & IFF_RUNNING)) 1194 cue_init(sc); 1195 } else { 1196 if (ifp->if_flags & IFF_RUNNING) 1197 cue_stop(sc); 1198 } 1199 sc->cue_if_flags = ifp->if_flags; 1200 error = 0; 1201 break; 1202 case SIOCADDMULTI: 1203 case SIOCDELMULTI: 1204 cue_setmulti(sc); 1205 error = 0; 1206 break; 1207 default: 1208 error = ether_ioctl(ifp, command, data); 1209 break; 1210 } 1211 1212 splx(s); 1213 1214 return (error); 1215 } 1216 1217 Static void 1218 cue_watchdog(struct ifnet *ifp) 1219 { 1220 struct cue_softc *sc = ifp->if_softc; 1221 struct cue_chain *c; 1222 usbd_status stat; 1223 int s; 1224 1225 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 1226 1227 if (sc->cue_dying) 1228 return; 1229 1230 ifp->if_oerrors++; 1231 printf("%s: watchdog timeout\n", USBDEVNAME(sc->cue_dev)); 1232 1233 s = splusb(); 1234 c = &sc->cue_cdata.cue_tx_chain[0]; 1235 usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &stat); 1236 cue_txeof(c->cue_xfer, c, stat); 1237 1238 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1239 cue_start(ifp); 1240 splx(s); 1241 } 1242 1243 /* 1244 * Stop the adapter and free any mbufs allocated to the 1245 * RX and TX lists. 1246 */ 1247 Static void 1248 cue_stop(struct cue_softc *sc) 1249 { 1250 usbd_status err; 1251 struct ifnet *ifp; 1252 int i; 1253 1254 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 1255 1256 ifp = GET_IFP(sc); 1257 ifp->if_timer = 0; 1258 1259 cue_csr_write_1(sc, CUE_ETHCTL, 0); 1260 cue_reset(sc); 1261 usb_uncallout(sc->cue_stat_ch, cue_tick, sc); 1262 1263 /* Stop transfers. */ 1264 if (sc->cue_ep[CUE_ENDPT_RX] != NULL) { 1265 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]); 1266 if (err) { 1267 printf("%s: abort rx pipe failed: %s\n", 1268 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1269 } 1270 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]); 1271 if (err) { 1272 printf("%s: close rx pipe failed: %s\n", 1273 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1274 } 1275 sc->cue_ep[CUE_ENDPT_RX] = NULL; 1276 } 1277 1278 if (sc->cue_ep[CUE_ENDPT_TX] != NULL) { 1279 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]); 1280 if (err) { 1281 printf("%s: abort tx pipe failed: %s\n", 1282 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1283 } 1284 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]); 1285 if (err) { 1286 printf("%s: close tx pipe failed: %s\n", 1287 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1288 } 1289 sc->cue_ep[CUE_ENDPT_TX] = NULL; 1290 } 1291 1292 if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) { 1293 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]); 1294 if (err) { 1295 printf("%s: abort intr pipe failed: %s\n", 1296 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1297 } 1298 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]); 1299 if (err) { 1300 printf("%s: close intr pipe failed: %s\n", 1301 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1302 } 1303 sc->cue_ep[CUE_ENDPT_INTR] = NULL; 1304 } 1305 1306 /* Free RX resources. */ 1307 for (i = 0; i < CUE_RX_LIST_CNT; i++) { 1308 if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) { 1309 m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf); 1310 sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL; 1311 } 1312 if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) { 1313 usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer); 1314 sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL; 1315 } 1316 } 1317 1318 /* Free TX resources. */ 1319 for (i = 0; i < CUE_TX_LIST_CNT; i++) { 1320 if (sc->cue_cdata.cue_tx_chain[i].cue_mbuf != NULL) { 1321 m_freem(sc->cue_cdata.cue_tx_chain[i].cue_mbuf); 1322 sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL; 1323 } 1324 if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) { 1325 usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer); 1326 sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL; 1327 } 1328 } 1329 1330 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1331 } 1332