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