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