1 /* $OpenBSD: if_url.c,v 1.11 2003/05/07 04:33:33 deraadt Exp $ */ 2 /* $NetBSD: if_url.c,v 1.6 2002/09/29 10:19:21 martin Exp $ */ 3 /* 4 * Copyright (c) 2001, 2002 5 * Shingo WATANABE <nabe@nabechan.org>. 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 Shingo WATANABE. 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 THE AUTHOR 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 THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 */ 35 36 /* 37 * The RTL8150L(Realtek USB to fast ethernet controller) spec can be found at 38 * ftp://ftp.realtek.com.tw/lancard/data_sheet/8150/8150v14.pdf 39 * ftp://152.104.125.40/lancard/data_sheet/8150/8150v14.pdf 40 */ 41 42 /* 43 * TODO: 44 * Interrupt Endpoint support 45 * External PHYs 46 * powerhook() support? 47 */ 48 49 #if defined(__NetBSD__) 50 #include "opt_inet.h" 51 #include "opt_ns.h" 52 #include "rnd.h" 53 #endif 54 55 #include "bpfilter.h" 56 57 #include <sys/param.h> 58 #include <sys/systm.h> 59 #include <sys/lock.h> 60 #include <sys/mbuf.h> 61 #include <sys/kernel.h> 62 #if defined(__OpenBSD__) 63 #include <sys/proc.h> 64 #endif 65 #include <sys/socket.h> 66 67 #include <sys/device.h> 68 #if NRND > 0 69 #include <sys/rnd.h> 70 #endif 71 72 #include <net/if.h> 73 #include <net/if_arp.h> 74 #include <net/if_dl.h> 75 #include <net/if_media.h> 76 77 #if NBPFILTER > 0 78 #include <net/bpf.h> 79 #endif 80 #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m)) 81 82 #if defined(__NetBSD__) 83 #include <net/if_ether.h> 84 #ifdef INET 85 #include <netinet/in.h> 86 #include <netinet/if_inarp.h> 87 #endif 88 #endif /* defined(__NetBSD__) */ 89 90 #if defined(__OpenBSD__) 91 #ifdef INET 92 #include <netinet/in.h> 93 #include <netinet/in_systm.h> 94 #include <netinet/in_var.h> 95 #include <netinet/ip.h> 96 #include <netinet/if_ether.h> 97 #endif 98 #endif /* defined(__OpenBSD__) */ 99 100 #ifdef NS 101 #include <netns/ns.h> 102 #include <netns/ns_if.h> 103 #endif 104 105 #include <dev/mii/mii.h> 106 #include <dev/mii/miivar.h> 107 #include <dev/mii/urlphyreg.h> 108 109 #include <dev/usb/usb.h> 110 #include <dev/usb/usbdi.h> 111 #include <dev/usb/usbdi_util.h> 112 #include <dev/usb/usbdevs.h> 113 114 #include <dev/usb/if_urlreg.h> 115 116 117 /* Function declarations */ 118 USB_DECLARE_DRIVER(url); 119 120 Static int url_openpipes(struct url_softc *); 121 Static int url_rx_list_init(struct url_softc *); 122 Static int url_tx_list_init(struct url_softc *); 123 Static int url_newbuf(struct url_softc *, struct url_chain *, struct mbuf *); 124 Static void url_start(struct ifnet *); 125 Static int url_send(struct url_softc *, struct mbuf *, int); 126 Static void url_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 127 Static void url_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 128 Static void url_tick(void *); 129 Static void url_tick_task(void *); 130 Static int url_ioctl(struct ifnet *, u_long, caddr_t); 131 Static void url_stop_task(struct url_softc *); 132 Static void url_stop(struct ifnet *, int); 133 Static void url_watchdog(struct ifnet *); 134 Static int url_ifmedia_change(struct ifnet *); 135 Static void url_ifmedia_status(struct ifnet *, struct ifmediareq *); 136 Static void url_lock_mii(struct url_softc *); 137 Static void url_unlock_mii(struct url_softc *); 138 Static int url_int_miibus_readreg(device_ptr_t, int, int); 139 Static void url_int_miibus_writereg(device_ptr_t, int, int, int); 140 Static void url_miibus_statchg(device_ptr_t); 141 Static int url_init(struct ifnet *); 142 Static void url_setmulti(struct url_softc *); 143 Static void url_reset(struct url_softc *); 144 145 Static int url_csr_read_1(struct url_softc *, int); 146 Static int url_csr_read_2(struct url_softc *, int); 147 Static int url_csr_write_1(struct url_softc *, int, int); 148 Static int url_csr_write_2(struct url_softc *, int, int); 149 Static int url_csr_write_4(struct url_softc *, int, int); 150 Static int url_mem(struct url_softc *, int, int, void *, int); 151 152 /* Macros */ 153 #ifdef URL_DEBUG 154 #define DPRINTF(x) if (urldebug) logprintf x 155 #define DPRINTFN(n,x) if (urldebug >= (n)) logprintf x 156 int urldebug = 0; 157 #else 158 #define DPRINTF(x) 159 #define DPRINTFN(n,x) 160 #endif 161 162 #define URL_SETBIT(sc, reg, x) \ 163 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) | (x)) 164 165 #define URL_SETBIT2(sc, reg, x) \ 166 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) | (x)) 167 168 #define URL_CLRBIT(sc, reg, x) \ 169 url_csr_write_1(sc, reg, url_csr_read_1(sc, reg) & ~(x)) 170 171 #define URL_CLRBIT2(sc, reg, x) \ 172 url_csr_write_2(sc, reg, url_csr_read_2(sc, reg) & ~(x)) 173 174 static const struct url_type { 175 struct usb_devno url_dev; 176 u_int16_t url_flags; 177 #define URL_EXT_PHY 0x0001 178 } url_devs [] = { 179 /* MELCO LUA-KTX */ 180 {{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAKTX }, 0}, 181 /* GREEN HOUSE USBKR100 */ 182 {{ USB_VENDOR_GREENHOUSE2, USB_PRODUCT_GREENHOUSE2_USBKR100}, 0} 183 }; 184 #define url_lookup(v, p) ((struct url_type *)usb_lookup(url_devs, v, p)) 185 186 187 /* Probe */ 188 USB_MATCH(url) 189 { 190 USB_MATCH_START(url, uaa); 191 192 if (uaa->iface != NULL) 193 return (UMATCH_NONE); 194 195 return (url_lookup(uaa->vendor, uaa->product) != NULL ? 196 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 197 } 198 /* Attach */ 199 USB_ATTACH(url) 200 { 201 USB_ATTACH_START(url, sc, uaa); 202 usbd_device_handle dev = uaa->device; 203 usbd_interface_handle iface; 204 usbd_status err; 205 usb_interface_descriptor_t *id; 206 usb_endpoint_descriptor_t *ed; 207 char devinfo[1024]; 208 char *devname = USBDEVNAME(sc->sc_dev); 209 struct ifnet *ifp; 210 struct mii_data *mii; 211 u_char eaddr[ETHER_ADDR_LEN]; 212 int i, s; 213 214 usbd_devinfo(dev, 0, devinfo, sizeof devinfo); 215 USB_ATTACH_SETUP; 216 printf("%s: %s\n", devname, devinfo); 217 218 /* Move the device into the configured state. */ 219 err = usbd_set_config_no(dev, URL_CONFIG_NO, 1); 220 if (err) { 221 printf("%s: setting config no failed\n", devname); 222 goto bad; 223 } 224 225 usb_init_task(&sc->sc_tick_task, url_tick_task, sc); 226 lockinit(&sc->sc_mii_lock, PZERO, "urlmii", 0, 0); 227 usb_init_task(&sc->sc_stop_task, (void (*)(void *)) url_stop_task, sc); 228 229 /* get control interface */ 230 err = usbd_device2interface_handle(dev, URL_IFACE_INDEX, &iface); 231 if (err) { 232 printf("%s: failed to get interface, err=%s\n", devname, 233 usbd_errstr(err)); 234 goto bad; 235 } 236 237 sc->sc_udev = dev; 238 sc->sc_ctl_iface = iface; 239 sc->sc_flags = url_lookup(uaa->vendor, uaa->product)->url_flags; 240 241 /* get interface descriptor */ 242 id = usbd_get_interface_descriptor(sc->sc_ctl_iface); 243 244 /* find endpoints */ 245 sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1; 246 for (i = 0; i < id->bNumEndpoints; i++) { 247 ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i); 248 if (ed == NULL) { 249 printf("%s: couldn't get endpoint %d\n", devname, i); 250 goto bad; 251 } 252 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 253 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 254 sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */ 255 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 256 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) 257 sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */ 258 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT && 259 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 260 sc->sc_intrin_no = ed->bEndpointAddress; /* Status */ 261 } 262 263 if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 || 264 sc->sc_intrin_no == -1) { 265 printf("%s: missing endpoint\n", devname); 266 goto bad; 267 } 268 269 s = splnet(); 270 271 /* reset the adapter */ 272 url_reset(sc); 273 274 /* Get Ethernet Address */ 275 err = url_mem(sc, URL_CMD_READMEM, URL_IDR0, (void *)eaddr, 276 ETHER_ADDR_LEN); 277 if (err) { 278 printf("%s: read MAC address failed\n", devname); 279 splx(s); 280 goto bad; 281 } 282 283 /* Print Ethernet Address */ 284 printf("%s: address %s\n", devname, ether_sprintf(eaddr)); 285 286 /* initialize interface infomation */ 287 ifp = GET_IFP(sc); 288 ifp->if_softc = sc; 289 ifp->if_mtu = ETHERMTU; 290 strncpy(ifp->if_xname, devname, IFNAMSIZ); 291 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 292 ifp->if_start = url_start; 293 ifp->if_ioctl = url_ioctl; 294 ifp->if_watchdog = url_watchdog; 295 #if defined(__NetBSD__) 296 ifp->if_init = url_init; 297 ifp->if_stop = url_stop; 298 #endif 299 300 IFQ_SET_READY(&ifp->if_snd); 301 302 /* 303 * Do ifmedia setup. 304 */ 305 mii = &sc->sc_mii; 306 mii->mii_ifp = ifp; 307 mii->mii_readreg = url_int_miibus_readreg; 308 mii->mii_writereg = url_int_miibus_writereg; 309 #if 0 310 if (sc->sc_flags & URL_EXT_PHY) { 311 mii->mii_readreg = url_ext_miibus_readreg; 312 mii->mii_writereg = url_ext_miibus_writereg; 313 } 314 #endif 315 mii->mii_statchg = url_miibus_statchg; 316 mii->mii_flags = MIIF_AUTOTSLEEP; 317 ifmedia_init(&mii->mii_media, 0, 318 url_ifmedia_change, url_ifmedia_status); 319 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); 320 if (LIST_FIRST(&mii->mii_phys) == NULL) { 321 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); 322 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); 323 } else 324 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 325 326 /* attach the interface */ 327 if_attach(ifp); 328 Ether_ifattach(ifp, eaddr); 329 330 #if NRND > 0 331 rnd_attach_source(&sc->rnd_source, devname, RND_TYPE_NET, 0); 332 #endif 333 334 usb_callout_init(sc->sc_stat_ch); 335 sc->sc_attached = 1; 336 splx(s); 337 338 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, dev, USBDEV(sc->sc_dev)); 339 340 USB_ATTACH_SUCCESS_RETURN; 341 342 bad: 343 sc->sc_dying = 1; 344 USB_ATTACH_ERROR_RETURN; 345 } 346 347 /* detach */ 348 USB_DETACH(url) 349 { 350 USB_DETACH_START(url, sc); 351 struct ifnet *ifp = GET_IFP(sc); 352 int s; 353 354 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 355 356 /* Detached before attached finished */ 357 if (!sc->sc_attached) 358 return (0); 359 360 usb_uncallout(sc->sc_stat_ch, url_tick, sc); 361 362 /* Remove any pending tasks */ 363 usb_rem_task(sc->sc_udev, &sc->sc_tick_task); 364 usb_rem_task(sc->sc_udev, &sc->sc_stop_task); 365 366 s = splusb(); 367 368 if (--sc->sc_refcnt >= 0) { 369 /* Wait for processes to go away */ 370 usb_detach_wait(USBDEV(sc->sc_dev)); 371 } 372 373 if (ifp->if_flags & IFF_RUNNING) 374 url_stop(GET_IFP(sc), 1); 375 376 #if NRND > 0 377 rnd_detach_source(&sc->rnd_source); 378 #endif 379 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); 380 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); 381 ether_ifdetach(ifp); 382 if_detach(ifp); 383 384 #ifdef DIAGNOSTIC 385 if (sc->sc_pipe_tx != NULL) 386 printf("%s: detach has active tx endpoint.\n", 387 USBDEVNAME(sc->sc_dev)); 388 if (sc->sc_pipe_rx != NULL) 389 printf("%s: detach has active rx endpoint.\n", 390 USBDEVNAME(sc->sc_dev)); 391 if (sc->sc_pipe_intr != NULL) 392 printf("%s: detach has active intr endpoint.\n", 393 USBDEVNAME(sc->sc_dev)); 394 #endif 395 396 sc->sc_attached = 0; 397 398 splx(s); 399 400 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 401 USBDEV(sc->sc_dev)); 402 403 return (0); 404 } 405 406 /* read/write memory */ 407 Static int 408 url_mem(struct url_softc *sc, int cmd, int offset, void *buf, int len) 409 { 410 usb_device_request_t req; 411 usbd_status err; 412 413 if (sc == NULL) 414 return (0); 415 416 DPRINTFN(0x200, 417 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 418 419 if (sc->sc_dying) 420 return (0); 421 422 if (cmd == URL_CMD_READMEM) 423 req.bmRequestType = UT_READ_VENDOR_DEVICE; 424 else 425 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 426 req.bRequest = URL_REQ_MEM; 427 USETW(req.wValue, offset); 428 USETW(req.wIndex, 0x0000); 429 USETW(req.wLength, len); 430 431 sc->sc_refcnt++; 432 err = usbd_do_request(sc->sc_udev, &req, buf); 433 if (--sc->sc_refcnt < 0) 434 usb_detach_wakeup(USBDEV(sc->sc_dev)); 435 if (err) { 436 DPRINTF(("%s: url_mem(): %s failed. off=%04x, err=%d\n", 437 USBDEVNAME(sc->sc_dev), 438 cmd == URL_CMD_READMEM ? "read" : "write", 439 offset, err)); 440 } 441 442 return (err); 443 } 444 445 /* read 1byte from register */ 446 Static int 447 url_csr_read_1(struct url_softc *sc, int reg) 448 { 449 u_int8_t val = 0; 450 451 DPRINTFN(0x100, 452 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 453 454 if (sc->sc_dying) 455 return (0); 456 457 return (url_mem(sc, URL_CMD_READMEM, reg, &val, 1) ? 0 : val); 458 } 459 460 /* read 2bytes from register */ 461 Static int 462 url_csr_read_2(struct url_softc *sc, int reg) 463 { 464 uWord val; 465 466 DPRINTFN(0x100, 467 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 468 469 if (sc->sc_dying) 470 return (0); 471 472 USETW(val, 0); 473 return (url_mem(sc, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val)); 474 } 475 476 /* write 1byte to register */ 477 Static int 478 url_csr_write_1(struct url_softc *sc, int reg, int aval) 479 { 480 u_int8_t val = aval; 481 482 DPRINTFN(0x100, 483 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 484 485 if (sc->sc_dying) 486 return (0); 487 488 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0); 489 } 490 491 /* write 2bytes to register */ 492 Static int 493 url_csr_write_2(struct url_softc *sc, int reg, int aval) 494 { 495 uWord val; 496 497 DPRINTFN(0x100, 498 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 499 500 USETW(val, aval); 501 502 if (sc->sc_dying) 503 return (0); 504 505 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0); 506 } 507 508 /* write 4bytes to register */ 509 Static int 510 url_csr_write_4(struct url_softc *sc, int reg, int aval) 511 { 512 uDWord val; 513 514 DPRINTFN(0x100, 515 ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 516 517 USETDW(val, aval); 518 519 if (sc->sc_dying) 520 return (0); 521 522 return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0); 523 } 524 525 Static int 526 url_init(struct ifnet *ifp) 527 { 528 struct url_softc *sc = ifp->if_softc; 529 struct mii_data *mii = GET_MII(sc); 530 u_char *eaddr; 531 int i, s; 532 533 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 534 535 if (sc->sc_dying) 536 return (EIO); 537 538 s = splnet(); 539 540 /* Cancel pending I/O and free all TX/RX buffers */ 541 url_stop(ifp, 1); 542 543 #if defined(__OpenBSD__) 544 eaddr = sc->sc_ac.ac_enaddr; 545 #elif defined(__NetBSD__) 546 eaddr = LLADDR(ifp->if_sadl); 547 #endif 548 for (i = 0; i < ETHER_ADDR_LEN; i++) 549 url_csr_write_1(sc, URL_IDR0 + i, eaddr[i]); 550 551 /* Init transmission control register */ 552 URL_CLRBIT(sc, URL_TCR, 553 URL_TCR_TXRR1 | URL_TCR_TXRR0 | 554 URL_TCR_IFG1 | URL_TCR_IFG0 | 555 URL_TCR_NOCRC); 556 557 /* Init receive control register */ 558 URL_SETBIT2(sc, URL_RCR, URL_RCR_TAIL | URL_RCR_AD); 559 if (ifp->if_flags & IFF_BROADCAST) 560 URL_SETBIT2(sc, URL_RCR, URL_RCR_AB); 561 else 562 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AB); 563 564 /* If we want promiscuous mode, accept all physical frames. */ 565 if (ifp->if_flags & IFF_PROMISC) 566 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); 567 else 568 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); 569 570 571 /* Initialize transmit ring */ 572 if (url_tx_list_init(sc) == ENOBUFS) { 573 printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev)); 574 splx(s); 575 return (EIO); 576 } 577 578 /* Initialize receive ring */ 579 if (url_rx_list_init(sc) == ENOBUFS) { 580 printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev)); 581 splx(s); 582 return (EIO); 583 } 584 585 /* Load the multicast filter */ 586 url_setmulti(sc); 587 588 /* Enable RX and TX */ 589 URL_SETBIT(sc, URL_CR, URL_CR_TE | URL_CR_RE); 590 591 mii_mediachg(mii); 592 593 if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) { 594 if (url_openpipes(sc)) { 595 splx(s); 596 return (EIO); 597 } 598 } 599 600 ifp->if_flags |= IFF_RUNNING; 601 ifp->if_flags &= ~IFF_OACTIVE; 602 603 splx(s); 604 605 usb_callout(sc->sc_stat_ch, hz, url_tick, sc); 606 607 return (0); 608 } 609 610 Static void 611 url_reset(struct url_softc *sc) 612 { 613 int i; 614 615 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 616 617 if (sc->sc_dying) 618 return; 619 620 URL_SETBIT(sc, URL_CR, URL_CR_SOFT_RST); 621 622 for (i = 0; i < URL_TX_TIMEOUT; i++) { 623 if (!(url_csr_read_1(sc, URL_CR) & URL_CR_SOFT_RST)) 624 break; 625 delay(10); /* XXX */ 626 } 627 628 delay(10000); /* XXX */ 629 } 630 631 int 632 url_activate(device_ptr_t self, enum devact act) 633 { 634 struct url_softc *sc = (struct url_softc *)self; 635 636 DPRINTF(("%s: %s: enter, act=%d\n", USBDEVNAME(sc->sc_dev), 637 __func__, act)); 638 639 switch (act) { 640 case DVACT_ACTIVATE: 641 return (EOPNOTSUPP); 642 break; 643 644 case DVACT_DEACTIVATE: 645 if_deactivate(GET_IFP(sc)); 646 sc->sc_dying = 1; 647 break; 648 } 649 650 return (0); 651 } 652 653 #define url_calchash(addr) (ether_crc32_be((addr), ETHER_ADDR_LEN) >> 26) 654 655 656 Static void 657 url_setmulti(struct url_softc *sc) 658 { 659 struct ifnet *ifp; 660 struct ether_multi *enm; 661 struct ether_multistep step; 662 u_int32_t hashes[2] = { 0, 0 }; 663 int h = 0; 664 int mcnt = 0; 665 666 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 667 668 if (sc->sc_dying) 669 return; 670 671 ifp = GET_IFP(sc); 672 673 if (ifp->if_flags & IFF_PROMISC) { 674 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); 675 return; 676 } else if (ifp->if_flags & IFF_ALLMULTI) { 677 allmulti: 678 ifp->if_flags |= IFF_ALLMULTI; 679 URL_SETBIT2(sc, URL_RCR, URL_RCR_AAM); 680 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAP); 681 return; 682 } 683 684 /* first, zot all the existing hash bits */ 685 url_csr_write_4(sc, URL_MAR0, 0); 686 url_csr_write_4(sc, URL_MAR4, 0); 687 688 /* now program new ones */ 689 ETHER_FIRST_MULTI(step, &sc->sc_ac, enm); 690 while (enm != NULL) { 691 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 692 ETHER_ADDR_LEN) != 0) 693 goto allmulti; 694 695 h = url_calchash(enm->enm_addrlo); 696 if (h < 32) 697 hashes[0] |= (1 << h); 698 else 699 hashes[1] |= (1 << (h -32)); 700 mcnt++; 701 ETHER_NEXT_MULTI(step, enm); 702 } 703 704 ifp->if_flags &= ~IFF_ALLMULTI; 705 706 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); 707 708 if (mcnt){ 709 URL_SETBIT2(sc, URL_RCR, URL_RCR_AM); 710 } else { 711 URL_CLRBIT2(sc, URL_RCR, URL_RCR_AM); 712 } 713 url_csr_write_4(sc, URL_MAR0, hashes[0]); 714 url_csr_write_4(sc, URL_MAR4, hashes[1]); 715 } 716 717 Static int 718 url_openpipes(struct url_softc *sc) 719 { 720 struct url_chain *c; 721 usbd_status err; 722 int i; 723 int error = 0; 724 725 if (sc->sc_dying) 726 return (EIO); 727 728 sc->sc_refcnt++; 729 730 /* Open RX pipe */ 731 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no, 732 USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx); 733 if (err) { 734 printf("%s: open rx pipe failed: %s\n", 735 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 736 error = EIO; 737 goto done; 738 } 739 740 /* Open TX pipe */ 741 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no, 742 USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx); 743 if (err) { 744 printf("%s: open tx pipe failed: %s\n", 745 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 746 error = EIO; 747 goto done; 748 } 749 750 #if 0 751 /* XXX: interrupt endpoint is not yet supported */ 752 /* Open Interrupt pipe */ 753 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no, 754 USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc, 755 &sc->sc_cdata.url_ibuf, URL_INTR_PKGLEN, 756 url_intr, URL_INTR_INTERVAL); 757 if (err) { 758 printf("%s: open intr pipe failed: %s\n", 759 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 760 error = EIO; 761 goto done; 762 } 763 #endif 764 765 766 /* Start up the receive pipe. */ 767 for (i = 0; i < URL_RX_LIST_CNT; i++) { 768 c = &sc->sc_cdata.url_rx_chain[i]; 769 usbd_setup_xfer(c->url_xfer, sc->sc_pipe_rx, 770 c, c->url_buf, URL_BUFSZ, 771 USBD_SHORT_XFER_OK | USBD_NO_COPY, 772 USBD_NO_TIMEOUT, url_rxeof); 773 (void)usbd_transfer(c->url_xfer); 774 DPRINTF(("%s: %s: start read\n", USBDEVNAME(sc->sc_dev), 775 __func__)); 776 } 777 778 done: 779 if (--sc->sc_refcnt < 0) 780 usb_detach_wakeup(USBDEV(sc->sc_dev)); 781 782 return (error); 783 } 784 785 Static int 786 url_newbuf(struct url_softc *sc, struct url_chain *c, struct mbuf *m) 787 { 788 struct mbuf *m_new = NULL; 789 790 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 791 792 if (m == NULL) { 793 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 794 if (m_new == NULL) { 795 printf("%s: no memory for rx list " 796 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev)); 797 return (ENOBUFS); 798 } 799 MCLGET(m_new, M_DONTWAIT); 800 if (!(m_new->m_flags & M_EXT)) { 801 printf("%s: no memory for rx list " 802 "-- packet dropped!\n", USBDEVNAME(sc->sc_dev)); 803 m_freem(m_new); 804 return (ENOBUFS); 805 } 806 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 807 } else { 808 m_new = m; 809 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 810 m_new->m_data = m_new->m_ext.ext_buf; 811 } 812 813 m_adj(m_new, ETHER_ALIGN); 814 c->url_mbuf = m_new; 815 816 return (0); 817 } 818 819 820 Static int 821 url_rx_list_init(struct url_softc *sc) 822 { 823 struct url_cdata *cd; 824 struct url_chain *c; 825 int i; 826 827 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 828 829 cd = &sc->sc_cdata; 830 for (i = 0; i < URL_RX_LIST_CNT; i++) { 831 c = &cd->url_rx_chain[i]; 832 c->url_sc = sc; 833 c->url_idx = i; 834 if (url_newbuf(sc, c, NULL) == ENOBUFS) 835 return (ENOBUFS); 836 if (c->url_xfer == NULL) { 837 c->url_xfer = usbd_alloc_xfer(sc->sc_udev); 838 if (c->url_xfer == NULL) 839 return (ENOBUFS); 840 c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ); 841 if (c->url_buf == NULL) { 842 usbd_free_xfer(c->url_xfer); 843 return (ENOBUFS); 844 } 845 } 846 } 847 848 return (0); 849 } 850 851 Static int 852 url_tx_list_init(struct url_softc *sc) 853 { 854 struct url_cdata *cd; 855 struct url_chain *c; 856 int i; 857 858 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 859 860 cd = &sc->sc_cdata; 861 for (i = 0; i < URL_TX_LIST_CNT; i++) { 862 c = &cd->url_tx_chain[i]; 863 c->url_sc = sc; 864 c->url_idx = i; 865 c->url_mbuf = NULL; 866 if (c->url_xfer == NULL) { 867 c->url_xfer = usbd_alloc_xfer(sc->sc_udev); 868 if (c->url_xfer == NULL) 869 return (ENOBUFS); 870 c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ); 871 if (c->url_buf == NULL) { 872 usbd_free_xfer(c->url_xfer); 873 return (ENOBUFS); 874 } 875 } 876 } 877 878 return (0); 879 } 880 881 Static void 882 url_start(struct ifnet *ifp) 883 { 884 struct url_softc *sc = ifp->if_softc; 885 struct mbuf *m_head = NULL; 886 887 DPRINTF(("%s: %s: enter, link=%d\n", USBDEVNAME(sc->sc_dev), 888 __func__, sc->sc_link)); 889 890 if (sc->sc_dying) 891 return; 892 893 if (!sc->sc_link) 894 return; 895 896 if (ifp->if_flags & IFF_OACTIVE) 897 return; 898 899 IFQ_POLL(&ifp->if_snd, m_head); 900 if (m_head == NULL) 901 return; 902 903 if (url_send(sc, m_head, 0)) { 904 ifp->if_flags |= IFF_OACTIVE; 905 return; 906 } 907 908 IFQ_DEQUEUE(&ifp->if_snd, m_head); 909 910 #if NBPFILTER > 0 911 if (ifp->if_bpf) 912 bpf_mtap(ifp->if_bpf, m_head); 913 #endif 914 915 ifp->if_flags |= IFF_OACTIVE; 916 917 /* Set a timeout in case the chip goes out to lunch. */ 918 ifp->if_timer = 5; 919 } 920 921 Static int 922 url_send(struct url_softc *sc, struct mbuf *m, int idx) 923 { 924 int total_len; 925 struct url_chain *c; 926 usbd_status err; 927 928 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); 929 930 c = &sc->sc_cdata.url_tx_chain[idx]; 931 932 /* Copy the mbuf data into a contiguous buffer */ 933 m_copydata(m, 0, m->m_pkthdr.len, c->url_buf); 934 c->url_mbuf = m; 935 total_len = m->m_pkthdr.len; 936 937 if (total_len < URL_MIN_FRAME_LEN) { 938 bzero(c->url_buf + total_len, URL_MIN_FRAME_LEN - total_len); 939 total_len = URL_MIN_FRAME_LEN; 940 } 941 usbd_setup_xfer(c->url_xfer, sc->sc_pipe_tx, c, c->url_buf, total_len, 942 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 943 URL_TX_TIMEOUT, url_txeof); 944 945 /* Transmit */ 946 sc->sc_refcnt++; 947 err = usbd_transfer(c->url_xfer); 948 if (--sc->sc_refcnt < 0) 949 usb_detach_wakeup(USBDEV(sc->sc_dev)); 950 if (err != USBD_IN_PROGRESS) { 951 printf("%s: url_send error=%s\n", USBDEVNAME(sc->sc_dev), 952 usbd_errstr(err)); 953 /* Stop the interface */ 954 usb_add_task(sc->sc_udev, &sc->sc_stop_task); 955 return (EIO); 956 } 957 958 DPRINTF(("%s: %s: send %d bytes\n", USBDEVNAME(sc->sc_dev), 959 __func__, total_len)); 960 961 sc->sc_cdata.url_tx_cnt++; 962 963 return (0); 964 } 965 966 Static void 967 url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 968 { 969 struct url_chain *c = priv; 970 struct url_softc *sc = c->url_sc; 971 struct ifnet *ifp = GET_IFP(sc); 972 int s; 973 974 if (sc->sc_dying) 975 return; 976 977 s = splnet(); 978 979 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 980 981 ifp->if_timer = 0; 982 ifp->if_flags &= ~IFF_OACTIVE; 983 984 if (status != USBD_NORMAL_COMPLETION) { 985 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 986 splx(s); 987 return; 988 } 989 ifp->if_oerrors++; 990 printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev), 991 usbd_errstr(status)); 992 if (status == USBD_STALLED) { 993 sc->sc_refcnt++; 994 usbd_clear_endpoint_stall(sc->sc_pipe_tx); 995 if (--sc->sc_refcnt < 0) 996 usb_detach_wakeup(USBDEV(sc->sc_dev)); 997 } 998 splx(s); 999 return; 1000 } 1001 1002 ifp->if_opackets++; 1003 1004 m_freem(c->url_mbuf); 1005 c->url_mbuf = NULL; 1006 1007 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1008 url_start(ifp); 1009 1010 splx(s); 1011 } 1012 1013 Static void 1014 url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1015 { 1016 struct url_chain *c = priv; 1017 struct url_softc *sc = c->url_sc; 1018 struct ifnet *ifp = GET_IFP(sc); 1019 struct mbuf *m; 1020 u_int32_t total_len; 1021 url_rxhdr_t rxhdr; 1022 int s; 1023 1024 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__)); 1025 1026 if (sc->sc_dying) 1027 return; 1028 1029 if (status != USBD_NORMAL_COMPLETION) { 1030 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1031 return; 1032 sc->sc_rx_errs++; 1033 if (usbd_ratecheck(&sc->sc_rx_notice)) { 1034 printf("%s: %u usb errors on rx: %s\n", 1035 USBDEVNAME(sc->sc_dev), sc->sc_rx_errs, 1036 usbd_errstr(status)); 1037 sc->sc_rx_errs = 0; 1038 } 1039 if (status == USBD_STALLED) { 1040 sc->sc_refcnt++; 1041 usbd_clear_endpoint_stall(sc->sc_pipe_rx); 1042 if (--sc->sc_refcnt < 0) 1043 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1044 } 1045 goto done; 1046 } 1047 1048 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 1049 1050 memcpy(mtod(c->url_mbuf, char *), c->url_buf, total_len); 1051 1052 if (total_len <= ETHER_CRC_LEN) { 1053 ifp->if_ierrors++; 1054 goto done; 1055 } 1056 1057 memcpy(&rxhdr, c->url_buf + total_len - ETHER_CRC_LEN, sizeof(rxhdr)); 1058 1059 DPRINTF(("%s: RX Status: %dbytes%s%s%s%s packets\n", 1060 USBDEVNAME(sc->sc_dev), 1061 UGETW(rxhdr) & URL_RXHDR_BYTEC_MASK, 1062 UGETW(rxhdr) & URL_RXHDR_VALID_MASK ? ", Valid" : "", 1063 UGETW(rxhdr) & URL_RXHDR_RUNTPKT_MASK ? ", Runt" : "", 1064 UGETW(rxhdr) & URL_RXHDR_PHYPKT_MASK ? ", Physical match" : "", 1065 UGETW(rxhdr) & URL_RXHDR_MCASTPKT_MASK ? ", Multicast" : "")); 1066 1067 if ((UGETW(rxhdr) & URL_RXHDR_VALID_MASK) == 0) { 1068 ifp->if_ierrors++; 1069 goto done; 1070 } 1071 1072 ifp->if_ipackets++; 1073 total_len -= ETHER_CRC_LEN; 1074 1075 m = c->url_mbuf; 1076 m->m_pkthdr.len = m->m_len = total_len; 1077 m->m_pkthdr.rcvif = ifp; 1078 1079 s = splnet(); 1080 1081 if (url_newbuf(sc, c, NULL) == ENOBUFS) { 1082 ifp->if_ierrors++; 1083 goto done1; 1084 } 1085 1086 #if NBPFILTER > 0 1087 if (ifp->if_bpf) 1088 BPF_MTAP(ifp, m); 1089 #endif 1090 1091 DPRINTF(("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev), 1092 __func__, m->m_len)); 1093 IF_INPUT(ifp, m); 1094 1095 done1: 1096 splx(s); 1097 1098 done: 1099 /* Setup new transfer */ 1100 usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->url_buf, URL_BUFSZ, 1101 USBD_SHORT_XFER_OK | USBD_NO_COPY, 1102 USBD_NO_TIMEOUT, url_rxeof); 1103 sc->sc_refcnt++; 1104 usbd_transfer(xfer); 1105 if (--sc->sc_refcnt < 0) 1106 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1107 1108 DPRINTF(("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev), __func__)); 1109 } 1110 1111 #if 0 1112 Static void url_intr() 1113 { 1114 } 1115 #endif 1116 1117 Static int 1118 url_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1119 { 1120 struct url_softc *sc = ifp->if_softc; 1121 struct ifaddr *ifa = (struct ifaddr *)data; 1122 struct ifreq *ifr = (struct ifreq *)data; 1123 struct mii_data *mii; 1124 int s, error = 0; 1125 1126 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 1127 1128 if (sc->sc_dying) 1129 return (EIO); 1130 1131 s = splnet(); 1132 1133 switch (cmd) { 1134 case SIOCSIFADDR: 1135 ifp->if_flags |= IFF_UP; 1136 url_init(ifp); 1137 1138 switch (ifa->ifa_addr->sa_family) { 1139 #ifdef INET 1140 case AF_INET: 1141 arp_ifinit(&sc->sc_ac, ifa); 1142 break; 1143 #endif /* INET */ 1144 #ifdef NS 1145 case AF_NS: 1146 { 1147 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 1148 1149 if (ns_nullhost(*ina)) 1150 ina->x_host = *(union ns_host *) 1151 LLADDR(ifp->if_sadl); 1152 else 1153 memcpy(LLADDR(ifp->if_sadl), 1154 ina->x_host.c_host, 1155 ifp->if_addrlen); 1156 break; 1157 } 1158 #endif /* NS */ 1159 } 1160 break; 1161 1162 case SIOCSIFMTU: 1163 if (ifr->ifr_mtu > ETHERMTU) 1164 error = EINVAL; 1165 else 1166 ifp->if_mtu = ifr->ifr_mtu; 1167 break; 1168 1169 case SIOCSIFFLAGS: 1170 if (ifp->if_flags & IFF_UP) { 1171 if (ifp->if_flags & IFF_RUNNING && 1172 ifp->if_flags & IFF_PROMISC) { 1173 URL_SETBIT2(sc, URL_RCR, 1174 URL_RCR_AAM|URL_RCR_AAP); 1175 } else if (ifp->if_flags & IFF_RUNNING && 1176 !(ifp->if_flags & IFF_PROMISC)) { 1177 URL_CLRBIT2(sc, URL_RCR, 1178 URL_RCR_AAM|URL_RCR_AAP); 1179 } else if (!(ifp->if_flags & IFF_RUNNING)) 1180 url_init(ifp); 1181 } else { 1182 if (ifp->if_flags & IFF_RUNNING) 1183 url_stop(ifp, 1); 1184 } 1185 error = 0; 1186 break; 1187 case SIOCADDMULTI: 1188 case SIOCDELMULTI: 1189 error = (cmd == SIOCADDMULTI) ? 1190 ether_addmulti(ifr, &sc->sc_ac) : 1191 ether_delmulti(ifr, &sc->sc_ac); 1192 if (error == ENETRESET) { 1193 url_init(ifp); 1194 } 1195 url_setmulti(sc); 1196 error = 0; 1197 break; 1198 case SIOCGIFMEDIA: 1199 case SIOCSIFMEDIA: 1200 mii = GET_MII(sc); 1201 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); 1202 break; 1203 default: 1204 error = EINVAL; 1205 break; 1206 } 1207 1208 splx(s); 1209 1210 return (error); 1211 } 1212 1213 Static void 1214 url_watchdog(struct ifnet *ifp) 1215 { 1216 struct url_softc *sc = ifp->if_softc; 1217 struct url_chain *c; 1218 usbd_status stat; 1219 int s; 1220 1221 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 1222 1223 ifp->if_oerrors++; 1224 printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev)); 1225 1226 s = splusb(); 1227 c = &sc->sc_cdata.url_tx_chain[0]; 1228 usbd_get_xfer_status(c->url_xfer, NULL, NULL, NULL, &stat); 1229 url_txeof(c->url_xfer, c, stat); 1230 1231 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1232 url_start(ifp); 1233 splx(s); 1234 } 1235 1236 Static void 1237 url_stop_task(struct url_softc *sc) 1238 { 1239 url_stop(GET_IFP(sc), 1); 1240 } 1241 1242 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ 1243 Static void 1244 url_stop(struct ifnet *ifp, int disable) 1245 { 1246 struct url_softc *sc = ifp->if_softc; 1247 usbd_status err; 1248 int i; 1249 1250 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 1251 1252 ifp->if_timer = 0; 1253 1254 url_reset(sc); 1255 1256 usb_uncallout(sc->sc_stat_ch, url_tick, sc); 1257 1258 /* Stop transfers */ 1259 /* RX endpoint */ 1260 if (sc->sc_pipe_rx != NULL) { 1261 err = usbd_abort_pipe(sc->sc_pipe_rx); 1262 if (err) 1263 printf("%s: abort rx pipe failed: %s\n", 1264 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1265 err = usbd_close_pipe(sc->sc_pipe_rx); 1266 if (err) 1267 printf("%s: close rx pipe failed: %s\n", 1268 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1269 sc->sc_pipe_rx = NULL; 1270 } 1271 1272 /* TX endpoint */ 1273 if (sc->sc_pipe_tx != NULL) { 1274 err = usbd_abort_pipe(sc->sc_pipe_tx); 1275 if (err) 1276 printf("%s: abort tx pipe failed: %s\n", 1277 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1278 err = usbd_close_pipe(sc->sc_pipe_tx); 1279 if (err) 1280 printf("%s: close tx pipe failed: %s\n", 1281 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1282 sc->sc_pipe_tx = NULL; 1283 } 1284 1285 #if 0 1286 /* XXX: Interrupt endpoint is not yet supported!! */ 1287 /* Interrupt endpoint */ 1288 if (sc->sc_pipe_intr != NULL) { 1289 err = usbd_abort_pipe(sc->sc_pipe_intr); 1290 if (err) 1291 printf("%s: abort intr pipe failed: %s\n", 1292 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1293 err = usbd_close_pipe(sc->sc_pipe_intr); 1294 if (err) 1295 printf("%s: close intr pipe failed: %s\n", 1296 USBDEVNAME(sc->sc_dev), usbd_errstr(err)); 1297 sc->sc_pipe_intr = NULL; 1298 } 1299 #endif 1300 1301 /* Free RX resources. */ 1302 for (i = 0; i < URL_RX_LIST_CNT; i++) { 1303 if (sc->sc_cdata.url_rx_chain[i].url_mbuf != NULL) { 1304 m_freem(sc->sc_cdata.url_rx_chain[i].url_mbuf); 1305 sc->sc_cdata.url_rx_chain[i].url_mbuf = NULL; 1306 } 1307 if (sc->sc_cdata.url_rx_chain[i].url_xfer != NULL) { 1308 usbd_free_xfer(sc->sc_cdata.url_rx_chain[i].url_xfer); 1309 sc->sc_cdata.url_rx_chain[i].url_xfer = NULL; 1310 } 1311 } 1312 1313 /* Free TX resources. */ 1314 for (i = 0; i < URL_TX_LIST_CNT; i++) { 1315 if (sc->sc_cdata.url_tx_chain[i].url_mbuf != NULL) { 1316 m_freem(sc->sc_cdata.url_tx_chain[i].url_mbuf); 1317 sc->sc_cdata.url_tx_chain[i].url_mbuf = NULL; 1318 } 1319 if (sc->sc_cdata.url_tx_chain[i].url_xfer != NULL) { 1320 usbd_free_xfer(sc->sc_cdata.url_tx_chain[i].url_xfer); 1321 sc->sc_cdata.url_tx_chain[i].url_xfer = NULL; 1322 } 1323 } 1324 1325 sc->sc_link = 0; 1326 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1327 } 1328 1329 /* Set media options */ 1330 Static int 1331 url_ifmedia_change(struct ifnet *ifp) 1332 { 1333 struct url_softc *sc = ifp->if_softc; 1334 struct mii_data *mii = GET_MII(sc); 1335 1336 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 1337 1338 if (sc->sc_dying) 1339 return (0); 1340 1341 sc->sc_link = 0; 1342 if (mii->mii_instance) { 1343 struct mii_softc *miisc; 1344 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL; 1345 miisc = LIST_NEXT(miisc, mii_list)) 1346 mii_phy_reset(miisc); 1347 } 1348 1349 return (mii_mediachg(mii)); 1350 } 1351 1352 /* Report current media status. */ 1353 Static void 1354 url_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr) 1355 { 1356 struct url_softc *sc = ifp->if_softc; 1357 struct mii_data *mii = GET_MII(sc); 1358 1359 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 1360 1361 if (sc->sc_dying) 1362 return; 1363 1364 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1365 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 1366 ifmr->ifm_status = 0; 1367 return; 1368 } 1369 1370 mii_pollstat(mii); 1371 ifmr->ifm_active = mii->mii_media_active; 1372 ifmr->ifm_status = mii->mii_media_status; 1373 } 1374 1375 Static void 1376 url_tick(void *xsc) 1377 { 1378 struct url_softc *sc = xsc; 1379 1380 if (sc == NULL) 1381 return; 1382 1383 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), 1384 __func__)); 1385 1386 if (sc->sc_dying) 1387 return; 1388 1389 /* Perform periodic stuff in process context */ 1390 usb_add_task(sc->sc_udev, &sc->sc_tick_task); 1391 } 1392 1393 Static void 1394 url_tick_task(void *xsc) 1395 { 1396 struct url_softc *sc = xsc; 1397 struct ifnet *ifp; 1398 struct mii_data *mii; 1399 int s; 1400 1401 if (sc == NULL) 1402 return; 1403 1404 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), 1405 __func__)); 1406 1407 if (sc->sc_dying) 1408 return; 1409 1410 ifp = GET_IFP(sc); 1411 mii = GET_MII(sc); 1412 1413 if (mii == NULL) 1414 return; 1415 1416 s = splnet(); 1417 1418 mii_tick(mii); 1419 if (!sc->sc_link) { 1420 mii_pollstat(mii); 1421 if (mii->mii_media_status & IFM_ACTIVE && 1422 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 1423 DPRINTF(("%s: %s: got link\n", 1424 USBDEVNAME(sc->sc_dev), __func__)); 1425 sc->sc_link++; 1426 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1427 url_start(ifp); 1428 } 1429 } 1430 1431 usb_callout(sc->sc_stat_ch, hz, url_tick, sc); 1432 1433 splx(s); 1434 } 1435 1436 /* Get exclusive access to the MII registers */ 1437 Static void 1438 url_lock_mii(struct url_softc *sc) 1439 { 1440 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), 1441 __func__)); 1442 1443 sc->sc_refcnt++; 1444 usb_lockmgr(&sc->sc_mii_lock, LK_EXCLUSIVE, NULL, curproc); 1445 } 1446 1447 Static void 1448 url_unlock_mii(struct url_softc *sc) 1449 { 1450 DPRINTFN(0xff, ("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), 1451 __func__)); 1452 1453 usb_lockmgr(&sc->sc_mii_lock, LK_RELEASE, NULL, curproc); 1454 if (--sc->sc_refcnt < 0) 1455 usb_detach_wakeup(USBDEV(sc->sc_dev)); 1456 } 1457 1458 Static int 1459 url_int_miibus_readreg(device_ptr_t dev, int phy, int reg) 1460 { 1461 struct url_softc *sc; 1462 u_int16_t val; 1463 1464 if (dev == NULL) 1465 return (0); 1466 1467 sc = USBGETSOFTC(dev); 1468 1469 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", 1470 USBDEVNAME(sc->sc_dev), __func__, phy, reg)); 1471 1472 if (sc->sc_dying) { 1473 #ifdef DIAGNOSTIC 1474 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev), 1475 __func__); 1476 #endif 1477 return (0); 1478 } 1479 1480 /* XXX: one PHY only for the RTL8150 internal PHY */ 1481 if (phy != 0) { 1482 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 1483 USBDEVNAME(sc->sc_dev), __func__, phy)); 1484 return (0); 1485 } 1486 1487 url_lock_mii(sc); 1488 1489 switch (reg) { 1490 case MII_BMCR: /* Control Register */ 1491 reg = URL_BMCR; 1492 break; 1493 case MII_BMSR: /* Status Register */ 1494 reg = URL_BMSR; 1495 break; 1496 case MII_PHYIDR1: 1497 case MII_PHYIDR2: 1498 val = 0; 1499 goto R_DONE; 1500 break; 1501 case MII_ANAR: /* Autonegotiation advertisement */ 1502 reg = URL_ANAR; 1503 break; 1504 case MII_ANLPAR: /* Autonegotiation link partner abilities */ 1505 reg = URL_ANLP; 1506 break; 1507 case URLPHY_MSR: /* Media Status Register */ 1508 reg = URL_MSR; 1509 break; 1510 default: 1511 printf("%s: %s: bad register %04x\n", 1512 USBDEVNAME(sc->sc_dev), __func__, reg); 1513 val = 0; 1514 goto R_DONE; 1515 break; 1516 } 1517 1518 if (reg == URL_MSR) 1519 val = url_csr_read_1(sc, reg); 1520 else 1521 val = url_csr_read_2(sc, reg); 1522 1523 R_DONE: 1524 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n", 1525 USBDEVNAME(sc->sc_dev), __func__, phy, reg, val)); 1526 1527 url_unlock_mii(sc); 1528 return (val); 1529 } 1530 1531 Static void 1532 url_int_miibus_writereg(device_ptr_t dev, int phy, int reg, int data) 1533 { 1534 struct url_softc *sc; 1535 1536 if (dev == NULL) 1537 return; 1538 1539 sc = USBGETSOFTC(dev); 1540 1541 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", 1542 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data)); 1543 1544 if (sc->sc_dying) { 1545 #ifdef DIAGNOSTIC 1546 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev), 1547 __func__); 1548 #endif 1549 return; 1550 } 1551 1552 /* XXX: one PHY only for the RTL8150 internal PHY */ 1553 if (phy != 0) { 1554 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 1555 USBDEVNAME(sc->sc_dev), __func__, phy)); 1556 return; 1557 } 1558 1559 url_lock_mii(sc); 1560 1561 switch (reg) { 1562 case MII_BMCR: /* Control Register */ 1563 reg = URL_BMCR; 1564 break; 1565 case MII_BMSR: /* Status Register */ 1566 reg = URL_BMSR; 1567 break; 1568 case MII_PHYIDR1: 1569 case MII_PHYIDR2: 1570 goto W_DONE; 1571 break; 1572 case MII_ANAR: /* Autonegotiation advertisement */ 1573 reg = URL_ANAR; 1574 break; 1575 case MII_ANLPAR: /* Autonegotiation link partner abilities */ 1576 reg = URL_ANLP; 1577 break; 1578 case URLPHY_MSR: /* Media Status Register */ 1579 reg = URL_MSR; 1580 break; 1581 default: 1582 printf("%s: %s: bad register %04x\n", 1583 USBDEVNAME(sc->sc_dev), __func__, reg); 1584 goto W_DONE; 1585 break; 1586 } 1587 1588 if (reg == URL_MSR) 1589 url_csr_write_1(sc, reg, data); 1590 else 1591 url_csr_write_2(sc, reg, data); 1592 W_DONE: 1593 1594 url_unlock_mii(sc); 1595 return; 1596 } 1597 1598 Static void 1599 url_miibus_statchg(device_ptr_t dev) 1600 { 1601 #ifdef URL_DEBUG 1602 struct url_softc *sc; 1603 1604 if (dev == NULL) 1605 return; 1606 1607 sc = USBGETSOFTC(dev); 1608 DPRINTF(("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__)); 1609 #endif 1610 /* Nothing to do */ 1611 } 1612 1613 #if 0 1614 /* 1615 * external PHYs support, but not test. 1616 */ 1617 Static int 1618 url_ext_miibus_redreg(device_ptr_t dev, int phy, int reg) 1619 { 1620 struct url_softc *sc = USBGETSOFTC(dev); 1621 u_int16_t val; 1622 1623 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n", 1624 USBDEVNAME(sc->sc_dev), __func__, phy, reg)); 1625 1626 if (sc->sc_dying) { 1627 #ifdef DIAGNOSTIC 1628 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev), 1629 __func__); 1630 #endif 1631 return (0); 1632 } 1633 1634 url_lock_mii(sc); 1635 1636 url_csr_write_1(sc, URL_PHYADD, phy & URL_PHYADD_MASK); 1637 /* 1638 * RTL8150L will initiate a MII management data transaction 1639 * if PHYCNT_OWN bit is set 1 by software. After transaction, 1640 * this bit is auto cleared by TRL8150L. 1641 */ 1642 url_csr_write_1(sc, URL_PHYCNT, 1643 (reg | URL_PHYCNT_PHYOWN) & ~URL_PHYCNT_RWCR); 1644 for (i = 0; i < URL_TIMEOUT; i++) { 1645 if ((url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN) == 0) 1646 break; 1647 } 1648 if (i == URL_TIMEOUT) { 1649 printf("%s: MII read timed out\n", USBDEVNAME(sc->sc_dev)); 1650 } 1651 1652 val = url_csr_read_2(sc, URL_PHYDAT); 1653 1654 DPRINTF(("%s: %s: phy=%d reg=0x%04x => 0x%04x\n", 1655 USBDEVNAME(sc->sc_dev), __func__, phy, reg, val)); 1656 1657 url_unlock_mii(sc); 1658 return (val); 1659 } 1660 1661 Static void 1662 url_ext_miibus_writereg(device_ptr_t dev, int phy, int reg, int data) 1663 { 1664 struct url_softc *sc = USBGETSOFTC(dev); 1665 1666 DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", 1667 USBDEVNAME(sc->sc_dev), __func__, phy, reg, data)); 1668 1669 if (sc->sc_dying) { 1670 #ifdef DIAGNOSTIC 1671 printf("%s: %s: dying\n", USBDEVNAME(sc->sc_dev), 1672 __func__); 1673 #endif 1674 return; 1675 } 1676 1677 url_lock_mii(sc); 1678 1679 url_csr_write_2(sc, URL_PHYDAT, data); 1680 url_csr_write_1(sc, URL_PHYADD, phy); 1681 url_csr_write_1(sc, URL_PHYCNT, reg | URL_PHYCNT_RWCR); /* Write */ 1682 1683 for (i=0; i < URL_TIMEOUT; i++) { 1684 if (url_csr_read_1(sc, URL_PHYCNT) & URL_PHYCNT_PHYOWN) 1685 break; 1686 } 1687 1688 if (i == URL_TIMEOUT) { 1689 printf("%s: MII write timed out\n", 1690 USBDEVNAME(sc->sc_dev)); 1691 } 1692 1693 url_unlock_mii(sc); 1694 return; 1695 } 1696 #endif 1697 1698