1 /* $NetBSD: if_cue.c,v 1.59 2010/04/05 07:21:48 joerg 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.59 2010/04/05 07:21:48 joerg 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 bpf_mtap(ifp, m); 824 825 DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->cue_dev), 826 __func__, m->m_len)); 827 IF_INPUT(ifp, m); 828 done1: 829 splx(s); 830 831 done: 832 /* Setup new transfer. */ 833 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX], 834 c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 835 USBD_NO_TIMEOUT, cue_rxeof); 836 usbd_transfer(c->cue_xfer); 837 838 DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->cue_dev), 839 __func__)); 840 } 841 842 /* 843 * A frame was downloaded to the chip. It's safe for us to clean up 844 * the list buffers. 845 */ 846 Static void 847 cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, 848 usbd_status status) 849 { 850 struct cue_chain *c = priv; 851 struct cue_softc *sc = c->cue_sc; 852 struct ifnet *ifp = GET_IFP(sc); 853 int s; 854 855 if (sc->cue_dying) 856 return; 857 858 s = splnet(); 859 860 DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->cue_dev), 861 __func__, status)); 862 863 ifp->if_timer = 0; 864 ifp->if_flags &= ~IFF_OACTIVE; 865 866 if (status != USBD_NORMAL_COMPLETION) { 867 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 868 splx(s); 869 return; 870 } 871 ifp->if_oerrors++; 872 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cue_dev), 873 usbd_errstr(status)); 874 if (status == USBD_STALLED) 875 usbd_clear_endpoint_stall_async(sc->cue_ep[CUE_ENDPT_TX]); 876 splx(s); 877 return; 878 } 879 880 ifp->if_opackets++; 881 882 m_freem(c->cue_mbuf); 883 c->cue_mbuf = NULL; 884 885 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 886 cue_start(ifp); 887 888 splx(s); 889 } 890 891 Static void 892 cue_tick(void *xsc) 893 { 894 struct cue_softc *sc = xsc; 895 896 if (sc == NULL) 897 return; 898 899 if (sc->cue_dying) 900 return; 901 902 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__)); 903 904 /* Perform statistics update in process context. */ 905 usb_add_task(sc->cue_udev, &sc->cue_tick_task, USB_TASKQ_DRIVER); 906 } 907 908 Static void 909 cue_tick_task(void *xsc) 910 { 911 struct cue_softc *sc = xsc; 912 struct ifnet *ifp; 913 914 if (sc->cue_dying) 915 return; 916 917 DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev), __func__)); 918 919 ifp = GET_IFP(sc); 920 921 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_SINGLECOLL); 922 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_MULTICOLL); 923 ifp->if_collisions += cue_csr_read_2(sc, CUE_TX_EXCESSCOLL); 924 925 if (cue_csr_read_2(sc, CUE_RX_FRAMEERR)) 926 ifp->if_ierrors++; 927 } 928 929 Static int 930 cue_send(struct cue_softc *sc, struct mbuf *m, int idx) 931 { 932 int total_len; 933 struct cue_chain *c; 934 usbd_status err; 935 936 c = &sc->cue_cdata.cue_tx_chain[idx]; 937 938 /* 939 * Copy the mbuf data into a contiguous buffer, leaving two 940 * bytes at the beginning to hold the frame length. 941 */ 942 m_copydata(m, 0, m->m_pkthdr.len, c->cue_buf + 2); 943 c->cue_mbuf = m; 944 945 total_len = m->m_pkthdr.len + 2; 946 947 DPRINTFN(10,("%s: %s: total_len=%d\n", 948 USBDEVNAME(sc->cue_dev), __func__, total_len)); 949 950 /* The first two bytes are the frame length */ 951 c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len; 952 c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); 953 954 /* XXX 10000 */ 955 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX], 956 c, c->cue_buf, total_len, USBD_NO_COPY, 10000, cue_txeof); 957 958 /* Transmit */ 959 err = usbd_transfer(c->cue_xfer); 960 if (err != USBD_IN_PROGRESS) { 961 printf("%s: cue_send error=%s\n", USBDEVNAME(sc->cue_dev), 962 usbd_errstr(err)); 963 /* Stop the interface from process context. */ 964 usb_add_task(sc->cue_udev, &sc->cue_stop_task, 965 USB_TASKQ_DRIVER); 966 return (EIO); 967 } 968 969 sc->cue_cdata.cue_tx_cnt++; 970 971 return (0); 972 } 973 974 Static void 975 cue_start(struct ifnet *ifp) 976 { 977 struct cue_softc *sc = ifp->if_softc; 978 struct mbuf *m_head = NULL; 979 980 if (sc->cue_dying) 981 return; 982 983 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 984 985 if (ifp->if_flags & IFF_OACTIVE) 986 return; 987 988 IFQ_POLL(&ifp->if_snd, m_head); 989 if (m_head == NULL) 990 return; 991 992 if (cue_send(sc, m_head, 0)) { 993 ifp->if_flags |= IFF_OACTIVE; 994 return; 995 } 996 997 IFQ_DEQUEUE(&ifp->if_snd, m_head); 998 999 /* 1000 * If there's a BPF listener, bounce a copy of this frame 1001 * to him. 1002 */ 1003 bpf_mtap(ifp, m_head); 1004 1005 ifp->if_flags |= IFF_OACTIVE; 1006 1007 /* 1008 * Set a timeout in case the chip goes out to lunch. 1009 */ 1010 ifp->if_timer = 5; 1011 } 1012 1013 Static void 1014 cue_init(void *xsc) 1015 { 1016 struct cue_softc *sc = xsc; 1017 struct ifnet *ifp = GET_IFP(sc); 1018 int i, s, ctl; 1019 const u_char *eaddr; 1020 1021 if (sc->cue_dying) 1022 return; 1023 1024 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 1025 1026 if (ifp->if_flags & IFF_RUNNING) 1027 return; 1028 1029 s = splnet(); 1030 1031 /* 1032 * Cancel pending I/O and free all RX/TX buffers. 1033 */ 1034 #if 1 1035 cue_reset(sc); 1036 #endif 1037 1038 /* Set advanced operation modes. */ 1039 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, 1040 CUE_AOP_EMBED_RXLEN | 0x03); /* 1 wait state */ 1041 1042 #if defined(__OpenBSD__) 1043 eaddr = sc->arpcom.ac_enaddr; 1044 #elif defined(__NetBSD__) 1045 eaddr = CLLADDR(ifp->if_sadl); 1046 #endif 1047 /* Set MAC address */ 1048 for (i = 0; i < ETHER_ADDR_LEN; i++) 1049 cue_csr_write_1(sc, CUE_PAR0 - i, eaddr[i]); 1050 1051 /* Enable RX logic. */ 1052 ctl = CUE_ETHCTL_RX_ON | CUE_ETHCTL_MCAST_ON; 1053 if (ifp->if_flags & IFF_PROMISC) 1054 ctl |= CUE_ETHCTL_PROMISC; 1055 cue_csr_write_1(sc, CUE_ETHCTL, ctl); 1056 1057 /* Init TX ring. */ 1058 if (cue_tx_list_init(sc) == ENOBUFS) { 1059 printf("%s: tx list init failed\n", USBDEVNAME(sc->cue_dev)); 1060 splx(s); 1061 return; 1062 } 1063 1064 /* Init RX ring. */ 1065 if (cue_rx_list_init(sc) == ENOBUFS) { 1066 printf("%s: rx list init failed\n", USBDEVNAME(sc->cue_dev)); 1067 splx(s); 1068 return; 1069 } 1070 1071 /* Load the multicast filter. */ 1072 cue_setmulti(sc); 1073 1074 /* 1075 * Set the number of RX and TX buffers that we want 1076 * to reserve inside the ASIC. 1077 */ 1078 cue_csr_write_1(sc, CUE_RX_BUFPKTS, CUE_RX_FRAMES); 1079 cue_csr_write_1(sc, CUE_TX_BUFPKTS, CUE_TX_FRAMES); 1080 1081 /* Set advanced operation modes. */ 1082 cue_csr_write_1(sc, CUE_ADVANCED_OPMODES, 1083 CUE_AOP_EMBED_RXLEN | 0x01); /* 1 wait state */ 1084 1085 /* Program the LED operation. */ 1086 cue_csr_write_1(sc, CUE_LEDCTL, CUE_LEDCTL_FOLLOW_LINK); 1087 1088 if (sc->cue_ep[CUE_ENDPT_RX] == NULL) { 1089 if (cue_open_pipes(sc)) { 1090 splx(s); 1091 return; 1092 } 1093 } 1094 1095 ifp->if_flags |= IFF_RUNNING; 1096 ifp->if_flags &= ~IFF_OACTIVE; 1097 1098 splx(s); 1099 1100 usb_callout(sc->cue_stat_ch, hz, cue_tick, sc); 1101 } 1102 1103 Static int 1104 cue_open_pipes(struct cue_softc *sc) 1105 { 1106 struct cue_chain *c; 1107 usbd_status err; 1108 int i; 1109 1110 /* Open RX and TX pipes. */ 1111 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_RX], 1112 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_RX]); 1113 if (err) { 1114 printf("%s: open rx pipe failed: %s\n", 1115 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1116 return (EIO); 1117 } 1118 err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX], 1119 USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]); 1120 if (err) { 1121 printf("%s: open tx pipe failed: %s\n", 1122 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1123 return (EIO); 1124 } 1125 1126 /* Start up the receive pipe. */ 1127 for (i = 0; i < CUE_RX_LIST_CNT; i++) { 1128 c = &sc->cue_cdata.cue_rx_chain[i]; 1129 usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX], 1130 c, c->cue_buf, CUE_BUFSZ, 1131 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, 1132 cue_rxeof); 1133 usbd_transfer(c->cue_xfer); 1134 } 1135 1136 return (0); 1137 } 1138 1139 Static int 1140 cue_ioctl(struct ifnet *ifp, u_long command, void *data) 1141 { 1142 struct cue_softc *sc = ifp->if_softc; 1143 struct ifaddr *ifa = (struct ifaddr *)data; 1144 struct ifreq *ifr = (struct ifreq *)data; 1145 int s, error = 0; 1146 1147 if (sc->cue_dying) 1148 return (EIO); 1149 1150 s = splnet(); 1151 1152 switch(command) { 1153 case SIOCINITIFADDR: 1154 ifp->if_flags |= IFF_UP; 1155 cue_init(sc); 1156 1157 switch (ifa->ifa_addr->sa_family) { 1158 #ifdef INET 1159 case AF_INET: 1160 #if defined(__NetBSD__) 1161 arp_ifinit(ifp, ifa); 1162 #else 1163 arp_ifinit(&sc->arpcom, ifa); 1164 #endif 1165 break; 1166 #endif /* INET */ 1167 } 1168 break; 1169 1170 case SIOCSIFMTU: 1171 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) 1172 error = EINVAL; 1173 else if ((error = ifioctl_common(ifp, command, data)) == ENETRESET) 1174 error = 0; 1175 break; 1176 1177 case SIOCSIFFLAGS: 1178 if ((error = ifioctl_common(ifp, command, data)) != 0) 1179 break; 1180 if (ifp->if_flags & IFF_UP) { 1181 if (ifp->if_flags & IFF_RUNNING && 1182 ifp->if_flags & IFF_PROMISC && 1183 !(sc->cue_if_flags & IFF_PROMISC)) { 1184 CUE_SETBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); 1185 cue_setmulti(sc); 1186 } else if (ifp->if_flags & IFF_RUNNING && 1187 !(ifp->if_flags & IFF_PROMISC) && 1188 sc->cue_if_flags & IFF_PROMISC) { 1189 CUE_CLRBIT(sc, CUE_ETHCTL, CUE_ETHCTL_PROMISC); 1190 cue_setmulti(sc); 1191 } else if (!(ifp->if_flags & IFF_RUNNING)) 1192 cue_init(sc); 1193 } else { 1194 if (ifp->if_flags & IFF_RUNNING) 1195 cue_stop(sc); 1196 } 1197 sc->cue_if_flags = ifp->if_flags; 1198 error = 0; 1199 break; 1200 case SIOCADDMULTI: 1201 case SIOCDELMULTI: 1202 cue_setmulti(sc); 1203 error = 0; 1204 break; 1205 default: 1206 error = ether_ioctl(ifp, command, data); 1207 break; 1208 } 1209 1210 splx(s); 1211 1212 return (error); 1213 } 1214 1215 Static void 1216 cue_watchdog(struct ifnet *ifp) 1217 { 1218 struct cue_softc *sc = ifp->if_softc; 1219 struct cue_chain *c; 1220 usbd_status stat; 1221 int s; 1222 1223 DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 1224 1225 if (sc->cue_dying) 1226 return; 1227 1228 ifp->if_oerrors++; 1229 printf("%s: watchdog timeout\n", USBDEVNAME(sc->cue_dev)); 1230 1231 s = splusb(); 1232 c = &sc->cue_cdata.cue_tx_chain[0]; 1233 usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &stat); 1234 cue_txeof(c->cue_xfer, c, stat); 1235 1236 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1237 cue_start(ifp); 1238 splx(s); 1239 } 1240 1241 /* 1242 * Stop the adapter and free any mbufs allocated to the 1243 * RX and TX lists. 1244 */ 1245 Static void 1246 cue_stop(struct cue_softc *sc) 1247 { 1248 usbd_status err; 1249 struct ifnet *ifp; 1250 int i; 1251 1252 DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->cue_dev),__func__)); 1253 1254 ifp = GET_IFP(sc); 1255 ifp->if_timer = 0; 1256 1257 cue_csr_write_1(sc, CUE_ETHCTL, 0); 1258 cue_reset(sc); 1259 usb_uncallout(sc->cue_stat_ch, cue_tick, sc); 1260 1261 /* Stop transfers. */ 1262 if (sc->cue_ep[CUE_ENDPT_RX] != NULL) { 1263 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_RX]); 1264 if (err) { 1265 printf("%s: abort rx pipe failed: %s\n", 1266 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1267 } 1268 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]); 1269 if (err) { 1270 printf("%s: close rx pipe failed: %s\n", 1271 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1272 } 1273 sc->cue_ep[CUE_ENDPT_RX] = NULL; 1274 } 1275 1276 if (sc->cue_ep[CUE_ENDPT_TX] != NULL) { 1277 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_TX]); 1278 if (err) { 1279 printf("%s: abort tx pipe failed: %s\n", 1280 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1281 } 1282 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]); 1283 if (err) { 1284 printf("%s: close tx pipe failed: %s\n", 1285 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1286 } 1287 sc->cue_ep[CUE_ENDPT_TX] = NULL; 1288 } 1289 1290 if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) { 1291 err = usbd_abort_pipe(sc->cue_ep[CUE_ENDPT_INTR]); 1292 if (err) { 1293 printf("%s: abort intr pipe failed: %s\n", 1294 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1295 } 1296 err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]); 1297 if (err) { 1298 printf("%s: close intr pipe failed: %s\n", 1299 USBDEVNAME(sc->cue_dev), usbd_errstr(err)); 1300 } 1301 sc->cue_ep[CUE_ENDPT_INTR] = NULL; 1302 } 1303 1304 /* Free RX resources. */ 1305 for (i = 0; i < CUE_RX_LIST_CNT; i++) { 1306 if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) { 1307 m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf); 1308 sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL; 1309 } 1310 if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) { 1311 usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer); 1312 sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL; 1313 } 1314 } 1315 1316 /* Free TX resources. */ 1317 for (i = 0; i < CUE_TX_LIST_CNT; i++) { 1318 if (sc->cue_cdata.cue_tx_chain[i].cue_mbuf != NULL) { 1319 m_freem(sc->cue_cdata.cue_tx_chain[i].cue_mbuf); 1320 sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL; 1321 } 1322 if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) { 1323 usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer); 1324 sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL; 1325 } 1326 } 1327 1328 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1329 } 1330