1 /* $NetBSD: if_udav.c,v 1.78 2021/04/02 09:27:44 skrll Exp $ */ 2 /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ 3 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.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-F01-062202s.pdf 38 */ 39 40 /* 41 * TODO: 42 * Interrupt Endpoint support 43 * External PHYs 44 * powerhook() support? 45 */ 46 47 #include <sys/cdefs.h> 48 __KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.78 2021/04/02 09:27:44 skrll Exp $"); 49 50 #ifdef _KERNEL_OPT 51 #include "opt_usb.h" 52 #endif 53 54 #include <sys/param.h> 55 56 #include <dev/usb/usbnet.h> 57 #include <dev/usb/if_udavreg.h> 58 59 /* Function declarations */ 60 static int udav_match(device_t, cfdata_t, void *); 61 static void udav_attach(device_t, device_t, void *); 62 63 CFATTACH_DECL_NEW(udav, sizeof(struct usbnet), udav_match, udav_attach, 64 usbnet_detach, usbnet_activate); 65 66 static void udav_chip_init(struct usbnet *); 67 68 static unsigned udav_uno_tx_prepare(struct usbnet *, struct mbuf *, 69 struct usbnet_chain *); 70 static void udav_uno_rx_loop(struct usbnet *, struct usbnet_chain *, uint32_t); 71 static void udav_uno_stop(struct ifnet *, int); 72 static int udav_uno_ioctl(struct ifnet *, u_long, void *); 73 static int udav_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 74 static int udav_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 75 static void udav_uno_mii_statchg(struct ifnet *); 76 static int udav_uno_init(struct ifnet *); 77 static void udav_setiff_locked(struct usbnet *); 78 static void udav_reset(struct usbnet *); 79 80 static int udav_csr_read(struct usbnet *, int, void *, int); 81 static int udav_csr_write(struct usbnet *, int, void *, int); 82 static int udav_csr_read1(struct usbnet *, int); 83 static int udav_csr_write1(struct usbnet *, int, unsigned char); 84 85 #if 0 86 static int udav_mem_read(struct usbnet *, int, void *, int); 87 static int udav_mem_write(struct usbnet *, int, void *, int); 88 static int udav_mem_write1(struct usbnet *, int, unsigned char); 89 #endif 90 91 /* Macros */ 92 #ifdef UDAV_DEBUG 93 #define DPRINTF(x) if (udavdebug) printf x 94 #define DPRINTFN(n, x) if (udavdebug >= (n)) printf x 95 int udavdebug = 0; 96 #else 97 #define DPRINTF(x) 98 #define DPRINTFN(n, x) 99 #endif 100 101 #define UDAV_SETBIT(un, reg, x) \ 102 udav_csr_write1(un, reg, udav_csr_read1(un, reg) | (x)) 103 104 #define UDAV_CLRBIT(un, reg, x) \ 105 udav_csr_write1(un, reg, udav_csr_read1(un, reg) & ~(x)) 106 107 static const struct udav_type { 108 struct usb_devno udav_dev; 109 uint16_t udav_flags; 110 #define UDAV_EXT_PHY 0x0001 111 #define UDAV_NO_PHY 0x0002 112 } udav_devs [] = { 113 /* Corega USB-TXC */ 114 {{ USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB_TXC }, 0}, 115 /* ShanTou ST268 USB NIC */ 116 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ST268_USB_NIC }, 0}, 117 /* ShanTou ADM8515 */ 118 {{ USB_VENDOR_SHANTOU, USB_PRODUCT_SHANTOU_ADM8515 }, 0}, 119 /* SUNRISING SR9600 */ 120 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_SR9600 }, 0 }, 121 /* SUNRISING QF9700 */ 122 {{ USB_VENDOR_SUNRISING, USB_PRODUCT_SUNRISING_QF9700 }, UDAV_NO_PHY }, 123 /* QUAN DM9601 */ 124 {{USB_VENDOR_QUAN, USB_PRODUCT_QUAN_DM9601 }, 0}, 125 #if 0 126 /* DAVICOM DM9601 Generic? */ 127 /* XXX: The following ids was obtained from the data sheet. */ 128 {{ 0x0a46, 0x9601 }, 0}, 129 #endif 130 }; 131 #define udav_lookup(v, p) ((const struct udav_type *)usb_lookup(udav_devs, v, p)) 132 133 static const struct usbnet_ops udav_ops = { 134 .uno_stop = udav_uno_stop, 135 .uno_ioctl = udav_uno_ioctl, 136 .uno_read_reg = udav_uno_mii_read_reg, 137 .uno_write_reg = udav_uno_mii_write_reg, 138 .uno_statchg = udav_uno_mii_statchg, 139 .uno_tx_prepare = udav_uno_tx_prepare, 140 .uno_rx_loop = udav_uno_rx_loop, 141 .uno_init = udav_uno_init, 142 }; 143 144 /* Probe */ 145 static int 146 udav_match(device_t parent, cfdata_t match, void *aux) 147 { 148 struct usb_attach_arg *uaa = aux; 149 150 return udav_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 151 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 152 } 153 154 /* Attach */ 155 static void 156 udav_attach(device_t parent, device_t self, void *aux) 157 { 158 USBNET_MII_DECL_DEFAULT(unm); 159 struct usbnet_mii *unmp; 160 struct usbnet * const un = device_private(self); 161 struct usb_attach_arg *uaa = aux; 162 struct usbd_device *dev = uaa->uaa_device; 163 struct usbd_interface *iface; 164 usbd_status err; 165 usb_interface_descriptor_t *id; 166 usb_endpoint_descriptor_t *ed; 167 char *devinfop; 168 int i; 169 170 aprint_naive("\n"); 171 aprint_normal("\n"); 172 devinfop = usbd_devinfo_alloc(dev, 0); 173 aprint_normal_dev(self, "%s\n", devinfop); 174 usbd_devinfo_free(devinfop); 175 176 un->un_dev = self; 177 un->un_udev = dev; 178 un->un_sc = un; 179 un->un_ops = &udav_ops; 180 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 181 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 182 un->un_rx_list_cnt = UDAV_RX_LIST_CNT; 183 un->un_tx_list_cnt = UDAV_TX_LIST_CNT; 184 un->un_rx_bufsz = UDAV_BUFSZ; 185 un->un_tx_bufsz = UDAV_BUFSZ; 186 187 /* Move the device into the configured state. */ 188 err = usbd_set_config_no(dev, UDAV_CONFIG_NO, 1); /* idx 0 */ 189 if (err) { 190 aprint_error_dev(self, "failed to set configuration" 191 ", err=%s\n", usbd_errstr(err)); 192 return; 193 } 194 195 /* get control interface */ 196 err = usbd_device2interface_handle(dev, UDAV_IFACE_INDEX, &iface); 197 if (err) { 198 aprint_error_dev(self, "failed to get interface, err=%s\n", 199 usbd_errstr(err)); 200 return; 201 } 202 203 un->un_iface = iface; 204 un->un_flags = udav_lookup(uaa->uaa_vendor, 205 uaa->uaa_product)->udav_flags; 206 207 /* get interface descriptor */ 208 id = usbd_get_interface_descriptor(un->un_iface); 209 210 /* find endpoints */ 211 un->un_ed[USBNET_ENDPT_RX] = un->un_ed[USBNET_ENDPT_TX] = 212 un->un_ed[USBNET_ENDPT_INTR] = -1; 213 for (i = 0; i < id->bNumEndpoints; i++) { 214 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 215 if (ed == NULL) { 216 aprint_error_dev(self, "couldn't get endpoint %d\n", i); 217 return; 218 } 219 if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 220 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 221 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 222 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_BULK && 223 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT) 224 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 225 else if ((ed->bmAttributes & UE_XFERTYPE) == UE_INTERRUPT && 226 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) 227 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 228 } 229 230 if (un->un_ed[USBNET_ENDPT_RX] == 0 || 231 un->un_ed[USBNET_ENDPT_TX] == 0 || 232 un->un_ed[USBNET_ENDPT_INTR] == 0) { 233 aprint_error_dev(self, "missing endpoint\n"); 234 return; 235 } 236 237 /* Not supported yet. */ 238 un->un_ed[USBNET_ENDPT_INTR] = 0; 239 240 usbnet_attach(un, "udavdet"); 241 242 usbnet_lock_core(un); 243 usbnet_busy(un); 244 245 // /* reset the adapter */ 246 // udav_reset(un); 247 248 /* Get Ethernet Address */ 249 err = udav_csr_read(un, UDAV_PAR, un->un_eaddr, ETHER_ADDR_LEN); 250 usbnet_unbusy(un); 251 usbnet_unlock_core(un); 252 if (err) { 253 aprint_error_dev(self, "read MAC address failed\n"); 254 return; 255 } 256 257 if (ISSET(un->un_flags, UDAV_NO_PHY)) 258 unmp = NULL; 259 else 260 unmp = &unm; 261 262 /* initialize interface information */ 263 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 264 0, unmp); 265 266 return; 267 } 268 269 #if 0 270 /* read memory */ 271 static int 272 udav_mem_read(struct usbnet *un, int offset, void *buf, int len) 273 { 274 usb_device_request_t req; 275 usbd_status err; 276 277 DPRINTFN(0x200, 278 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 279 280 if (usbnet_isdying(un)) 281 return 0; 282 283 offset &= 0xffff; 284 len &= 0xff; 285 286 req.bmRequestType = UT_READ_VENDOR_DEVICE; 287 req.bRequest = UDAV_REQ_MEM_READ; 288 USETW(req.wValue, 0x0000); 289 USETW(req.wIndex, offset); 290 USETW(req.wLength, len); 291 292 err = usbd_do_request(un->un_udev, &req, buf); 293 if (err) { 294 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", 295 device_xname(un->un_dev), __func__, offset, err)); 296 } 297 298 return err; 299 } 300 301 /* write memory */ 302 static int 303 udav_mem_write(struct usbnet *un, int offset, void *buf, int len) 304 { 305 usb_device_request_t req; 306 usbd_status err; 307 308 DPRINTFN(0x200, 309 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 310 311 if (usbnet_isdying(un)) 312 return 0; 313 314 offset &= 0xffff; 315 len &= 0xff; 316 317 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 318 req.bRequest = UDAV_REQ_MEM_WRITE; 319 USETW(req.wValue, 0x0000); 320 USETW(req.wIndex, offset); 321 USETW(req.wLength, len); 322 323 err = usbd_do_request(un->un_udev, &req, buf); 324 if (err) { 325 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 326 device_xname(un->un_dev), __func__, offset, err)); 327 } 328 329 return err; 330 } 331 332 /* write memory */ 333 static int 334 udav_mem_write1(struct usbnet *un, int offset, unsigned char ch) 335 { 336 usb_device_request_t req; 337 usbd_status err; 338 339 DPRINTFN(0x200, 340 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 341 342 if (usbnet_isdying(un)) 343 return 0; 344 345 offset &= 0xffff; 346 347 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 348 req.bRequest = UDAV_REQ_MEM_WRITE1; 349 USETW(req.wValue, ch); 350 USETW(req.wIndex, offset); 351 USETW(req.wLength, 0x0000); 352 353 err = usbd_do_request(un->un_udev, &req, NULL); 354 if (err) { 355 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 356 device_xname(un->un_dev), __func__, offset, err)); 357 } 358 359 return err; 360 } 361 #endif 362 363 /* read register(s) */ 364 static int 365 udav_csr_read(struct usbnet *un, int offset, void *buf, int len) 366 { 367 usb_device_request_t req; 368 usbd_status err; 369 370 usbnet_isowned_core(un); 371 KASSERT(!usbnet_isdying(un)); 372 373 DPRINTFN(0x200, 374 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 375 376 offset &= 0xff; 377 len &= 0xff; 378 379 req.bmRequestType = UT_READ_VENDOR_DEVICE; 380 req.bRequest = UDAV_REQ_REG_READ; 381 USETW(req.wValue, 0x0000); 382 USETW(req.wIndex, offset); 383 USETW(req.wLength, len); 384 385 err = usbd_do_request(un->un_udev, &req, buf); 386 if (err) { 387 DPRINTF(("%s: %s: read failed. off=%04x, err=%d\n", 388 device_xname(un->un_dev), __func__, offset, err)); 389 } 390 391 return err; 392 } 393 394 /* write register(s) */ 395 static int 396 udav_csr_write(struct usbnet *un, int offset, void *buf, int len) 397 { 398 usb_device_request_t req; 399 usbd_status err; 400 401 usbnet_isowned_core(un); 402 KASSERT(!usbnet_isdying(un)); 403 404 DPRINTFN(0x200, 405 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 406 407 offset &= 0xff; 408 len &= 0xff; 409 410 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 411 req.bRequest = UDAV_REQ_REG_WRITE; 412 USETW(req.wValue, 0x0000); 413 USETW(req.wIndex, offset); 414 USETW(req.wLength, len); 415 416 err = usbd_do_request(un->un_udev, &req, buf); 417 if (err) { 418 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 419 device_xname(un->un_dev), __func__, offset, err)); 420 } 421 422 return err; 423 } 424 425 static int 426 udav_csr_read1(struct usbnet *un, int offset) 427 { 428 uint8_t val = 0; 429 430 usbnet_isowned_core(un); 431 432 DPRINTFN(0x200, 433 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 434 435 if (usbnet_isdying(un)) 436 return 0; 437 438 return udav_csr_read(un, offset, &val, 1) ? 0 : val; 439 } 440 441 /* write a register */ 442 static int 443 udav_csr_write1(struct usbnet *un, int offset, unsigned char ch) 444 { 445 usb_device_request_t req; 446 usbd_status err; 447 448 usbnet_isowned_core(un); 449 KASSERT(!usbnet_isdying(un)); 450 451 DPRINTFN(0x200, 452 ("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 453 454 offset &= 0xff; 455 456 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 457 req.bRequest = UDAV_REQ_REG_WRITE1; 458 USETW(req.wValue, ch); 459 USETW(req.wIndex, offset); 460 USETW(req.wLength, 0x0000); 461 462 err = usbd_do_request(un->un_udev, &req, NULL); 463 if (err) { 464 DPRINTF(("%s: %s: write failed. off=%04x, err=%d\n", 465 device_xname(un->un_dev), __func__, offset, err)); 466 } 467 468 return err; 469 } 470 471 static int 472 udav_uno_init(struct ifnet *ifp) 473 { 474 struct usbnet * const un = ifp->if_softc; 475 struct mii_data * const mii = usbnet_mii(un); 476 uint8_t eaddr[ETHER_ADDR_LEN]; 477 int rc = 0; 478 479 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 480 481 usbnet_lock_core(un); 482 483 if (usbnet_isdying(un)) { 484 usbnet_unlock_core(un); 485 return EIO; 486 } 487 488 /* Cancel pending I/O and free all TX/RX buffers */ 489 if (ifp->if_flags & IFF_RUNNING) 490 usbnet_stop(un, ifp, 1); 491 492 usbnet_busy(un); 493 494 memcpy(eaddr, CLLADDR(ifp->if_sadl), sizeof(eaddr)); 495 udav_csr_write(un, UDAV_PAR, eaddr, ETHER_ADDR_LEN); 496 497 /* Initialize network control register */ 498 /* Disable loopback */ 499 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_LBK0 | UDAV_NCR_LBK1); 500 501 /* Initialize RX control register */ 502 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_DIS_LONG | UDAV_RCR_DIS_CRC); 503 504 /* If we want promiscuous mode, accept all physical frames. */ 505 if (ifp->if_flags & IFF_PROMISC) 506 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 507 else 508 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 509 510 /* Load the multicast filter */ 511 udav_setiff_locked(un); 512 513 /* Enable RX */ 514 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_RXEN); 515 516 /* clear POWER_DOWN state of internal PHY */ 517 UDAV_SETBIT(un, UDAV_GPCR, UDAV_GPCR_GEP_CNTL0); 518 UDAV_CLRBIT(un, UDAV_GPR, UDAV_GPR_GEPIO0); 519 520 if (mii && (rc = mii_mediachg(mii)) == ENXIO) 521 rc = 0; 522 523 if (rc != 0) { 524 usbnet_unbusy(un); 525 usbnet_unlock_core(un); 526 return rc; 527 } 528 529 if (usbnet_isdying(un)) 530 rc = EIO; 531 else 532 rc = usbnet_init_rx_tx(un); 533 534 usbnet_unbusy(un); 535 usbnet_unlock_core(un); 536 537 return rc; 538 } 539 540 static void 541 udav_reset(struct usbnet *un) 542 { 543 usbnet_isowned_core(un); 544 545 if (usbnet_isdying(un)) 546 return; 547 548 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 549 550 udav_chip_init(un); 551 } 552 553 static void 554 udav_chip_init(struct usbnet *un) 555 { 556 usbnet_isowned_core(un); 557 558 /* Select PHY */ 559 #if 1 560 /* 561 * XXX: force select internal phy. 562 * external phy routines are not tested. 563 */ 564 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 565 #else 566 if (un->un_flags & UDAV_EXT_PHY) { 567 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 568 } else { 569 UDAV_CLRBIT(un, UDAV_NCR, UDAV_NCR_EXT_PHY); 570 } 571 #endif 572 573 UDAV_SETBIT(un, UDAV_NCR, UDAV_NCR_RST); 574 575 for (int i = 0; i < UDAV_TX_TIMEOUT; i++) { 576 if (!(udav_csr_read1(un, UDAV_NCR) & UDAV_NCR_RST)) 577 break; 578 delay(10); /* XXX */ 579 } 580 delay(10000); /* XXX */ 581 } 582 583 #define UDAV_BITS 6 584 585 #define UDAV_CALCHASH(addr) \ 586 (ether_crc32_le((addr), ETHER_ADDR_LEN) & ((1 << UDAV_BITS) - 1)) 587 588 static void 589 udav_setiff_locked(struct usbnet *un) 590 { 591 struct ethercom *ec = usbnet_ec(un); 592 struct ifnet * const ifp = usbnet_ifp(un); 593 struct ether_multi *enm; 594 struct ether_multistep step; 595 uint8_t hashes[8]; 596 int h = 0; 597 598 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 599 600 usbnet_isowned_core(un); 601 602 if (usbnet_isdying(un)) 603 return; 604 605 if (ISSET(un->un_flags, UDAV_NO_PHY)) { 606 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); 607 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); 608 return; 609 } 610 611 if (ifp->if_flags & IFF_PROMISC) { 612 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL | UDAV_RCR_PRMSC); 613 return; 614 } else if (ifp->if_flags & IFF_ALLMULTI) { 615 allmulti: 616 ifp->if_flags |= IFF_ALLMULTI; 617 UDAV_SETBIT(un, UDAV_RCR, UDAV_RCR_ALL); 618 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_PRMSC); 619 return; 620 } 621 622 /* first, zot all the existing hash bits */ 623 memset(hashes, 0x00, sizeof(hashes)); 624 hashes[7] |= 0x80; /* broadcast address */ 625 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes)); 626 627 /* now program new ones */ 628 ETHER_LOCK(ec); 629 ETHER_FIRST_MULTI(step, ec, enm); 630 while (enm != NULL) { 631 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 632 ETHER_ADDR_LEN) != 0) { 633 ETHER_UNLOCK(ec); 634 goto allmulti; 635 } 636 637 h = UDAV_CALCHASH(enm->enm_addrlo); 638 hashes[h>>3] |= 1 << (h & 0x7); 639 ETHER_NEXT_MULTI(step, enm); 640 } 641 ETHER_UNLOCK(ec); 642 643 /* disable all multicast */ 644 ifp->if_flags &= ~IFF_ALLMULTI; 645 UDAV_CLRBIT(un, UDAV_RCR, UDAV_RCR_ALL); 646 647 /* write hash value to the register */ 648 udav_csr_write(un, UDAV_MAR, hashes, sizeof(hashes)); 649 } 650 651 static unsigned 652 udav_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 653 { 654 int total_len; 655 uint8_t *buf = c->unc_buf; 656 657 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 658 659 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - 2) 660 return 0; 661 662 /* Copy the mbuf data into a contiguous buffer */ 663 m_copydata(m, 0, m->m_pkthdr.len, buf + 2); 664 total_len = m->m_pkthdr.len; 665 if (total_len < UDAV_MIN_FRAME_LEN) { 666 memset(buf + 2 + total_len, 0, 667 UDAV_MIN_FRAME_LEN - total_len); 668 total_len = UDAV_MIN_FRAME_LEN; 669 } 670 671 /* Frame length is specified in the first 2bytes of the buffer */ 672 buf[0] = (uint8_t)total_len; 673 buf[1] = (uint8_t)(total_len >> 8); 674 total_len += 2; 675 676 DPRINTF(("%s: %s: send %d bytes\n", device_xname(un->un_dev), 677 __func__, total_len)); 678 679 return total_len; 680 } 681 682 static void 683 udav_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 684 { 685 struct ifnet *ifp = usbnet_ifp(un); 686 uint8_t *buf = c->unc_buf; 687 uint16_t pkt_len; 688 uint8_t pktstat; 689 690 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 691 692 /* first byte in received data */ 693 pktstat = *buf; 694 total_len -= sizeof(pktstat); 695 buf += sizeof(pktstat); 696 697 DPRINTF(("%s: RX Status: 0x%02x\n", device_xname(un->un_dev), pktstat)); 698 699 pkt_len = UGETW(buf); 700 total_len -= sizeof(pkt_len); 701 buf += sizeof(pkt_len); 702 703 DPRINTF(("%s: RX Length: 0x%02x\n", device_xname(un->un_dev), pkt_len)); 704 705 if (pktstat & UDAV_RSR_LCS) { 706 if_statinc(ifp, if_collisions); 707 return; 708 } 709 710 if (pkt_len < sizeof(struct ether_header) || 711 pkt_len > total_len || 712 (pktstat & UDAV_RSR_ERR)) { 713 if_statinc(ifp, if_ierrors); 714 return; 715 } 716 717 pkt_len -= ETHER_CRC_LEN; 718 719 DPRINTF(("%s: Rx deliver: 0x%02x\n", device_xname(un->un_dev), pkt_len)); 720 721 usbnet_enqueue(un, buf, pkt_len, 0, 0, 0); 722 } 723 724 static int 725 udav_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 726 { 727 struct usbnet * const un = ifp->if_softc; 728 729 usbnet_lock_core(un); 730 usbnet_busy(un); 731 732 switch (cmd) { 733 case SIOCADDMULTI: 734 case SIOCDELMULTI: 735 udav_setiff_locked(un); 736 break; 737 default: 738 break; 739 } 740 741 usbnet_unbusy(un); 742 usbnet_unlock_core(un); 743 744 return 0; 745 } 746 747 /* Stop the adapter and free any mbufs allocated to the RX and TX lists. */ 748 static void 749 udav_uno_stop(struct ifnet *ifp, int disable) 750 { 751 struct usbnet * const un = ifp->if_softc; 752 753 DPRINTF(("%s: %s: enter\n", device_xname(un->un_dev), __func__)); 754 755 udav_reset(un); 756 } 757 758 static int 759 udav_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 760 { 761 uint8_t data[2]; 762 763 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x\n", 764 device_xname(un->un_dev), __func__, phy, reg)); 765 766 if (usbnet_isdying(un)) { 767 #ifdef DIAGNOSTIC 768 printf("%s: %s: dying\n", device_xname(un->un_dev), 769 __func__); 770 #endif 771 return EINVAL; 772 } 773 774 /* XXX: one PHY only for the internal PHY */ 775 if (phy != 0) { 776 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 777 device_xname(un->un_dev), __func__, phy)); 778 return EINVAL; 779 } 780 781 /* select internal PHY and set PHY register address */ 782 udav_csr_write1(un, UDAV_EPAR, 783 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 784 785 /* select PHY operation and start read command */ 786 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRR); 787 788 /* XXX: should be wait? */ 789 790 /* end read command */ 791 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRR); 792 793 /* retrieve the result from data registers */ 794 udav_csr_read(un, UDAV_EPDRL, data, 2); 795 796 *val = data[0] | (data[1] << 8); 797 798 DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04hx\n", 799 device_xname(un->un_dev), __func__, phy, reg, *val)); 800 801 return 0; 802 } 803 804 static int 805 udav_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 806 { 807 uint8_t data[2]; 808 809 DPRINTFN(0xff, ("%s: %s: enter, phy=%d reg=0x%04x val=0x%04hx\n", 810 device_xname(un->un_dev), __func__, phy, reg, val)); 811 812 if (usbnet_isdying(un)) { 813 #ifdef DIAGNOSTIC 814 printf("%s: %s: dying\n", device_xname(un->un_dev), 815 __func__); 816 #endif 817 return EIO; 818 } 819 820 /* XXX: one PHY only for the internal PHY */ 821 if (phy != 0) { 822 DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", 823 device_xname(un->un_dev), __func__, phy)); 824 return EIO; 825 } 826 827 /* select internal PHY and set PHY register address */ 828 udav_csr_write1(un, UDAV_EPAR, 829 UDAV_EPAR_PHY_ADR0 | (reg & UDAV_EPAR_EROA_MASK)); 830 831 /* put the value to the data registers */ 832 data[0] = val & 0xff; 833 data[1] = (val >> 8) & 0xff; 834 udav_csr_write(un, UDAV_EPDRL, data, 2); 835 836 /* select PHY operation and start write command */ 837 udav_csr_write1(un, UDAV_EPCR, UDAV_EPCR_EPOS | UDAV_EPCR_ERPRW); 838 839 /* XXX: should be wait? */ 840 841 /* end write command */ 842 UDAV_CLRBIT(un, UDAV_EPCR, UDAV_EPCR_ERPRW); 843 844 return 0; 845 } 846 847 static void 848 udav_uno_mii_statchg(struct ifnet *ifp) 849 { 850 struct usbnet * const un = ifp->if_softc; 851 struct mii_data * const mii = usbnet_mii(un); 852 853 DPRINTF(("%s: %s: enter\n", ifp->if_xname, __func__)); 854 855 if (usbnet_isdying(un)) 856 return; 857 858 if ((mii->mii_media_status & IFM_ACTIVE) && 859 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 860 DPRINTF(("%s: %s: got link\n", 861 device_xname(un->un_dev), __func__)); 862 usbnet_set_link(un, true); 863 } 864 } 865 866 #ifdef _MODULE 867 #include "ioconf.c" 868 #endif 869 870 USBNET_MODULE(udav) 871