1 /* $OpenBSD: if_udav.c,v 1.58 2011/09/04 18:34:02 jsg Exp $ */ 2 /* $NetBSD: if_udav.c,v 1.3 2004/04/23 17:25:25 itojun Exp $ */ 3 /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ 4 /* 5 * Copyright (c) 2003 6 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 */ 33 34 /* 35 * DM9601(DAVICOM USB to Ethernet MAC Controller with Integrated 10/100 PHY) 36 * The spec can be found at the following url. 37 * http://www.meworks.net/userfile/24247/DM9601-DS-P03-102908.pdf 38 */ 39 40 /* 41 * TODO: 42 * Interrupt Endpoint support 43 * External PHYs 44 */ 45 46 #include <sys/cdefs.h> 47 48 #include "bpfilter.h" 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/rwlock.h> 53 #include <sys/mbuf.h> 54 #include <sys/kernel.h> 55 #include <sys/proc.h> 56 #include <sys/socket.h> 57 58 #include <sys/device.h> 59 60 #include <net/if.h> 61 #include <net/if_arp.h> 62 #include <net/if_dl.h> 63 #include <net/if_media.h> 64 65 #if NBPFILTER > 0 66 #include <net/bpf.h> 67 #endif 68 69 #ifdef INET 70 #include <netinet/in.h> 71 #include <netinet/in_systm.h> 72 #include <netinet/in_var.h> 73 #include <netinet/ip.h> 74 #include <netinet/if_ether.h> 75 #endif 76 77 #include <dev/mii/mii.h> 78 #include <dev/mii/miivar.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_udavreg.h> 86 87 88 /* Function declarations */ 89 int udav_match(struct device *, void *, void *); 90 void udav_attach(struct device *, struct device *, void *); 91 int udav_detach(struct device *, int); 92 int udav_activate(struct device *, int); 93 94 struct cfdriver udav_cd = { 95 NULL, "udav", DV_IFNET 96 }; 97 98 const struct cfattach udav_ca = { 99 sizeof(struct udav_softc), 100 udav_match, 101 udav_attach, 102 udav_detach, 103 udav_activate, 104 }; 105 106 int udav_openpipes(struct udav_softc *); 107 int udav_rx_list_init(struct udav_softc *); 108 int udav_tx_list_init(struct udav_softc *); 109 int udav_newbuf(struct udav_softc *, struct udav_chain *, struct mbuf *); 110 void udav_start(struct ifnet *); 111 int udav_send(struct udav_softc *, struct mbuf *, int); 112 void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 113 void udav_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); 114 void udav_tick(void *); 115 void udav_tick_task(void *); 116 int udav_ioctl(struct ifnet *, u_long, caddr_t); 117 void udav_stop_task(struct udav_softc *); 118 void udav_stop(struct ifnet *, int); 119 void udav_watchdog(struct ifnet *); 120 int udav_ifmedia_change(struct ifnet *); 121 void udav_ifmedia_status(struct ifnet *, struct ifmediareq *); 122 void udav_lock_mii(struct udav_softc *); 123 void udav_unlock_mii(struct udav_softc *); 124 int udav_miibus_readreg(struct device *, int, int); 125 void udav_miibus_writereg(struct device *, int, int, int); 126 void udav_miibus_statchg(struct device *); 127 int udav_init(struct ifnet *); 128 void udav_setmulti(struct udav_softc *); 129 void udav_reset(struct udav_softc *); 130 131 int udav_csr_read(struct udav_softc *, int, void *, int); 132 int udav_csr_write(struct udav_softc *, int, void *, int); 133 int udav_csr_read1(struct udav_softc *, int); 134 int udav_csr_write1(struct udav_softc *, int, unsigned char); 135 136 #if 0 137 int udav_mem_read(struct udav_softc *, int, void *, int); 138 int udav_mem_write(struct udav_softc *, int, void *, int); 139 int udav_mem_write1(struct udav_softc *, int, unsigned char); 140 #endif 141 142 /* Macros */ 143 #ifdef UDAV_DEBUG 144 #define DPRINTF(x) do { if (udavdebug) printf x; } while(0) 145 #define DPRINTFN(n,x) do { if (udavdebug >= (n)) printf x; } while(0) 146 int udavdebug = 0; 147 #else 148 #define DPRINTF(x) 149 #define DPRINTFN(n,x) 150 #endif 151 152 #define UDAV_SETBIT(sc, reg, x) \ 153 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) | (x)) 154 155 #define UDAV_CLRBIT(sc, reg, x) \ 156 udav_csr_write1(sc, reg, udav_csr_read1(sc, reg) & ~(x)) 157 158 static const struct udav_type { 159 struct usb_devno udav_dev; 160 u_int16_t udav_flags; 161 #define UDAV_EXT_PHY 0x0001 162 } udav_devs [] = { 163 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0 }, 164 {{ USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_DM9601 }, 0 }, 165 {{ USB_VENDOR_DAVICOM, USB_PRODUCT_DAVICOM_WK668 }, 0 }, 166 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_DM9601 }, 0 }, 167 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268 }, 0 }, 168 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ZT6688 }, 0 }, 169 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515 }, 0 }, 170 {{ USB_VENDOR_UNKNOWN4, USB_PRODUCT_UNKNOWN4_DM9601 }, 0 }, 171 {{ USB_VENDOR_UNKNOWN6, USB_PRODUCT_UNKNOWN6_DM9601 }, 0 } 172 }; 173 #define udav_lookup(v, p) ((struct udav_type *)usb_lookup(udav_devs, v, p)) 174 175 176 /* Probe */ 177 int 178 udav_match(struct device *parent, void *match, void *aux) 179 { 180 struct usb_attach_arg *uaa = aux; 181 182 if (uaa->iface != NULL) 183 return (UMATCH_NONE); 184 185 return (udav_lookup(uaa->vendor, uaa->product) != NULL ? 186 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 187 } 188 189 /* Attach */ 190 void 191 udav_attach(struct device *parent, struct device *self, void *aux) 192 { 193 struct udav_softc *sc = (struct udav_softc *)self; 194 struct usb_attach_arg *uaa = aux; 195 usbd_device_handle dev = uaa->device; 196 usbd_interface_handle iface; 197 usbd_status err; 198 usb_interface_descriptor_t *id; 199 usb_endpoint_descriptor_t *ed; 200 char *devname = sc->sc_dev.dv_xname; 201 struct ifnet *ifp; 202 struct mii_data *mii; 203 u_char eaddr[ETHER_ADDR_LEN]; 204 int i, s; 205 206 printf("%s: ", devname); 207 208 sc->sc_udev = dev; 209 210 /* Move the device into the configured state. */ 211 err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); 212 if (err) { 213 printf("setting config no failed\n"); 214 goto bad; 215 } 216 217 usb_init_task(&sc->sc_tick_task, udav_tick_task, sc, 218 USB_TASK_TYPE_GENERIC); 219 rw_init(&sc->sc_mii_lock, "udavmii"); 220 usb_init_task(&sc->sc_stop_task, (void (*)(void *)) udav_stop_task, sc, 221 USB_TASK_TYPE_GENERIC); 222 223 /* get control interface */ 224 err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface); 225 if (err) { 226 printf("failed to get interface, err=%s\n", usbd_errstr(err)); 227 goto bad; 228 } 229 230 sc->sc_ctl_iface = iface; 231 sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags; 232 233 /* get interface descriptor */ 234 id = usbd_get_interface_descriptor(sc->sc_ctl_iface); 235 236 /* find endpoints */ 237 sc->sc_bulkin_no = sc->sc_bulkout_no = sc->sc_intrin_no = -1; 238 for (i = 0; i < id->bNumEndpoints; i++) { 239 ed = usbd_interface2endpoint_descriptor(sc->sc_ctl_iface, i); 240 if (ed == NULL) { 241 printf("couldn't get endpoint %d\n", i); 242 goto bad; 243 } 244 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 245 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 246 sc->sc_bulkin_no = ed->bEndpointAddress; /* RX */ 247 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 248 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) 249 sc->sc_bulkout_no = ed->bEndpointAddress; /* TX */ 250 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT && 251 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 252 sc->sc_intrin_no = ed->bEndpointAddress; /* Status */ 253 } 254 255 if (sc->sc_bulkin_no == -1 || sc->sc_bulkout_no == -1 || 256 sc->sc_intrin_no == -1) { 257 printf("missing endpoint\n"); 258 goto bad; 259 } 260 261 s = splnet(); 262 263 /* reset the adapter */ 264 udav_reset(sc); 265 266 /* Get Ethernet Address */ 267 err = udav_csr_read(sc, UDAV_PAR, (void *)eaddr, ETHER_ADDR_LEN); 268 if (err) { 269 printf("read MAC address failed\n"); 270 splx(s); 271 goto bad; 272 } 273 274 /* Print Ethernet Address */ 275 printf("address %s\n", ether_sprintf(eaddr)); 276 277 bcopy(eaddr, (char *)&sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN); 278 279 /* initialize interface information */ 280 ifp = GET_IFP(sc); 281 ifp->if_softc = sc; 282 strlcpy(ifp->if_xname, devname, IFNAMSIZ); 283 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 284 ifp->if_start = udav_start; 285 ifp->if_ioctl = udav_ioctl; 286 ifp->if_watchdog = udav_watchdog; 287 288 IFQ_SET_READY(&ifp->if_snd); 289 290 /* 291 * Do ifmedia setup. 292 */ 293 mii = &sc->sc_mii; 294 mii->mii_ifp = ifp; 295 mii->mii_readreg = udav_miibus_readreg; 296 mii->mii_writereg = udav_miibus_writereg; 297 mii->mii_statchg = udav_miibus_statchg; 298 mii->mii_flags = MIIF_AUTOTSLEEP; 299 ifmedia_init(&mii->mii_media, 0, 300 udav_ifmedia_change, udav_ifmedia_status); 301 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); 302 if (LIST_FIRST(&mii->mii_phys) == NULL) { 303 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); 304 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); 305 } else 306 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 307 308 /* attach the interface */ 309 if_attach(ifp); 310 ether_ifattach(ifp); 311 312 timeout_set(&sc->sc_stat_ch, udav_tick, sc); 313 314 splx(s); 315 316 return; 317 318 bad: 319 usbd_deactivate(sc->sc_udev); 320 } 321 322 /* detach */ 323 int 324 udav_detach(struct device *self, int flags) 325 { 326 struct udav_softc *sc = (struct udav_softc *)self; 327 struct ifnet *ifp = GET_IFP(sc); 328 int s; 329 330 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 331 332 333 if (timeout_initialized(&sc->sc_stat_ch)) 334 timeout_del(&sc->sc_stat_ch); 335 336 /* Remove any pending tasks */ 337 usb_rem_task(sc->sc_udev, &sc->sc_tick_task); 338 usb_rem_task(sc->sc_udev, &sc->sc_stop_task); 339 340 s = splusb(); 341 342 if (--sc->sc_refcnt >= 0) { 343 /* Wait for processes to go away */ 344 usb_detach_wait(&sc->sc_dev); 345 } 346 if (ifp->if_flags & IFF_RUNNING) 347 udav_stop(GET_IFP(sc), 1); 348 349 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); 350 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); 351 if (ifp->if_softc != NULL) { 352 ether_ifdetach(ifp); 353 if_detach(ifp); 354 } 355 356 #ifdef DIAGNOSTIC 357 if (sc->sc_pipe_tx != NULL) 358 printf("%s: detach has active tx endpoint.\n", 359 sc->sc_dev.dv_xname); 360 if (sc->sc_pipe_rx != NULL) 361 printf("%s: detach has active rx endpoint.\n", 362 sc->sc_dev.dv_xname); 363 if (sc->sc_pipe_intr != NULL) 364 printf("%s: detach has active intr endpoint.\n", 365 sc->sc_dev.dv_xname); 366 #endif 367 splx(s); 368 369 return (0); 370 } 371 372 #if 0 373 /* read memory */ 374 int 375 udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len) 376 { 377 usb_device_request_t req; 378 usbd_status err; 379 380 if (sc == NULL) 381 return (0); 382 383 DPRINTFN(0x200, 384 ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 385 386 if (usbd_is_dying(sc->sc_udev)) 387 return (0); 388 389 offset &= 0xffff; 390 len &= 0xff; 391 392 req.bmRequestType = UT_READ_VENDOR_DEVICE; 393 req.bRequest = UDAV_REQ_MEM_READ; 394 USETW(req.wValue, 0x0000); 395 USETW(req.wIndex, offset); 396 USETW(req.wLength, len); 397 398 sc->sc_refcnt++; 399 err = usbd_do_request(sc->sc_udev, &req, buf); 400 if (--sc->sc_refcnt < 0) 401 usb_detach_wakeup(&sc->sc_dev); 402 if (err) { 403 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", 404 sc->sc_dev.dv_xname, __func__, offset, err)); 405 } 406 407 return (err); 408 } 409 410 /* write memory */ 411 int 412 udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len) 413 { 414 usb_device_request_t req; 415 usbd_status err; 416 417 if (sc == NULL) 418 return (0); 419 420 DPRINTFN(0x200, 421 ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 422 423 if (usbd_is_dying(sc->sc_udev)) 424 return (0); 425 426 offset &= 0xffff; 427 len &= 0xff; 428 429 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 430 req.bRequest = UDAV_REQ_MEM_WRITE; 431 USETW(req.wValue, 0x0000); 432 USETW(req.wIndex, offset); 433 USETW(req.wLength, len); 434 435 sc->sc_refcnt++; 436 err = usbd_do_request(sc->sc_udev, &req, buf); 437 if (--sc->sc_refcnt < 0) 438 usb_detach_wakeup(&sc->sc_dev); 439 if (err) { 440 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 441 sc->sc_dev.dv_xname, __func__, offset, err)); 442 } 443 444 return (err); 445 } 446 447 /* write memory */ 448 int 449 udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch) 450 { 451 usb_device_request_t req; 452 usbd_status err; 453 454 if (sc == NULL) 455 return (0); 456 457 DPRINTFN(0x200, 458 ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 459 460 if (usbd_is_dying(sc->sc_udev)) 461 return (0); 462 463 offset &= 0xffff; 464 465 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 466 req.bRequest = UDAV_REQ_MEM_WRITE1; 467 USETW(req.wValue, ch); 468 USETW(req.wIndex, offset); 469 USETW(req.wLength, 0x0000); 470 471 sc->sc_refcnt++; 472 err = usbd_do_request(sc->sc_udev, &req, NULL); 473 if (--sc->sc_refcnt < 0) 474 usb_detach_wakeup(&sc->sc_dev); 475 if (err) { 476 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 477 sc->sc_dev.dv_xname, __func__, offset, err)); 478 } 479 480 return (err); 481 } 482 #endif 483 484 /* read register(s) */ 485 int 486 udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len) 487 { 488 usb_device_request_t req; 489 usbd_status err; 490 491 if (sc == NULL) 492 return (0); 493 494 DPRINTFN(0x200, 495 ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 496 497 if (usbd_is_dying(sc->sc_udev)) 498 return (0); 499 500 offset &= 0xff; 501 len &= 0xff; 502 503 req.bmRequestType = UT_READ_VENDOR_DEVICE; 504 req.bRequest = UDAV_REQ_REG_READ; 505 USETW(req.wValue, 0x0000); 506 USETW(req.wIndex, offset); 507 USETW(req.wLength, len); 508 509 sc->sc_refcnt++; 510 err = usbd_do_request(sc->sc_udev, &req, buf); 511 if (--sc->sc_refcnt < 0) 512 usb_detach_wakeup(&sc->sc_dev); 513 if (err) { 514 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", 515 sc->sc_dev.dv_xname, __func__, offset, err)); 516 } 517 518 return (err); 519 } 520 521 /* write register(s) */ 522 int 523 udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len) 524 { 525 usb_device_request_t req; 526 usbd_status err; 527 528 if (sc == NULL) 529 return (0); 530 531 DPRINTFN(0x200, 532 ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 533 534 if (usbd_is_dying(sc->sc_udev)) 535 return (0); 536 537 offset &= 0xff; 538 len &= 0xff; 539 540 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 541 req.bRequest = UDAV_REQ_REG_WRITE; 542 USETW(req.wValue, 0x0000); 543 USETW(req.wIndex, offset); 544 USETW(req.wLength, len); 545 546 sc->sc_refcnt++; 547 err = usbd_do_request(sc->sc_udev, &req, buf); 548 if (--sc->sc_refcnt < 0) 549 usb_detach_wakeup(&sc->sc_dev); 550 if (err) { 551 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 552 sc->sc_dev.dv_xname, __func__, offset, err)); 553 } 554 555 return (err); 556 } 557 558 int 559 udav_csr_read1(struct udav_softc *sc, int offset) 560 { 561 u_int8_t val = 0; 562 563 if (sc == NULL) 564 return (0); 565 566 DPRINTFN(0x200, 567 ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 568 569 return (udav_csr_read(sc, offset, &val, 1) ? 0 : val); 570 } 571 572 /* write a register */ 573 int 574 udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch) 575 { 576 usb_device_request_t req; 577 usbd_status err; 578 579 if (sc == NULL) 580 return (0); 581 582 DPRINTFN(0x200, 583 ("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 584 585 if (usbd_is_dying(sc->sc_udev)) 586 return (0); 587 588 offset &= 0xff; 589 590 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 591 req.bRequest = UDAV_REQ_REG_WRITE1; 592 USETW(req.wValue, ch); 593 USETW(req.wIndex, offset); 594 USETW(req.wLength, 0x0000); 595 596 sc->sc_refcnt++; 597 err = usbd_do_request(sc->sc_udev, &req, NULL); 598 if (--sc->sc_refcnt < 0) 599 usb_detach_wakeup(&sc->sc_dev); 600 if (err) { 601 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 602 sc->sc_dev.dv_xname, __func__, offset, err)); 603 } 604 605 return (err); 606 } 607 608 int 609 udav_init(struct ifnet *ifp) 610 { 611 struct udav_softc *sc = ifp->if_softc; 612 struct mii_data *mii = GET_MII(sc); 613 u_char *eaddr; 614 int s; 615 616 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 617 618 s = splnet(); 619 620 /* Cancel pending I/O and free all TX/RX buffers */ 621 udav_stop(ifp, 1); 622 623 eaddr = sc->sc_ac.ac_enaddr; 624 udav_csr_write(sc, UDAV_PAR, eaddr, ETHER_ADDR_LEN); 625 626 /* Initialize network control register */ 627 /* Disable loopback */ 628 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1); 629 630 /* Initialize RX control register */ 631 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC); 632 633 /* If we want promiscuous mode, accept all physical frames. */ 634 if (ifp->if_flags & IFF_PROMISC) 635 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC); 636 else 637 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC); 638 639 /* Initialize transmit ring */ 640 if (udav_tx_list_init(sc) == ENOBUFS) { 641 printf("%s: tx list init failed\n", sc->sc_dev.dv_xname); 642 splx(s); 643 return (EIO); 644 } 645 646 /* Initialize receive ring */ 647 if (udav_rx_list_init(sc) == ENOBUFS) { 648 printf("%s: rx list init failed\n", sc->sc_dev.dv_xname); 649 splx(s); 650 return (EIO); 651 } 652 653 /* Load the multicast filter */ 654 udav_setmulti(sc); 655 656 /* Enable RX */ 657 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_RXEN); 658 659 /* clear POWER_DOWN state of internal PHY */ 660 UDAV_SETBIT(sc, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0); 661 UDAV_CLRBIT(sc, UDAV_GPR, UDAV_GPR_GEPIO0); 662 663 mii_mediachg(mii); 664 665 if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) { 666 if (udav_openpipes(sc)) { 667 splx(s); 668 return (EIO); 669 } 670 } 671 672 ifp->if_flags |= IFF_RUNNING; 673 ifp->if_flags &= ~IFF_OACTIVE; 674 675 splx(s); 676 677 timeout_add_sec(&sc->sc_stat_ch, 1); 678 679 return (0); 680 } 681 682 void 683 udav_reset(struct udav_softc *sc) 684 { 685 int i; 686 687 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 688 689 if (usbd_is_dying(sc->sc_udev)) 690 return; 691 692 /* Select PHY */ 693 #if 1 694 /* 695 * XXX: force select internal phy. 696 * external phy routines are not tested. 697 */ 698 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY); 699 #else 700 if (sc->sc_flags & UDAV_EXT_PHY) { 701 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY); 702 } else { 703 UDAV_CLRBIT(sc, UDAV_NCR, UDAV_NCR_EXT_PHY); 704 } 705 #endif 706 707 UDAV_SETBIT(sc, UDAV_NCR, UDAV_NCR_RST); 708 709 for (i = 0; i < UDAV_TX_TIMEOUT; i++) { 710 if (!(udav_csr_read1(sc, UDAV_NCR) & UDAV_NCR_RST)) 711 break; 712 delay(10); /* XXX */ 713 } 714 delay(10000); /* XXX */ 715 } 716 717 int 718 udav_activate(struct device *self, int act) 719 { 720 struct udav_softc *sc = (struct udav_softc *)self; 721 722 DPRINTF(("%s: %s: enter, act=%d\n", sc->sc_dev.dv_xname, 723 __func__, act)); 724 switch (act) { 725 case DVACT_DEACTIVATE: 726 usbd_deactivate(sc->sc_udev); 727 break; 728 } 729 return (0); 730 } 731 732 #define UDAV_BITS 6 733 734 #define UDAV_CALCHASH(addr) \ 735 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1)) 736 737 void 738 udav_setmulti(struct udav_softc *sc) 739 { 740 struct ifnet *ifp; 741 struct ether_multi *enm; 742 struct ether_multistep step; 743 u_int8_t hashes[8]; 744 int h = 0; 745 746 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 747 748 if (usbd_is_dying(sc->sc_udev)) 749 return; 750 751 ifp = GET_IFP(sc); 752 753 if (ifp->if_flags & IFF_PROMISC) { 754 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC); 755 return; 756 } else if (ifp->if_flags & IFF_ALLMULTI) { 757 allmulti: 758 ifp->if_flags |= IFF_ALLMULTI; 759 UDAV_SETBIT(sc, UDAV_RCR, UDAV_RCR_ALL); 760 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_PRMSC); 761 return; 762 } 763 764 /* first, zot all the existing hash bits */ 765 memset(hashes, 0x00, sizeof(hashes)); 766 hashes[7] |= 0x80; /* broadcast address */ 767 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes)); 768 769 /* now program new ones */ 770 ETHER_FIRST_MULTI(step, &sc->sc_ac, enm); 771 while (enm != NULL) { 772 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 773 ETHER_ADDR_LEN) != 0) 774 goto allmulti; 775 776 h = UDAV_CALCHASH(enm->enm_addrlo); 777 hashes[h>>3] |= 1 << (h & 0x7); 778 ETHER_NEXT_MULTI(step, enm); 779 } 780 781 /* disable all multicast */ 782 ifp->if_flags &= ~IFF_ALLMULTI; 783 UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL); 784 785 /* write hash value to the register */ 786 udav_csr_write(sc, UDAV_MAR, hashes, sizeof(hashes)); 787 } 788 789 int 790 udav_openpipes(struct udav_softc *sc) 791 { 792 struct udav_chain *c; 793 usbd_status err; 794 int i; 795 int error = 0; 796 797 if (usbd_is_dying(sc->sc_udev)) 798 return (EIO); 799 800 sc->sc_refcnt++; 801 802 /* Open RX pipe */ 803 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkin_no, 804 USBD_EXCLUSIVE_USE, &sc->sc_pipe_rx); 805 if (err) { 806 printf("%s: open rx pipe failed: %s\n", 807 sc->sc_dev.dv_xname, usbd_errstr(err)); 808 error = EIO; 809 goto done; 810 } 811 812 /* Open TX pipe */ 813 err = usbd_open_pipe(sc->sc_ctl_iface, sc->sc_bulkout_no, 814 USBD_EXCLUSIVE_USE, &sc->sc_pipe_tx); 815 if (err) { 816 printf("%s: open tx pipe failed: %s\n", 817 sc->sc_dev.dv_xname, usbd_errstr(err)); 818 error = EIO; 819 goto done; 820 } 821 822 #if 0 823 /* XXX: interrupt endpoint is not yet supported */ 824 /* Open Interrupt pipe */ 825 err = usbd_open_pipe_intr(sc->sc_ctl_iface, sc->sc_intrin_no, 826 USBD_EXCLUSIVE_USE, &sc->sc_pipe_intr, sc, 827 &sc->sc_cdata.udav_ibuf, UDAV_INTR_PKGLEN, 828 udav_intr, UDAV_INTR_INTERVAL); 829 if (err) { 830 printf("%s: open intr pipe failed: %s\n", 831 sc->sc_dev.dv_xname, usbd_errstr(err)); 832 error = EIO; 833 goto done; 834 } 835 #endif 836 837 838 /* Start up the receive pipe. */ 839 for (i = 0; i < UDAV_RX_LIST_CNT; i++) { 840 c = &sc->sc_cdata.udav_rx_chain[i]; 841 usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx, 842 c, c->udav_buf, UDAV_BUFSZ, 843 USBD_SHORT_XFER_OK | USBD_NO_COPY, 844 USBD_NO_TIMEOUT, udav_rxeof); 845 (void)usbd_transfer(c->udav_xfer); 846 DPRINTF(("%s: %s: start read\n", sc->sc_dev.dv_xname, 847 __func__)); 848 } 849 850 done: 851 if (--sc->sc_refcnt < 0) 852 usb_detach_wakeup(&sc->sc_dev); 853 854 return (error); 855 } 856 857 int 858 udav_newbuf(struct udav_softc *sc, struct udav_chain *c, struct mbuf *m) 859 { 860 struct mbuf *m_new = NULL; 861 862 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 863 864 if (m == NULL) { 865 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 866 if (m_new == NULL) { 867 printf("%s: no memory for rx list " 868 "-- packet dropped!\n", sc->sc_dev.dv_xname); 869 return (ENOBUFS); 870 } 871 MCLGET(m_new, M_DONTWAIT); 872 if (!(m_new->m_flags & M_EXT)) { 873 printf("%s: no memory for rx list " 874 "-- packet dropped!\n", sc->sc_dev.dv_xname); 875 m_freem(m_new); 876 return (ENOBUFS); 877 } 878 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 879 } else { 880 m_new = m; 881 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 882 m_new->m_data = m_new->m_ext.ext_buf; 883 } 884 885 m_adj(m_new, ETHER_ALIGN); 886 c->udav_mbuf = m_new; 887 888 return (0); 889 } 890 891 892 int 893 udav_rx_list_init(struct udav_softc *sc) 894 { 895 struct udav_cdata *cd; 896 struct udav_chain *c; 897 int i; 898 899 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 900 901 cd = &sc->sc_cdata; 902 for (i = 0; i < UDAV_RX_LIST_CNT; i++) { 903 c = &cd->udav_rx_chain[i]; 904 c->udav_sc = sc; 905 c->udav_idx = i; 906 if (udav_newbuf(sc, c, NULL) == ENOBUFS) 907 return (ENOBUFS); 908 if (c->udav_xfer == NULL) { 909 c->udav_xfer = usbd_alloc_xfer(sc->sc_udev); 910 if (c->udav_xfer == NULL) 911 return (ENOBUFS); 912 c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ); 913 if (c->udav_buf == NULL) { 914 usbd_free_xfer(c->udav_xfer); 915 return (ENOBUFS); 916 } 917 } 918 } 919 920 return (0); 921 } 922 923 int 924 udav_tx_list_init(struct udav_softc *sc) 925 { 926 struct udav_cdata *cd; 927 struct udav_chain *c; 928 int i; 929 930 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 931 932 cd = &sc->sc_cdata; 933 for (i = 0; i < UDAV_TX_LIST_CNT; i++) { 934 c = &cd->udav_tx_chain[i]; 935 c->udav_sc = sc; 936 c->udav_idx = i; 937 c->udav_mbuf = NULL; 938 if (c->udav_xfer == NULL) { 939 c->udav_xfer = usbd_alloc_xfer(sc->sc_udev); 940 if (c->udav_xfer == NULL) 941 return (ENOBUFS); 942 c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ); 943 if (c->udav_buf == NULL) { 944 usbd_free_xfer(c->udav_xfer); 945 return (ENOBUFS); 946 } 947 } 948 } 949 950 return (0); 951 } 952 953 void 954 udav_start(struct ifnet *ifp) 955 { 956 struct udav_softc *sc = ifp->if_softc; 957 struct mbuf *m_head = NULL; 958 959 DPRINTF(("%s: %s: enter, link=%d\n", sc->sc_dev.dv_xname, 960 __func__, sc->sc_link)); 961 962 if (usbd_is_dying(sc->sc_udev)) 963 return; 964 965 if (!sc->sc_link) 966 return; 967 968 if (ifp->if_flags & IFF_OACTIVE) 969 return; 970 971 IFQ_POLL(&ifp->if_snd, m_head); 972 if (m_head == NULL) 973 return; 974 975 if (udav_send(sc, m_head, 0)) { 976 ifp->if_flags |= IFF_OACTIVE; 977 return; 978 } 979 980 IFQ_DEQUEUE(&ifp->if_snd, m_head); 981 982 #if NBPFILTER > 0 983 if (ifp->if_bpf) 984 bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT); 985 #endif 986 987 ifp->if_flags |= IFF_OACTIVE; 988 989 /* Set a timeout in case the chip goes out to lunch. */ 990 ifp->if_timer = 5; 991 } 992 993 int 994 udav_send(struct udav_softc *sc, struct mbuf *m, int idx) 995 { 996 int total_len; 997 struct udav_chain *c; 998 usbd_status err; 999 1000 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__)); 1001 1002 c = &sc->sc_cdata.udav_tx_chain[idx]; 1003 1004 /* Copy the mbuf data into a contiguous buffer */ 1005 /* first 2 bytes are packet length */ 1006 m_copydata(m, 0, m->m_pkthdr.len, c->udav_buf + 2); 1007 c->udav_mbuf = m; 1008 total_len = m->m_pkthdr.len; 1009 if (total_len < UDAV_MIN_FRAME_LEN) { 1010 memset(c->udav_buf + 2 + total_len, 0, 1011 UDAV_MIN_FRAME_LEN - total_len); 1012 total_len = UDAV_MIN_FRAME_LEN; 1013 } 1014 1015 /* Frame length is specified in the first 2bytes of the buffer */ 1016 c->udav_buf[0] = (u_int8_t)total_len; 1017 c->udav_buf[1] = (u_int8_t)(total_len >> 8); 1018 total_len += 2; 1019 1020 usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_tx, c, c->udav_buf, total_len, 1021 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 1022 UDAV_TX_TIMEOUT, udav_txeof); 1023 1024 /* Transmit */ 1025 sc->sc_refcnt++; 1026 err = usbd_transfer(c->udav_xfer); 1027 if (--sc->sc_refcnt < 0) 1028 usb_detach_wakeup(&sc->sc_dev); 1029 if (err != USBD_IN_PROGRESS) { 1030 printf("%s: udav_send error=%s\n", sc->sc_dev.dv_xname, 1031 usbd_errstr(err)); 1032 /* Stop the interface */ 1033 usb_add_task(sc->sc_udev, &sc->sc_stop_task); 1034 return (EIO); 1035 } 1036 1037 DPRINTF(("%s: %s: send %d bytes\n", sc->sc_dev.dv_xname, 1038 __func__, total_len)); 1039 1040 sc->sc_cdata.udav_tx_cnt++; 1041 1042 return (0); 1043 } 1044 1045 void 1046 udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1047 { 1048 struct udav_chain *c = priv; 1049 struct udav_softc *sc = c->udav_sc; 1050 struct ifnet *ifp = GET_IFP(sc); 1051 int s; 1052 1053 if (usbd_is_dying(sc->sc_udev)) 1054 return; 1055 1056 s = splnet(); 1057 1058 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 1059 1060 ifp->if_timer = 0; 1061 ifp->if_flags &= ~IFF_OACTIVE; 1062 1063 if (status != USBD_NORMAL_COMPLETION) { 1064 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1065 splx(s); 1066 return; 1067 } 1068 ifp->if_oerrors++; 1069 printf("%s: usb error on tx: %s\n", sc->sc_dev.dv_xname, 1070 usbd_errstr(status)); 1071 if (status == USBD_STALLED) { 1072 sc->sc_refcnt++; 1073 usbd_clear_endpoint_stall_async(sc->sc_pipe_tx); 1074 if (--sc->sc_refcnt < 0) 1075 usb_detach_wakeup(&sc->sc_dev); 1076 } 1077 splx(s); 1078 return; 1079 } 1080 1081 ifp->if_opackets++; 1082 1083 m_freem(c->udav_mbuf); 1084 c->udav_mbuf = NULL; 1085 1086 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1087 udav_start(ifp); 1088 1089 splx(s); 1090 } 1091 1092 void 1093 udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) 1094 { 1095 struct udav_chain *c = priv; 1096 struct udav_softc *sc = c->udav_sc; 1097 struct ifnet *ifp = GET_IFP(sc); 1098 struct udav_rx_hdr *h; 1099 struct mbuf *m; 1100 u_int32_t total_len; 1101 int s; 1102 1103 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname,__func__)); 1104 1105 if (usbd_is_dying(sc->sc_udev)) 1106 return; 1107 1108 if (status != USBD_NORMAL_COMPLETION) { 1109 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1110 return; 1111 sc->sc_rx_errs++; 1112 if (usbd_ratecheck(&sc->sc_rx_notice)) { 1113 printf("%s: %u usb errors on rx: %s\n", 1114 sc->sc_dev.dv_xname, sc->sc_rx_errs, 1115 usbd_errstr(status)); 1116 sc->sc_rx_errs = 0; 1117 } 1118 if (status == USBD_STALLED) { 1119 sc->sc_refcnt++; 1120 usbd_clear_endpoint_stall_async(sc->sc_pipe_rx); 1121 if (--sc->sc_refcnt < 0) 1122 usb_detach_wakeup(&sc->sc_dev); 1123 } 1124 goto done; 1125 } 1126 1127 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 1128 1129 if (total_len < UDAV_RX_HDRLEN) { 1130 ifp->if_ierrors++; 1131 goto done; 1132 } 1133 1134 h = (struct udav_rx_hdr *)c->udav_buf; 1135 total_len = UGETW(h->length) - ETHER_CRC_LEN; 1136 1137 DPRINTF(("%s: RX Status: 0x%02x\n", sc->sc_dev.dv_xname, h->pktstat)); 1138 1139 if (h->pktstat & UDAV_RSR_LCS) { 1140 ifp->if_collisions++; 1141 goto done; 1142 } 1143 1144 /* RX status may still be correct but total_len is bogus */ 1145 if (total_len < sizeof(struct ether_header) || 1146 h->pktstat & UDAV_RSR_ERR || 1147 total_len > UDAV_BUFSZ ) { 1148 ifp->if_ierrors++; 1149 goto done; 1150 } 1151 1152 /* copy data to mbuf */ 1153 m = c->udav_mbuf; 1154 memcpy(mtod(m, char *), c->udav_buf + UDAV_RX_HDRLEN, total_len); 1155 1156 ifp->if_ipackets++; 1157 1158 m->m_pkthdr.len = m->m_len = total_len; 1159 m->m_pkthdr.rcvif = ifp; 1160 1161 s = splnet(); 1162 1163 if (udav_newbuf(sc, c, NULL) == ENOBUFS) { 1164 ifp->if_ierrors++; 1165 goto done1; 1166 } 1167 1168 #if NBPFILTER > 0 1169 if (ifp->if_bpf) 1170 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN); 1171 #endif 1172 1173 DPRINTF(("%s: %s: deliver %d\n", sc->sc_dev.dv_xname, 1174 __func__, m->m_len)); 1175 ether_input_mbuf(ifp, m); 1176 1177 done1: 1178 splx(s); 1179 1180 done: 1181 /* Setup new transfer */ 1182 usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->udav_buf, UDAV_BUFSZ, 1183 USBD_SHORT_XFER_OK | USBD_NO_COPY, 1184 USBD_NO_TIMEOUT, udav_rxeof); 1185 sc->sc_refcnt++; 1186 usbd_transfer(xfer); 1187 if (--sc->sc_refcnt < 0) 1188 usb_detach_wakeup(&sc->sc_dev); 1189 1190 DPRINTF(("%s: %s: start rx\n", sc->sc_dev.dv_xname, __func__)); 1191 } 1192 1193 int 1194 udav_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1195 { 1196 struct udav_softc *sc = ifp->if_softc; 1197 struct ifaddr *ifa = (struct ifaddr *)data; 1198 struct ifreq *ifr = (struct ifreq *)data; 1199 struct mii_data *mii; 1200 int s, error = 0; 1201 1202 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 1203 1204 if (usbd_is_dying(sc->sc_udev)) 1205 return (EIO); 1206 1207 s = splnet(); 1208 1209 switch (cmd) { 1210 case SIOCGIFMEDIA: 1211 case SIOCSIFMEDIA: 1212 mii = GET_MII(sc); 1213 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); 1214 break; 1215 1216 case SIOCSIFADDR: 1217 ifp->if_flags |= IFF_UP; 1218 udav_init(ifp); 1219 1220 switch (ifa->ifa_addr->sa_family) { 1221 #ifdef INET 1222 case AF_INET: 1223 arp_ifinit(&sc->sc_ac, ifa); 1224 break; 1225 #endif /* INET */ 1226 } 1227 break; 1228 1229 case SIOCSIFFLAGS: 1230 if (ifp->if_flags & IFF_UP) { 1231 if (ifp->if_flags & IFF_RUNNING && 1232 ifp->if_flags & IFF_PROMISC) { 1233 UDAV_SETBIT(sc, UDAV_RCR, 1234 UDAV_RCR_ALL|UDAV_RCR_PRMSC); 1235 } else if (ifp->if_flags & IFF_RUNNING && 1236 !(ifp->if_flags & IFF_PROMISC)) { 1237 UDAV_CLRBIT(sc, UDAV_RCR, 1238 UDAV_RCR_PRMSC); 1239 } else if (!(ifp->if_flags & IFF_RUNNING)) 1240 udav_init(ifp); 1241 } else { 1242 if (ifp->if_flags & IFF_RUNNING) 1243 udav_stop(ifp, 1); 1244 } 1245 error = 0; 1246 break; 1247 1248 default: 1249 error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); 1250 } 1251 1252 if (error == ENETRESET) { 1253 if (ifp->if_flags & IFF_RUNNING) 1254 udav_setmulti(sc); 1255 error = 0; 1256 } 1257 1258 splx(s); 1259 return (error); 1260 } 1261 1262 void 1263 udav_watchdog(struct ifnet *ifp) 1264 { 1265 struct udav_softc *sc = ifp->if_softc; 1266 struct udav_chain *c; 1267 usbd_status stat; 1268 int s; 1269 1270 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 1271 1272 ifp->if_oerrors++; 1273 printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname); 1274 1275 s = splusb(); 1276 c = &sc->sc_cdata.udav_tx_chain[0]; 1277 usbd_get_xfer_status(c->udav_xfer, NULL, NULL, NULL, &stat); 1278 udav_txeof(c->udav_xfer, c, stat); 1279 1280 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1281 udav_start(ifp); 1282 splx(s); 1283 } 1284 1285 void 1286 udav_stop_task(struct udav_softc *sc) 1287 { 1288 udav_stop(GET_IFP(sc), 1); 1289 } 1290 1291 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ 1292 void 1293 udav_stop(struct ifnet *ifp, int disable) 1294 { 1295 struct udav_softc *sc = ifp->if_softc; 1296 usbd_status err; 1297 int i; 1298 1299 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 1300 1301 ifp->if_timer = 0; 1302 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1303 1304 udav_reset(sc); 1305 1306 timeout_del(&sc->sc_stat_ch); 1307 1308 /* Stop transfers */ 1309 /* RX endpoint */ 1310 if (sc->sc_pipe_rx != NULL) { 1311 err = usbd_abort_pipe(sc->sc_pipe_rx); 1312 if (err) 1313 printf("%s: abort rx pipe failed: %s\n", 1314 sc->sc_dev.dv_xname, usbd_errstr(err)); 1315 err = usbd_close_pipe(sc->sc_pipe_rx); 1316 if (err) 1317 printf("%s: close rx pipe failed: %s\n", 1318 sc->sc_dev.dv_xname, usbd_errstr(err)); 1319 sc->sc_pipe_rx = NULL; 1320 } 1321 1322 /* TX endpoint */ 1323 if (sc->sc_pipe_tx != NULL) { 1324 err = usbd_abort_pipe(sc->sc_pipe_tx); 1325 if (err) 1326 printf("%s: abort tx pipe failed: %s\n", 1327 sc->sc_dev.dv_xname, usbd_errstr(err)); 1328 err = usbd_close_pipe(sc->sc_pipe_tx); 1329 if (err) 1330 printf("%s: close tx pipe failed: %s\n", 1331 sc->sc_dev.dv_xname, usbd_errstr(err)); 1332 sc->sc_pipe_tx = NULL; 1333 } 1334 1335 #if 0 1336 /* XXX: Interrupt endpoint is not yet supported!! */ 1337 /* Interrupt endpoint */ 1338 if (sc->sc_pipe_intr != NULL) { 1339 err = usbd_abort_pipe(sc->sc_pipe_intr); 1340 if (err) 1341 printf("%s: abort intr pipe failed: %s\n", 1342 sc->sc_dev.dv_xname, usbd_errstr(err)); 1343 err = usbd_close_pipe(sc->sc_pipe_intr); 1344 if (err) 1345 printf("%s: close intr pipe failed: %s\n", 1346 sc->sc_dev.dv_xname, usbd_errstr(err)); 1347 sc->sc_pipe_intr = NULL; 1348 } 1349 #endif 1350 1351 /* Free RX resources. */ 1352 for (i = 0; i < UDAV_RX_LIST_CNT; i++) { 1353 if (sc->sc_cdata.udav_rx_chain[i].udav_mbuf != NULL) { 1354 m_freem(sc->sc_cdata.udav_rx_chain[i].udav_mbuf); 1355 sc->sc_cdata.udav_rx_chain[i].udav_mbuf = NULL; 1356 } 1357 if (sc->sc_cdata.udav_rx_chain[i].udav_xfer != NULL) { 1358 usbd_free_xfer(sc->sc_cdata.udav_rx_chain[i].udav_xfer); 1359 sc->sc_cdata.udav_rx_chain[i].udav_xfer = NULL; 1360 } 1361 } 1362 1363 /* Free TX resources. */ 1364 for (i = 0; i < UDAV_TX_LIST_CNT; i++) { 1365 if (sc->sc_cdata.udav_tx_chain[i].udav_mbuf != NULL) { 1366 m_freem(sc->sc_cdata.udav_tx_chain[i].udav_mbuf); 1367 sc->sc_cdata.udav_tx_chain[i].udav_mbuf = NULL; 1368 } 1369 if (sc->sc_cdata.udav_tx_chain[i].udav_xfer != NULL) { 1370 usbd_free_xfer(sc->sc_cdata.udav_tx_chain[i].udav_xfer); 1371 sc->sc_cdata.udav_tx_chain[i].udav_xfer = NULL; 1372 } 1373 } 1374 1375 sc->sc_link = 0; 1376 } 1377 1378 /* Set media options */ 1379 int 1380 udav_ifmedia_change(struct ifnet *ifp) 1381 { 1382 struct udav_softc *sc = ifp->if_softc; 1383 struct mii_data *mii = GET_MII(sc); 1384 1385 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 1386 1387 if (usbd_is_dying(sc->sc_udev)) 1388 return (0); 1389 1390 sc->sc_link = 0; 1391 if (mii->mii_instance) { 1392 struct mii_softc *miisc; 1393 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL; 1394 miisc = LIST_NEXT(miisc, mii_list)) 1395 mii_phy_reset(miisc); 1396 } 1397 1398 return (mii_mediachg(mii)); 1399 } 1400 1401 /* Report current media status. */ 1402 void 1403 udav_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr) 1404 { 1405 struct udav_softc *sc = ifp->if_softc; 1406 struct mii_data *mii = GET_MII(sc); 1407 1408 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 1409 1410 if (usbd_is_dying(sc->sc_udev)) 1411 return; 1412 1413 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1414 ifmr->ifm_active = IFM_ETHER | IFM_NONE; 1415 ifmr->ifm_status = 0; 1416 return; 1417 } 1418 1419 mii_pollstat(mii); 1420 ifmr->ifm_active = mii->mii_media_active; 1421 ifmr->ifm_status = mii->mii_media_status; 1422 } 1423 1424 void 1425 udav_tick(void *xsc) 1426 { 1427 struct udav_softc *sc = xsc; 1428 1429 if (sc == NULL) 1430 return; 1431 1432 DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, 1433 __func__)); 1434 1435 /* Perform periodic stuff in process context */ 1436 usb_add_task(sc->sc_udev, &sc->sc_tick_task); 1437 } 1438 1439 void 1440 udav_tick_task(void *xsc) 1441 { 1442 struct udav_softc *sc = xsc; 1443 struct ifnet *ifp; 1444 struct mii_data *mii; 1445 int s; 1446 1447 if (sc == NULL) 1448 return; 1449 1450 DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, 1451 __func__)); 1452 1453 if (usbd_is_dying(sc->sc_udev)) 1454 return; 1455 1456 ifp = GET_IFP(sc); 1457 mii = GET_MII(sc); 1458 1459 if (mii == NULL) 1460 return; 1461 1462 s = splnet(); 1463 1464 mii_tick(mii); 1465 if (!sc->sc_link && mii->mii_media_status & IFM_ACTIVE && 1466 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 1467 DPRINTF(("%s: %s: got link\n", 1468 sc->sc_dev.dv_xname, __func__)); 1469 sc->sc_link++; 1470 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) 1471 udav_start(ifp); 1472 } 1473 1474 timeout_add_sec(&sc->sc_stat_ch, 1); 1475 1476 splx(s); 1477 } 1478 1479 /* Get exclusive access to the MII registers */ 1480 void 1481 udav_lock_mii(struct udav_softc *sc) 1482 { 1483 DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, 1484 __func__)); 1485 1486 sc->sc_refcnt++; 1487 rw_enter_write(&sc->sc_mii_lock); 1488 } 1489 1490 void 1491 udav_unlock_mii(struct udav_softc *sc) 1492 { 1493 DPRINTFN(0xff, ("%s: %s: enter\n", sc->sc_dev.dv_xname, 1494 __func__)); 1495 1496 rw_exit_write(&sc->sc_mii_lock); 1497 if (--sc->sc_refcnt < 0) 1498 usb_detach_wakeup(&sc->sc_dev); 1499 } 1500 1501 int 1502 udav_miibus_readreg(struct device *dev, int phy, int reg) 1503 { 1504 struct udav_softc *sc; 1505 u_int8_t val[2]; 1506 u_int16_t data16; 1507 1508 if (dev == NULL) 1509 return (0); 1510 1511 sc = (void *)dev; 1512 1513 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", 1514 sc->sc_dev.dv_xname, __func__, phy, reg)); 1515 1516 if (usbd_is_dying(sc->sc_udev)) { 1517 #ifdef DIAGNOSTIC 1518 printf("%s: %s: dying\n", sc->sc_dev.dv_xname, 1519 __func__); 1520 #endif 1521 return (0); 1522 } 1523 1524 /* XXX: one PHY only for the internal PHY */ 1525 if (phy != 0) { 1526 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 1527 sc->sc_dev.dv_xname, __func__, phy)); 1528 return (0); 1529 } 1530 1531 udav_lock_mii(sc); 1532 1533 /* select internal PHY and set PHY register address */ 1534 udav_csr_write1(sc, UDAV_EPAR, 1535 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 1536 1537 /* select PHY operation and start read command */ 1538 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR); 1539 1540 /* XXX: should be wait? */ 1541 1542 /* end read command */ 1543 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRR); 1544 1545 /* retrieve the result from data registers */ 1546 udav_csr_read(sc, UDAV_EPDRL, val, 2); 1547 1548 udav_unlock_mii(sc); 1549 1550 data16 = val[0] | (val[1] << 8); 1551 1552 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n", 1553 sc->sc_dev.dv_xname, __func__, phy, reg, data16)); 1554 1555 return (data16); 1556 } 1557 1558 void 1559 udav_miibus_writereg(struct device *dev, int phy, int reg, int data) 1560 { 1561 struct udav_softc *sc; 1562 u_int8_t val[2]; 1563 1564 if (dev == NULL) 1565 return; 1566 1567 sc = (void *)dev; 1568 1569 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x data=0x%04x\n", 1570 sc->sc_dev.dv_xname, __func__, phy, reg, data)); 1571 1572 if (usbd_is_dying(sc->sc_udev)) { 1573 #ifdef DIAGNOSTIC 1574 printf("%s: %s: dying\n", sc->sc_dev.dv_xname, 1575 __func__); 1576 #endif 1577 return; 1578 } 1579 1580 /* XXX: one PHY only for the internal PHY */ 1581 if (phy != 0) { 1582 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 1583 sc->sc_dev.dv_xname, __func__, phy)); 1584 return; 1585 } 1586 1587 udav_lock_mii(sc); 1588 1589 /* select internal PHY and set PHY register address */ 1590 udav_csr_write1(sc, UDAV_EPAR, 1591 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 1592 1593 /* put the value to the data registers */ 1594 val[0] = data & 0xff; 1595 val[1] = (data >> 8) & 0xff; 1596 udav_csr_write(sc, UDAV_EPDRL, val, 2); 1597 1598 /* select PHY operation and start write command */ 1599 udav_csr_write1(sc, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW); 1600 1601 /* XXX: should be wait? */ 1602 1603 /* end write command */ 1604 UDAV_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW); 1605 1606 udav_unlock_mii(sc); 1607 1608 return; 1609 } 1610 1611 void 1612 udav_miibus_statchg(struct device *dev) 1613 { 1614 #ifdef UDAV_DEBUG 1615 struct udav_softc *sc; 1616 1617 if (dev == NULL) 1618 return; 1619 1620 sc = (void *)dev; 1621 DPRINTF(("%s: %s: enter\n", sc->sc_dev.dv_xname, __func__)); 1622 #endif 1623 /* Nothing to do */ 1624 } 1625