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