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