1 /* $NetBSD: if_axen.c,v 1.73 2020/03/15 23:04:50 thorpej Exp $ */ 2 /* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ 3 4 /* 5 * Copyright (c) 2013 Yojiro UO <yuo@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * ASIX Electronics AX88178a USB 2.0 ethernet and AX88179 USB 3.0 Ethernet 22 * driver. 23 */ 24 25 #include <sys/cdefs.h> 26 __KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.73 2020/03/15 23:04:50 thorpej Exp $"); 27 28 #ifdef _KERNEL_OPT 29 #include "opt_usb.h" 30 #endif 31 32 #include <sys/param.h> 33 34 #include <netinet/in.h> /* XXX for netinet/ip.h */ 35 #include <netinet/ip.h> /* XXX for IP_MAXPACKET */ 36 37 #include <dev/usb/usbnet.h> 38 39 #include <dev/usb/if_axenreg.h> 40 41 #ifdef AXEN_DEBUG 42 #define DPRINTF(x) do { if (axendebug) printf x; } while (/*CONSTCOND*/0) 43 #define DPRINTFN(n, x) do { if (axendebug >= (n)) printf x; } while (/*CONSTCOND*/0) 44 int axendebug = 0; 45 #else 46 #define DPRINTF(x) 47 #define DPRINTFN(n, x) 48 #endif 49 50 struct axen_type { 51 struct usb_devno axen_devno; 52 uint16_t axen_flags; 53 #define AX178A 0x0001 /* AX88178a */ 54 #define AX179 0x0002 /* AX88179 */ 55 }; 56 57 /* 58 * Various supported device vendors/products. 59 */ 60 static const struct axen_type axen_devs[] = { 61 #if 0 /* not tested */ 62 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178A}, AX178A }, 63 #endif 64 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179}, AX179 }, 65 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312}, AX179 } 66 }; 67 68 #define axen_lookup(v, p) ((const struct axen_type *)usb_lookup(axen_devs, v, p)) 69 70 static int axen_match(device_t, cfdata_t, void *); 71 static void axen_attach(device_t, device_t, void *); 72 73 CFATTACH_DECL_NEW(axen, sizeof(struct usbnet), 74 axen_match, axen_attach, usbnet_detach, usbnet_activate); 75 76 static int axen_cmd(struct usbnet *, int, int, int, void *); 77 static void axen_reset(struct usbnet *); 78 static int axen_get_eaddr(struct usbnet *, void *); 79 static void axen_ax88179_init(struct usbnet *); 80 81 static void axen_uno_stop(struct ifnet *, int); 82 static int axen_uno_ioctl(struct ifnet *, u_long, void *); 83 static int axen_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 84 static int axen_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 85 static void axen_uno_mii_statchg(struct ifnet *); 86 static void axen_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 87 uint32_t); 88 static unsigned axen_uno_tx_prepare(struct usbnet *, struct mbuf *, 89 struct usbnet_chain *); 90 static int axen_uno_init(struct ifnet *); 91 92 static const struct usbnet_ops axen_ops = { 93 .uno_stop = axen_uno_stop, 94 .uno_ioctl = axen_uno_ioctl, 95 .uno_read_reg = axen_uno_mii_read_reg, 96 .uno_write_reg = axen_uno_mii_write_reg, 97 .uno_statchg = axen_uno_mii_statchg, 98 .uno_tx_prepare = axen_uno_tx_prepare, 99 .uno_rx_loop = axen_uno_rx_loop, 100 .uno_init = axen_uno_init, 101 }; 102 103 static int 104 axen_cmd(struct usbnet *un, int cmd, int index, int val, void *buf) 105 { 106 usb_device_request_t req; 107 usbd_status err; 108 109 usbnet_isowned_core(un); 110 111 if (usbnet_isdying(un)) 112 return 0; 113 114 if (AXEN_CMD_DIR(cmd)) 115 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 116 else 117 req.bmRequestType = UT_READ_VENDOR_DEVICE; 118 req.bRequest = AXEN_CMD_CMD(cmd); 119 USETW(req.wValue, val); 120 USETW(req.wIndex, index); 121 USETW(req.wLength, AXEN_CMD_LEN(cmd)); 122 123 err = usbd_do_request(un->un_udev, &req, buf); 124 DPRINTFN(5, ("axen_cmd: cmd 0x%04x val 0x%04x len %d\n", 125 cmd, val, AXEN_CMD_LEN(cmd))); 126 127 if (err) { 128 DPRINTF(("%s: cmd: %d, error: %d\n", __func__, cmd, err)); 129 return -1; 130 } 131 132 return 0; 133 } 134 135 static int 136 axen_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 137 { 138 uint16_t data; 139 140 if (un->un_phyno != phy) 141 return EINVAL; 142 143 usbd_status err = axen_cmd(un, AXEN_CMD_MII_READ_REG, reg, phy, &data); 144 if (err) 145 return EIO; 146 147 *val = le16toh(data); 148 if (reg == MII_BMSR) 149 *val &= ~BMSR_EXTCAP; 150 151 return 0; 152 } 153 154 static int 155 axen_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 156 { 157 uint16_t uval = htole16(val); 158 159 if (un->un_phyno != phy) 160 return EINVAL; 161 162 usbd_status err = axen_cmd(un, AXEN_CMD_MII_WRITE_REG, reg, phy, &uval); 163 if (err) 164 return EIO; 165 166 return 0; 167 } 168 169 static void 170 axen_uno_mii_statchg(struct ifnet *ifp) 171 { 172 struct usbnet * const un = ifp->if_softc; 173 struct mii_data * const mii = usbnet_mii(un); 174 int err; 175 uint16_t val; 176 uint16_t wval; 177 178 if (usbnet_isdying(un)) 179 return; 180 181 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 182 (IFM_ACTIVE | IFM_AVALID)) { 183 switch (IFM_SUBTYPE(mii->mii_media_active)) { 184 case IFM_10_T: 185 case IFM_100_TX: 186 usbnet_set_link(un, true); 187 break; 188 case IFM_1000_T: 189 usbnet_set_link(un, true); 190 break; 191 default: 192 break; 193 } 194 } 195 196 /* Lost link, do nothing. */ 197 if (!usbnet_havelink(un)) 198 return; 199 200 val = 0; 201 if ((mii->mii_media_active & IFM_FDX) != 0) 202 val |= AXEN_MEDIUM_FDX; 203 204 val |= AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN | 205 AXEN_MEDIUM_RECV_EN; 206 switch (IFM_SUBTYPE(mii->mii_media_active)) { 207 case IFM_1000_T: 208 val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ; 209 break; 210 case IFM_100_TX: 211 val |= AXEN_MEDIUM_PS; 212 break; 213 case IFM_10_T: 214 /* doesn't need to be handled */ 215 break; 216 } 217 218 DPRINTF(("%s: val=%#x\n", __func__, val)); 219 wval = htole16(val); 220 err = axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); 221 if (err) 222 aprint_error_dev(un->un_dev, "media change failed\n"); 223 } 224 225 static void 226 axen_setiff_locked(struct usbnet *un) 227 { 228 struct ifnet * const ifp = usbnet_ifp(un); 229 struct ethercom *ec = usbnet_ec(un); 230 struct ether_multi *enm; 231 struct ether_multistep step; 232 uint32_t h = 0; 233 uint16_t rxmode; 234 uint8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 235 uint16_t wval; 236 237 if (usbnet_isdying(un)) 238 return; 239 240 usbnet_isowned_core(un); 241 242 rxmode = 0; 243 244 /* Enable receiver, set RX mode */ 245 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 246 rxmode = le16toh(wval); 247 rxmode &= ~(AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_PROMISC | 248 AXEN_RXCTL_ACPT_MCAST); 249 250 if (ifp->if_flags & IFF_PROMISC) { 251 DPRINTF(("%s: promisc\n", device_xname(un->un_dev))); 252 rxmode |= AXEN_RXCTL_PROMISC; 253 allmulti: 254 ETHER_LOCK(ec); 255 ec->ec_flags |= ETHER_F_ALLMULTI; 256 ETHER_UNLOCK(ec); 257 rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST 258 /* | AXEN_RXCTL_ACPT_PHY_MCAST */; 259 } else { 260 /* now program new ones */ 261 DPRINTF(("%s: initializing hash table\n", 262 device_xname(un->un_dev))); 263 ETHER_LOCK(ec); 264 ec->ec_flags &= ~ETHER_F_ALLMULTI; 265 266 ETHER_FIRST_MULTI(step, ec, enm); 267 while (enm != NULL) { 268 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 269 ETHER_ADDR_LEN)) { 270 DPRINTF(("%s: allmulti\n", 271 device_xname(un->un_dev))); 272 memset(hashtbl, 0, sizeof(hashtbl)); 273 ETHER_UNLOCK(ec); 274 goto allmulti; 275 } 276 h = ether_crc32_be(enm->enm_addrlo, 277 ETHER_ADDR_LEN) >> 26; 278 hashtbl[h / 8] |= 1 << (h % 8); 279 DPRINTF(("%s: %s added\n", 280 device_xname(un->un_dev), 281 ether_sprintf(enm->enm_addrlo))); 282 ETHER_NEXT_MULTI(step, enm); 283 } 284 ETHER_UNLOCK(ec); 285 rxmode |= AXEN_RXCTL_ACPT_MCAST; 286 } 287 288 axen_cmd(un, AXEN_CMD_MAC_WRITE_FILTER, 8, AXEN_FILTER_MULTI, hashtbl); 289 wval = htole16(rxmode); 290 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 291 } 292 293 static void 294 axen_reset(struct usbnet *un) 295 { 296 usbnet_isowned_core(un); 297 if (usbnet_isdying(un)) 298 return; 299 /* XXX What to reset? */ 300 301 /* Wait a little while for the chip to get its brains in order. */ 302 DELAY(1000); 303 } 304 305 static int 306 axen_get_eaddr(struct usbnet *un, void *addr) 307 { 308 #if 1 309 return axen_cmd(un, AXEN_CMD_MAC_READ_ETHER, 6, AXEN_CMD_MAC_NODE_ID, 310 addr); 311 #else 312 int i, retry; 313 uint8_t eeprom[20]; 314 uint16_t csum; 315 uint16_t buf; 316 317 for (i = 0; i < 6; i++) { 318 /* set eeprom address */ 319 buf = htole16(i); 320 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_ADDR, &buf); 321 322 /* set eeprom command */ 323 buf = htole16(AXEN_EEPROM_READ); 324 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_CMD, &buf); 325 326 /* check the value is ready */ 327 retry = 3; 328 do { 329 buf = htole16(AXEN_EEPROM_READ); 330 usbd_delay_ms(un->un_udev, 10); 331 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_MAC_EEPROM_CMD, 332 &buf); 333 retry--; 334 if (retry < 0) 335 return EINVAL; 336 } while ((le16toh(buf) & 0xff) & AXEN_EEPROM_BUSY); 337 338 /* read data */ 339 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_EEPROM_READ, 340 &eeprom[i * 2]); 341 342 /* sanity check */ 343 if ((i == 0) && (eeprom[0] == 0xff)) 344 return EINVAL; 345 } 346 347 /* check checksum */ 348 csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9]; 349 csum = (csum >> 8) + (csum & 0xff) + eeprom[10]; 350 if (csum != 0xff) { 351 printf("eeprom checksum mismatch(0x%02x)\n", csum); 352 return EINVAL; 353 } 354 355 memcpy(addr, eeprom, ETHER_ADDR_LEN); 356 return 0; 357 #endif 358 } 359 360 static void 361 axen_ax88179_init(struct usbnet *un) 362 { 363 struct axen_qctrl qctrl; 364 uint16_t ctl, temp; 365 uint16_t wval; 366 uint8_t val; 367 368 usbnet_lock_core(un); 369 usbnet_busy(un); 370 371 /* XXX: ? */ 372 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_UNK_05, &val); 373 DPRINTFN(5, ("AXEN_CMD_MAC_READ(0x05): 0x%02x\n", val)); 374 375 /* check AX88179 version, UA1 / UA2 */ 376 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_GENERAL_STATUS, &val); 377 /* UA1 */ 378 if (!(val & AXEN_GENERAL_STATUS_MASK)) { 379 DPRINTF(("AX88179 ver. UA1\n")); 380 } else { 381 DPRINTF(("AX88179 ver. UA2\n")); 382 } 383 384 /* power up ethernet PHY */ 385 wval = htole16(0); 386 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 387 388 wval = htole16(AXEN_PHYPWR_RSTCTL_IPRL); 389 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 390 usbd_delay_ms(un->un_udev, 200); 391 392 /* set clock mode */ 393 val = AXEN_PHYCLK_ACS | AXEN_PHYCLK_BCS; 394 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 395 usbd_delay_ms(un->un_udev, 100); 396 397 /* set monitor mode (disable) */ 398 val = AXEN_MONITOR_NONE; 399 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val); 400 401 /* enable auto detach */ 402 axen_cmd(un, AXEN_CMD_EEPROM_READ, 2, AXEN_EEPROM_STAT, &wval); 403 temp = le16toh(wval); 404 DPRINTFN(2,("EEPROM0x43 = 0x%04x\n", temp)); 405 if (!(temp == 0xffff) && !(temp & 0x0100)) { 406 /* Enable auto detach bit */ 407 val = 0; 408 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 409 val = AXEN_PHYCLK_ULR; 410 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 411 usbd_delay_ms(un->un_udev, 100); 412 413 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_PHYPWR_RSTCTL, &wval); 414 ctl = le16toh(wval); 415 ctl |= AXEN_PHYPWR_RSTCTL_AUTODETACH; 416 wval = htole16(ctl); 417 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 418 usbd_delay_ms(un->un_udev, 200); 419 aprint_error_dev(un->un_dev, "enable auto detach (0x%04x)\n", 420 ctl); 421 } 422 423 /* bulkin queue setting */ 424 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &val); 425 switch (val) { 426 case AXEN_USB_FS: 427 DPRINTF(("uplink: USB1.1\n")); 428 qctrl.ctrl = 0x07; 429 qctrl.timer_low = 0xcc; 430 qctrl.timer_high = 0x4c; 431 qctrl.bufsize = AXEN_BUFSZ_LS - 1; 432 qctrl.ifg = 0x08; 433 break; 434 case AXEN_USB_HS: 435 DPRINTF(("uplink: USB2.0\n")); 436 qctrl.ctrl = 0x07; 437 qctrl.timer_low = 0x02; 438 qctrl.timer_high = 0xa0; 439 qctrl.bufsize = AXEN_BUFSZ_HS - 1; 440 qctrl.ifg = 0xff; 441 break; 442 case AXEN_USB_SS: 443 DPRINTF(("uplink: USB3.0\n")); 444 qctrl.ctrl = 0x07; 445 qctrl.timer_low = 0x4f; 446 qctrl.timer_high = 0x00; 447 qctrl.bufsize = AXEN_BUFSZ_SS - 1; 448 qctrl.ifg = 0xff; 449 break; 450 default: 451 aprint_error_dev(un->un_dev, "unknown uplink bus:0x%02x\n", 452 val); 453 usbnet_unbusy(un); 454 usbnet_unlock_core(un); 455 return; 456 } 457 axen_cmd(un, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl); 458 459 /* 460 * set buffer high/low watermark to pause/resume. 461 * write 2byte will set high/log simultaneous with AXEN_PAUSE_HIGH. 462 * XXX: what is the best value? OSX driver uses 0x3c-0x4c as LOW-HIGH 463 * watermark parameters. 464 */ 465 val = 0x34; 466 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_LOW_WATERMARK, &val); 467 val = 0x52; 468 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_HIGH_WATERMARK, &val); 469 470 /* Set RX/TX configuration. */ 471 /* Set RX control register */ 472 ctl = AXEN_RXCTL_IPE | AXEN_RXCTL_DROPCRCERR | AXEN_RXCTL_AUTOB; 473 wval = htole16(ctl); 474 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 475 476 /* set monitor mode (enable) */ 477 val = AXEN_MONITOR_PMETYPE | AXEN_MONITOR_PMEPOL | AXEN_MONITOR_RWMP; 478 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val); 479 axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_MONITOR_MODE, &val); 480 DPRINTF(("axen: Monitor mode = 0x%02x\n", val)); 481 482 /* set medium type */ 483 ctl = AXEN_MEDIUM_GIGA | AXEN_MEDIUM_FDX | AXEN_MEDIUM_EN_125MHZ | 484 AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN | 485 AXEN_MEDIUM_RECV_EN; 486 wval = htole16(ctl); 487 DPRINTF(("axen: set to medium mode: 0x%04x\n", ctl)); 488 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); 489 usbd_delay_ms(un->un_udev, 100); 490 491 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MEDIUM_STATUS, &wval); 492 DPRINTF(("axen: current medium mode: 0x%04x\n", le16toh(wval))); 493 494 #if 0 /* XXX: TBD.... */ 495 #define GMII_LED_ACTIVE 0x1a 496 #define GMII_PHY_PAGE_SEL 0x1e 497 #define GMII_PHY_PAGE_SEL 0x1f 498 #define GMII_PAGE_EXT 0x0007 499 usbnet_mii_writereg(un->un_dev, un->un_phyno, GMII_PHY_PAGE_SEL, 500 GMII_PAGE_EXT); 501 usbnet_mii_writereg(un->un_dev, un->un_phyno, GMII_PHY_PAGE, 502 0x002c); 503 #endif 504 505 #if 1 /* XXX: phy hack ? */ 506 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x1F, 0x0005); 507 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x0C, 0x0000); 508 usbnet_mii_readreg(un->un_dev, un->un_phyno, 0x0001, &wval); 509 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x01, wval | 0x0080); 510 usbnet_mii_writereg(un->un_dev, un->un_phyno, 0x1F, 0x0000); 511 #endif 512 513 usbnet_unbusy(un); 514 usbnet_unlock_core(un); 515 } 516 517 static void 518 axen_setoe_locked(struct usbnet *un) 519 { 520 struct ifnet * const ifp = usbnet_ifp(un); 521 uint64_t enabled = ifp->if_capenable; 522 uint8_t val; 523 524 usbnet_isowned_core(un); 525 526 val = AXEN_RXCOE_OFF; 527 if (enabled & IFCAP_CSUM_IPv4_Rx) 528 val |= AXEN_RXCOE_IPv4; 529 if (enabled & IFCAP_CSUM_TCPv4_Rx) 530 val |= AXEN_RXCOE_TCPv4; 531 if (enabled & IFCAP_CSUM_UDPv4_Rx) 532 val |= AXEN_RXCOE_UDPv4; 533 if (enabled & IFCAP_CSUM_TCPv6_Rx) 534 val |= AXEN_RXCOE_TCPv6; 535 if (enabled & IFCAP_CSUM_UDPv6_Rx) 536 val |= AXEN_RXCOE_UDPv6; 537 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_RX_COE, &val); 538 539 val = AXEN_TXCOE_OFF; 540 if (enabled & IFCAP_CSUM_IPv4_Tx) 541 val |= AXEN_TXCOE_IPv4; 542 if (enabled & IFCAP_CSUM_TCPv4_Tx) 543 val |= AXEN_TXCOE_TCPv4; 544 if (enabled & IFCAP_CSUM_UDPv4_Tx) 545 val |= AXEN_TXCOE_UDPv4; 546 if (enabled & IFCAP_CSUM_TCPv6_Tx) 547 val |= AXEN_TXCOE_TCPv6; 548 if (enabled & IFCAP_CSUM_UDPv6_Tx) 549 val |= AXEN_TXCOE_UDPv6; 550 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_TX_COE, &val); 551 } 552 553 static int 554 axen_uno_ioctl(struct ifnet *ifp, u_long cmd, void *data) 555 { 556 struct usbnet * const un = ifp->if_softc; 557 558 usbnet_lock_core(un); 559 usbnet_busy(un); 560 561 switch (cmd) { 562 case SIOCSIFFLAGS: 563 case SIOCSETHERCAP: 564 case SIOCADDMULTI: 565 case SIOCDELMULTI: 566 axen_setiff_locked(un); 567 break; 568 case SIOCSIFCAP: 569 axen_setoe_locked(un); 570 break; 571 default: 572 break; 573 } 574 575 usbnet_unbusy(un); 576 usbnet_unlock_core(un); 577 578 return 0; 579 } 580 581 static int 582 axen_match(device_t parent, cfdata_t match, void *aux) 583 { 584 struct usb_attach_arg *uaa = aux; 585 586 return axen_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 587 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 588 } 589 590 static void 591 axen_attach(device_t parent, device_t self, void *aux) 592 { 593 USBNET_MII_DECL_DEFAULT(unm); 594 struct usbnet * const un = device_private(self); 595 struct usb_attach_arg *uaa = aux; 596 struct usbd_device *dev = uaa->uaa_device; 597 usbd_status err; 598 usb_interface_descriptor_t *id; 599 usb_endpoint_descriptor_t *ed; 600 char *devinfop; 601 uint16_t axen_flags; 602 int i; 603 604 aprint_naive("\n"); 605 aprint_normal("\n"); 606 devinfop = usbd_devinfo_alloc(dev, 0); 607 aprint_normal_dev(self, "%s\n", devinfop); 608 usbd_devinfo_free(devinfop); 609 610 un->un_dev = self; 611 un->un_udev = dev; 612 un->un_sc = un; 613 un->un_ops = &axen_ops; 614 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 615 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 616 un->un_rx_list_cnt = AXEN_RX_LIST_CNT; 617 un->un_tx_list_cnt = AXEN_TX_LIST_CNT; 618 619 err = usbd_set_config_no(dev, AXEN_CONFIG_NO, 1); 620 if (err) { 621 aprint_error_dev(self, "failed to set configuration" 622 ", err=%s\n", usbd_errstr(err)); 623 return; 624 } 625 626 axen_flags = axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags; 627 628 err = usbd_device2interface_handle(dev, AXEN_IFACE_IDX, &un->un_iface); 629 if (err) { 630 aprint_error_dev(self, "getting interface handle failed\n"); 631 return; 632 } 633 634 /* decide on what our bufsize will be */ 635 switch (dev->ud_speed) { 636 case USB_SPEED_SUPER: 637 un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024; 638 break; 639 case USB_SPEED_HIGH: 640 un->un_rx_bufsz = AXEN_BUFSZ_HS * 1024; 641 break; 642 default: 643 un->un_rx_bufsz = AXEN_BUFSZ_LS * 1024; 644 break; 645 } 646 un->un_tx_bufsz = IP_MAXPACKET + ETHER_HDR_LEN + ETHER_CRC_LEN + 647 ETHER_VLAN_ENCAP_LEN + sizeof(struct axen_sframe_hdr); 648 649 /* Find endpoints. */ 650 id = usbd_get_interface_descriptor(un->un_iface); 651 for (i = 0; i < id->bNumEndpoints; i++) { 652 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 653 if (!ed) { 654 aprint_error_dev(self, "couldn't get ep %d\n", i); 655 return; 656 } 657 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 658 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 659 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 660 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 661 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 662 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 663 #if 0 /* not used yet */ 664 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 665 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 666 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 667 #endif 668 } 669 } 670 671 /* Set these up now for axen_cmd(). */ 672 usbnet_attach(un, "axendet"); 673 674 un->un_phyno = AXEN_PHY_ID; 675 DPRINTF(("%s: phyno %d\n", device_xname(self), un->un_phyno)); 676 677 /* Get station address. */ 678 usbnet_lock_core(un); 679 usbnet_busy(un); 680 if (axen_get_eaddr(un, &un->un_eaddr)) { 681 usbnet_unbusy(un); 682 usbnet_unlock_core(un); 683 printf("EEPROM checksum error\n"); 684 return; 685 } 686 usbnet_unbusy(un); 687 usbnet_unlock_core(un); 688 689 axen_ax88179_init(un); 690 691 /* An ASIX chip was detected. Inform the world. */ 692 if (axen_flags & AX178A) 693 aprint_normal_dev(self, "AX88178a\n"); 694 else if (axen_flags & AX179) 695 aprint_normal_dev(self, "AX88179\n"); 696 else 697 aprint_normal_dev(self, "(unknown)\n"); 698 699 struct ethercom *ec = usbnet_ec(un); 700 ec->ec_capabilities = ETHERCAP_VLAN_MTU; 701 702 /* Adapter does not support TSOv6 (They call it LSOv2). */ 703 struct ifnet *ifp = usbnet_ifp(un); 704 ifp->if_capabilities |= IFCAP_TSOv4 | 705 IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx | 706 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx | 707 IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_UDPv4_Tx | 708 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_TCPv6_Tx | 709 IFCAP_CSUM_UDPv6_Rx | IFCAP_CSUM_UDPv6_Tx; 710 711 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 712 0, &unm); 713 } 714 715 static int 716 axen_csum_flags_rx(struct ifnet *ifp, uint32_t pkt_hdr) 717 { 718 int enabled_flags = ifp->if_csum_flags_rx; 719 int csum_flags = 0; 720 int l3_type, l4_type; 721 722 if (enabled_flags == 0) 723 return 0; 724 725 l3_type = (pkt_hdr & AXEN_RXHDR_L3_TYPE_MASK) >> 726 AXEN_RXHDR_L3_TYPE_OFFSET; 727 728 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4) 729 csum_flags |= M_CSUM_IPv4; 730 731 l4_type = (pkt_hdr & AXEN_RXHDR_L4_TYPE_MASK) >> 732 AXEN_RXHDR_L4_TYPE_OFFSET; 733 734 switch (l4_type) { 735 case AXEN_RXHDR_L4_TYPE_TCP: 736 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4) 737 csum_flags |= M_CSUM_TCPv4; 738 else 739 csum_flags |= M_CSUM_TCPv6; 740 break; 741 case AXEN_RXHDR_L4_TYPE_UDP: 742 if (l3_type == AXEN_RXHDR_L3_TYPE_IPV4) 743 csum_flags |= M_CSUM_UDPv4; 744 else 745 csum_flags |= M_CSUM_UDPv6; 746 break; 747 default: 748 break; 749 } 750 751 csum_flags &= enabled_flags; 752 if ((csum_flags & M_CSUM_IPv4) && (pkt_hdr & AXEN_RXHDR_L3CSUM_ERR)) 753 csum_flags |= M_CSUM_IPv4_BAD; 754 if ((csum_flags & ~M_CSUM_IPv4) && (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) 755 csum_flags |= M_CSUM_TCP_UDP_BAD; 756 757 return csum_flags; 758 } 759 760 static void 761 axen_uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 762 { 763 struct ifnet *ifp = usbnet_ifp(un); 764 uint8_t *buf = c->unc_buf; 765 uint32_t rx_hdr, pkt_hdr; 766 uint32_t *hdr_p; 767 uint16_t hdr_offset, pkt_count; 768 size_t pkt_len; 769 size_t temp; 770 771 if (total_len < sizeof(pkt_hdr)) { 772 aprint_error_dev(un->un_dev, "rxeof: too short transfer\n"); 773 if_statinc(ifp, if_ierrors); 774 return; 775 } 776 777 /* 778 * buffer map 779 * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr] 780 * each packet has 0xeeee as psuedo header.. 781 */ 782 hdr_p = (uint32_t *)(buf + total_len - sizeof(uint32_t)); 783 rx_hdr = le32toh(*hdr_p); 784 hdr_offset = (uint16_t)(rx_hdr >> 16); 785 pkt_count = (uint16_t)(rx_hdr & 0xffff); 786 787 /* sanity check */ 788 if (hdr_offset > total_len) { 789 aprint_error_dev(un->un_dev, 790 "rxeof: invalid hdr offset (%u > %u)\n", 791 hdr_offset, total_len); 792 if_statinc(ifp, if_ierrors); 793 usbd_delay_ms(un->un_udev, 100); 794 return; 795 } 796 797 /* point first packet header */ 798 hdr_p = (uint32_t *)(buf + hdr_offset); 799 800 /* 801 * ax88179 will pack multiple ip packet to a USB transaction. 802 * process all of packets in the buffer 803 */ 804 805 #if 1 /* XXX: paranoiac check. need to remove later */ 806 #define AXEN_MAX_PACKED_PACKET 200 807 if (pkt_count > AXEN_MAX_PACKED_PACKET) { 808 DPRINTF(("%s: Too many packets (%d) in a transaction, discard.\n", 809 device_xname(un->un_dev), pkt_count)); 810 return; 811 } 812 #endif 813 814 if (pkt_count) 815 rnd_add_uint32(usbnet_rndsrc(un), pkt_count); 816 817 do { 818 if ((buf[0] != 0xee) || (buf[1] != 0xee)) { 819 aprint_error_dev(un->un_dev, 820 "invalid buffer(pkt#%d), continue\n", pkt_count); 821 if_statadd(ifp, if_ierrors, pkt_count); 822 return; 823 } 824 825 pkt_hdr = le32toh(*hdr_p); 826 pkt_len = (pkt_hdr >> 16) & 0x1fff; 827 DPRINTFN(10, 828 ("%s: rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n", 829 device_xname(un->un_dev), pkt_count, pkt_hdr, pkt_len)); 830 831 if (pkt_hdr & (AXEN_RXHDR_CRC_ERR | AXEN_RXHDR_DROP_ERR)) { 832 if_statinc(ifp, if_ierrors); 833 /* move to next pkt header */ 834 DPRINTF(("%s: %s err (pkt#%d)\n", 835 device_xname(un->un_dev), 836 (pkt_hdr & AXEN_RXHDR_CRC_ERR) ? "crc" : "drop", 837 pkt_count)); 838 goto nextpkt; 839 } 840 841 usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 6, 842 axen_csum_flags_rx(ifp, pkt_hdr), 0, 0); 843 844 nextpkt: 845 /* 846 * prepare next packet 847 * as each packet will be aligned 8byte boundary, 848 * need to fix up the start point of the buffer. 849 */ 850 temp = ((pkt_len + 7) & 0xfff8); 851 buf = buf + temp; 852 hdr_p++; 853 pkt_count--; 854 } while (pkt_count > 0); 855 } 856 857 static unsigned 858 axen_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 859 { 860 struct axen_sframe_hdr hdr; 861 u_int length, boundary; 862 863 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - sizeof(hdr)) 864 return 0; 865 length = m->m_pkthdr.len + sizeof(hdr); 866 867 /* XXX Is this needed? wMaxPacketSize? */ 868 switch (un->un_udev->ud_speed) { 869 case USB_SPEED_SUPER: 870 boundary = 4096; 871 break; 872 case USB_SPEED_HIGH: 873 boundary = 512; 874 break; 875 default: 876 boundary = 64; 877 break; 878 } 879 880 hdr.plen = htole32(m->m_pkthdr.len); 881 882 hdr.gso = (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) ? 883 m->m_pkthdr.segsz : 0; 884 if ((length % boundary) == 0) { 885 DPRINTF(("%s: boundary hit\n", device_xname(un->un_dev))); 886 hdr.gso |= 0x80008000; /* XXX enable padding */ 887 } 888 hdr.gso = htole32(hdr.gso); 889 890 memcpy(c->unc_buf, &hdr, sizeof(hdr)); 891 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + sizeof(hdr)); 892 893 return length; 894 } 895 896 static int 897 axen_init_locked(struct ifnet *ifp) 898 { 899 struct usbnet * const un = ifp->if_softc; 900 uint16_t rxmode; 901 uint16_t wval; 902 uint8_t bval; 903 904 usbnet_isowned_core(un); 905 906 if (usbnet_isdying(un)) 907 return EIO; 908 909 /* Cancel pending I/O */ 910 usbnet_stop(un, ifp, 1); 911 912 /* Reset the ethernet interface. */ 913 axen_reset(un); 914 915 /* XXX: ? */ 916 bval = 0x01; 917 axen_cmd(un, AXEN_CMD_MAC_WRITE, 1, AXEN_UNK_28, &bval); 918 919 /* Configure offloading engine. */ 920 axen_setoe_locked(un); 921 922 /* Program promiscuous mode and multicast filters. */ 923 axen_setiff_locked(un); 924 925 /* Enable receiver, set RX mode */ 926 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 927 rxmode = le16toh(wval); 928 rxmode |= AXEN_RXCTL_START; 929 wval = htole16(rxmode); 930 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 931 932 return usbnet_init_rx_tx(un); 933 } 934 935 static int 936 axen_uno_init(struct ifnet *ifp) 937 { 938 struct usbnet * const un = ifp->if_softc; 939 940 usbnet_lock_core(un); 941 usbnet_busy(un); 942 int ret = axen_init_locked(ifp); 943 usbnet_unbusy(un); 944 usbnet_unlock_core(un); 945 946 return ret; 947 } 948 949 static void 950 axen_uno_stop(struct ifnet *ifp, int disable) 951 { 952 struct usbnet * const un = ifp->if_softc; 953 uint16_t rxmode, wval; 954 955 axen_reset(un); 956 957 /* Disable receiver, set RX mode */ 958 axen_cmd(un, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 959 rxmode = le16toh(wval); 960 rxmode &= ~AXEN_RXCTL_START; 961 wval = htole16(rxmode); 962 axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 963 } 964 965 #ifdef _MODULE 966 #include "ioconf.c" 967 #endif 968 969 USBNET_MODULE(axen) 970