1 /* $OpenBSD: if_axen.c,v 1.34 2024/10/07 07:35:40 kevlo Exp $ */ 2 3 /* 4 * Copyright (c) 2013 Yojiro UO <yuo@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * ASIX Electronics AX88178a/AX88772d USB 2.0 ethernet and 21 * AX88179/AX88179a USB 3.0 Ethernet driver. 22 */ 23 24 #include "bpfilter.h" 25 26 #include <sys/param.h> 27 #include <sys/systm.h> 28 #include <sys/sockio.h> 29 #include <sys/rwlock.h> 30 #include <sys/mbuf.h> 31 32 #include <sys/device.h> 33 34 #include <machine/bus.h> 35 36 #include <net/if.h> 37 #include <net/if_media.h> 38 39 #if NBPFILTER > 0 40 #include <net/bpf.h> 41 #endif 42 43 #include <netinet/in.h> 44 #include <netinet/if_ether.h> 45 46 #include <dev/mii/mii.h> 47 #include <dev/mii/miivar.h> 48 49 #include <dev/usb/usb.h> 50 #include <dev/usb/usbdi.h> 51 #include <dev/usb/usbdi_util.h> 52 #include <dev/usb/usbdivar.h> 53 #include <dev/usb/usbdevs.h> 54 55 #include <dev/usb/if_axenreg.h> 56 57 #ifdef AXEN_DEBUG 58 #define DPRINTF(x) do { if (axendebug) printf x; } while (0) 59 #define DPRINTFN(n,x) do { if (axendebug >= (n)) printf x; } while (0) 60 int axendebug = 0; 61 #else 62 #define DPRINTF(x) 63 #define DPRINTFN(n,x) 64 #endif 65 66 #define AXEN_TOE /* enable checksum offload function */ 67 68 /* 69 * Various supported device vendors/products. 70 */ 71 const struct axen_type axen_devs[] = { 72 #if 0 /* not tested */ 73 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178A}, AX178A }, 74 #endif 75 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88179}, AX179 }, 76 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUB1312}, AX179 }, 77 { { USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_AX88179}, AX179 }, 78 { { USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_AX88179}, AX179 }, 79 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN032}, AX179 } 80 }; 81 82 #define axen_lookup(v, p) ((struct axen_type *)usb_lookup(axen_devs, v, p)) 83 84 int axen_match(struct device *, void *, void *); 85 void axen_attach(struct device *, struct device *, void *); 86 int axen_detach(struct device *, int); 87 88 struct cfdriver axen_cd = { 89 NULL, "axen", DV_IFNET 90 }; 91 92 const struct cfattach axen_ca = { 93 sizeof(struct axen_softc), axen_match, axen_attach, axen_detach 94 }; 95 96 int axen_tx_list_init(struct axen_softc *); 97 int axen_rx_list_init(struct axen_softc *); 98 struct mbuf *axen_newbuf(void); 99 int axen_encap(struct axen_softc *, struct mbuf *, int); 100 void axen_rxeof(struct usbd_xfer *, void *, usbd_status); 101 void axen_txeof(struct usbd_xfer *, void *, usbd_status); 102 void axen_tick(void *); 103 void axen_tick_task(void *); 104 void axen_start(struct ifnet *); 105 int axen_ioctl(struct ifnet *, u_long, caddr_t); 106 void axen_init(void *); 107 void axen_stop(struct axen_softc *); 108 void axen_watchdog(struct ifnet *); 109 int axen_miibus_readreg(struct device *, int, int); 110 void axen_miibus_writereg(struct device *, int, int, int); 111 void axen_miibus_statchg(struct device *); 112 int axen_cmd(struct axen_softc *, int, int, int, void *); 113 int axen_ifmedia_upd(struct ifnet *); 114 void axen_ifmedia_sts(struct ifnet *, struct ifmediareq *); 115 void axen_reset(struct axen_softc *sc); 116 void axen_iff(struct axen_softc *); 117 void axen_lock_mii(struct axen_softc *sc); 118 void axen_unlock_mii(struct axen_softc *sc); 119 120 void axen_ax88179_init(struct axen_softc *); 121 122 /* Get exclusive access to the MII registers */ 123 void 124 axen_lock_mii(struct axen_softc *sc) 125 { 126 sc->axen_refcnt++; 127 rw_enter_write(&sc->axen_mii_lock); 128 } 129 130 void 131 axen_unlock_mii(struct axen_softc *sc) 132 { 133 rw_exit_write(&sc->axen_mii_lock); 134 if (--sc->axen_refcnt < 0) 135 usb_detach_wakeup(&sc->axen_dev); 136 } 137 138 int 139 axen_cmd(struct axen_softc *sc, int cmd, int index, int val, void *buf) 140 { 141 usb_device_request_t req; 142 usbd_status err; 143 144 if (usbd_is_dying(sc->axen_udev)) 145 return 0; 146 147 if (AXEN_CMD_DIR(cmd)) 148 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 149 else 150 req.bmRequestType = UT_READ_VENDOR_DEVICE; 151 req.bRequest = AXEN_CMD_CMD(cmd); 152 USETW(req.wValue, val); 153 USETW(req.wIndex, index); 154 USETW(req.wLength, AXEN_CMD_LEN(cmd)); 155 156 err = usbd_do_request(sc->axen_udev, &req, buf); 157 DPRINTFN(5, ("axen_cmd: cmd 0x%04x val 0x%04x len %d\n", 158 cmd, val, AXEN_CMD_LEN(cmd))); 159 160 if (err) { 161 DPRINTF(("axen_cmd err: cmd: %d, error: %d\n", cmd, err)); 162 return -1; 163 } 164 165 return 0; 166 } 167 168 int 169 axen_miibus_readreg(struct device *dev, int phy, int reg) 170 { 171 struct axen_softc *sc = (void *)dev; 172 int err; 173 uWord val; 174 int ival; 175 176 if (usbd_is_dying(sc->axen_udev)) { 177 DPRINTF(("axen: dying\n")); 178 return 0; 179 } 180 181 if (sc->axen_phyno != phy) 182 return 0; 183 184 axen_lock_mii(sc); 185 err = axen_cmd(sc, AXEN_CMD_MII_READ_REG, reg, phy, &val); 186 axen_unlock_mii(sc); 187 188 if (err) { 189 printf("axen%d: read PHY failed\n", sc->axen_unit); 190 return -1; 191 } 192 193 ival = UGETW(val); 194 DPRINTFN(2,("axen_miibus_readreg: phy 0x%x reg 0x%x val 0x%x\n", 195 phy, reg, ival)); 196 197 if (reg == MII_BMSR) { 198 ival &= ~BMSR_EXTCAP; 199 } 200 201 return ival; 202 } 203 204 void 205 axen_miibus_writereg(struct device *dev, int phy, int reg, int val) 206 { 207 struct axen_softc *sc = (void *)dev; 208 int err; 209 uWord uval; 210 211 if (usbd_is_dying(sc->axen_udev)) 212 return; 213 214 if (sc->axen_phyno != phy) 215 return; 216 217 USETW(uval, val); 218 axen_lock_mii(sc); 219 err = axen_cmd(sc, AXEN_CMD_MII_WRITE_REG, reg, phy, &uval); 220 axen_unlock_mii(sc); 221 DPRINTFN(2, ("axen_miibus_writereg: phy 0x%x reg 0x%x val 0x%0x\n", 222 phy, reg, val)); 223 224 if (err) { 225 printf("axen%d: write PHY failed\n", sc->axen_unit); 226 return; 227 } 228 } 229 230 void 231 axen_miibus_statchg(struct device *dev) 232 { 233 struct axen_softc *sc = (void *)dev; 234 struct mii_data *mii = GET_MII(sc); 235 struct ifnet *ifp; 236 int err; 237 uint16_t val; 238 uWord wval; 239 240 ifp = GET_IFP(sc); 241 if (mii == NULL || ifp == NULL || 242 (ifp->if_flags & IFF_RUNNING) == 0) 243 return; 244 245 sc->axen_link = 0; 246 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 247 (IFM_ACTIVE | IFM_AVALID)) { 248 switch (IFM_SUBTYPE(mii->mii_media_active)) { 249 case IFM_10_T: 250 case IFM_100_TX: 251 sc->axen_link++; 252 break; 253 case IFM_1000_T: 254 if ((sc->axen_flags & AX772D) != 0) 255 break; 256 sc->axen_link++; 257 break; 258 default: 259 break; 260 } 261 } 262 263 /* Lost link, do nothing. */ 264 if (sc->axen_link == 0) 265 return; 266 267 val = 0; 268 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) 269 val |= AXEN_MEDIUM_FDX; 270 271 val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE); 272 val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN); 273 274 switch (IFM_SUBTYPE(mii->mii_media_active)) { 275 case IFM_1000_T: 276 val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ; 277 break; 278 case IFM_100_TX: 279 val |= AXEN_MEDIUM_PS; 280 break; 281 case IFM_10_T: 282 /* doesn't need to be handled */ 283 break; 284 } 285 286 DPRINTF(("axen_miibus_statchg: val=0x%x\n", val)); 287 USETW(wval, val); 288 axen_lock_mii(sc); 289 err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); 290 axen_unlock_mii(sc); 291 if (err) { 292 printf("%s: media change failed\n", sc->axen_dev.dv_xname); 293 return; 294 } 295 } 296 297 /* 298 * Set media options. 299 */ 300 int 301 axen_ifmedia_upd(struct ifnet *ifp) 302 { 303 struct axen_softc *sc = ifp->if_softc; 304 struct mii_data *mii = GET_MII(sc); 305 int err; 306 307 sc->axen_link = 0; 308 309 if (mii->mii_instance) { 310 struct mii_softc *miisc; 311 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) 312 mii_phy_reset(miisc); 313 } 314 315 err = mii_mediachg(mii); 316 if (err == ENXIO) 317 return 0; 318 else 319 return err; 320 } 321 322 /* 323 * Report current media status. 324 */ 325 void 326 axen_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 327 { 328 struct axen_softc *sc = ifp->if_softc; 329 struct mii_data *mii = GET_MII(sc); 330 331 mii_pollstat(mii); 332 ifmr->ifm_active = mii->mii_media_active; 333 ifmr->ifm_status = mii->mii_media_status; 334 } 335 336 void 337 axen_iff(struct axen_softc *sc) 338 { 339 struct ifnet *ifp = GET_IFP(sc); 340 struct arpcom *ac = &sc->arpcom; 341 struct ether_multi *enm; 342 struct ether_multistep step; 343 u_int32_t h = 0; 344 u_int16_t rxmode; 345 u_int8_t hashtbl[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 346 uWord wval; 347 348 if (usbd_is_dying(sc->axen_udev)) 349 return; 350 351 rxmode = 0; 352 353 /* Enable receiver, set RX mode */ 354 axen_lock_mii(sc); 355 axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 356 rxmode = UGETW(wval); 357 rxmode &= ~(AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_ACPT_PHY_MCAST | 358 AXEN_RXCTL_PROMISC); 359 ifp->if_flags &= ~IFF_ALLMULTI; 360 361 /* 362 * Always accept broadcast frames. 363 * Always accept frames destined to our station address. 364 */ 365 rxmode |= AXEN_RXCTL_ACPT_BCAST; 366 367 if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { 368 ifp->if_flags |= IFF_ALLMULTI; 369 rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_ACPT_PHY_MCAST; 370 if (ifp->if_flags & IFF_PROMISC) 371 rxmode |= AXEN_RXCTL_PROMISC; 372 } else { 373 rxmode |= AXEN_RXCTL_ACPT_ALL_MCAST | AXEN_RXCTL_ACPT_PHY_MCAST; 374 375 /* now program new ones */ 376 ETHER_FIRST_MULTI(step, ac, enm); 377 while (enm != NULL) { 378 h = ether_crc32_be(enm->enm_addrlo, 379 ETHER_ADDR_LEN) >> 26; 380 hashtbl[h / 8] |= 1 << (h % 8); 381 ETHER_NEXT_MULTI(step, enm); 382 } 383 } 384 385 axen_cmd(sc, AXEN_CMD_MAC_WRITE_FILTER, 8, AXEN_FILTER_MULTI, 386 (void *)&hashtbl); 387 USETW(wval, rxmode); 388 axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 389 axen_unlock_mii(sc); 390 } 391 392 void 393 axen_reset(struct axen_softc *sc) 394 { 395 if (usbd_is_dying(sc->axen_udev)) 396 return; 397 398 axen_ax88179_init(sc); 399 400 /* Wait a little while for the chip to get its brains in order. */ 401 DELAY(1000); 402 return; 403 } 404 405 void 406 axen_ax88179_init(struct axen_softc *sc) 407 { 408 uWord wval; 409 uByte val; 410 u_int16_t ctl, temp; 411 struct axen_qctrl qctrl; 412 413 axen_lock_mii(sc); 414 415 /* XXX: ? */ 416 axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_UNK_05, &val); 417 DPRINTFN(5, ("AXEN_CMD_MAC_READ(0x05): 0x%02x\n", val)); 418 419 /* check AX88179 version, UA1 / UA2 */ 420 axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_GENERAL_STATUS, &val); 421 /* UA1 */ 422 if (!(val & AXEN_GENERAL_STATUS_MASK)) { 423 sc->axen_rev = AXEN_REV_UA1; 424 DPRINTF(("AX88179 ver. UA1\n")); 425 } else { 426 sc->axen_rev = AXEN_REV_UA2; 427 DPRINTF(("AX88179 ver. UA2\n")); 428 } 429 430 /* power up ethernet PHY */ 431 USETW(wval, 0); 432 axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 433 434 USETW(wval, AXEN_PHYPWR_RSTCTL_IPRL); 435 axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 436 usbd_delay_ms(sc->axen_udev, 200); 437 438 /* set clock mode */ 439 val = AXEN_PHYCLK_ACS | AXEN_PHYCLK_BCS; 440 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 441 usbd_delay_ms(sc->axen_udev, 100); 442 443 /* set monitor mode (disable) */ 444 val = AXEN_MONITOR_NONE; 445 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val); 446 447 /* enable auto detach */ 448 axen_cmd(sc, AXEN_CMD_EEPROM_READ, 2, AXEN_EEPROM_STAT, &wval); 449 temp = UGETW(wval); 450 DPRINTFN(2,("EEPROM0x43 = 0x%04x\n", temp)); 451 if (!(temp == 0xffff) && !(temp & 0x0100)) { 452 /* Enable auto detach bit */ 453 val = 0; 454 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 455 val = AXEN_PHYCLK_ULR; 456 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_PHYCLK, &val); 457 usbd_delay_ms(sc->axen_udev, 100); 458 459 axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_PHYPWR_RSTCTL, &wval); 460 ctl = UGETW(wval); 461 ctl |= AXEN_PHYPWR_RSTCTL_AUTODETACH; 462 USETW(wval, ctl); 463 axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_PHYPWR_RSTCTL, &wval); 464 usbd_delay_ms(sc->axen_udev, 200); 465 printf("%s: enable auto detach (0x%04x)\n", 466 sc->axen_dev.dv_xname, ctl); 467 } 468 469 /* bulkin queue setting */ 470 axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &val); 471 switch (val) { 472 case AXEN_USB_FS: 473 DPRINTF(("uplink: USB1.1\n")); 474 qctrl.ctrl = 0x07; 475 qctrl.timer_low = 0xcc; 476 qctrl.timer_high= 0x4c; 477 qctrl.bufsize = AXEN_BUFSZ_LS - 1; 478 qctrl.ifg = 0x08; 479 break; 480 case AXEN_USB_HS: 481 DPRINTF(("uplink: USB2.0\n")); 482 qctrl.ctrl = 0x07; 483 qctrl.timer_low = 0x02; 484 qctrl.timer_high= 0xa0; 485 qctrl.bufsize = AXEN_BUFSZ_HS - 1; 486 qctrl.ifg = 0xff; 487 break; 488 case AXEN_USB_SS: 489 DPRINTF(("uplink: USB3.0\n")); 490 qctrl.ctrl = 0x07; 491 qctrl.timer_low = 0x4f; 492 qctrl.timer_high= 0x00; 493 qctrl.bufsize = AXEN_BUFSZ_SS - 1; 494 qctrl.ifg = 0xff; 495 break; 496 default: 497 printf("%s: unknown uplink bus:0x%02x\n", 498 sc->axen_dev.dv_xname, val); 499 axen_unlock_mii(sc); 500 return; 501 } 502 axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl); 503 504 /* Set MAC address. */ 505 axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN, 506 AXEN_CMD_MAC_NODE_ID, &sc->arpcom.ac_enaddr); 507 508 /* 509 * set buffer high/low watermark to pause/resume. 510 * write 2byte will set high/log simultaneous with AXEN_PAUSE_HIGH. 511 * XXX: what is the best value? OSX driver uses 0x3c-0x4c as LOW-HIGH 512 * watermark parameters. 513 */ 514 val = 0x34; 515 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_LOW_WATERMARK, &val); 516 val = 0x52; 517 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_PAUSE_HIGH_WATERMARK, &val); 518 519 /* Set RX/TX configuration. */ 520 /* Offloading enable */ 521 #ifdef AXEN_TOE 522 val = AXEN_RXCOE_IPv4 | AXEN_RXCOE_TCPv4 | AXEN_RXCOE_UDPv4 | 523 AXEN_RXCOE_TCPv6 | AXEN_RXCOE_UDPv6; 524 #else 525 val = AXEN_RXCOE_OFF; 526 #endif 527 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_RX_COE, &val); 528 529 #ifdef AXEN_TOE 530 val = AXEN_TXCOE_IPv4 | AXEN_TXCOE_TCPv4 | AXEN_TXCOE_UDPv4 | 531 AXEN_TXCOE_TCPv6 | AXEN_TXCOE_UDPv6; 532 #else 533 val = AXEN_TXCOE_OFF; 534 #endif 535 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_TX_COE, &val); 536 537 /* Set RX control register */ 538 ctl = AXEN_RXCTL_IPE | AXEN_RXCTL_DROPCRCERR | AXEN_RXCTL_AUTOB; 539 ctl |= AXEN_RXCTL_ACPT_PHY_MCAST | AXEN_RXCTL_ACPT_ALL_MCAST; 540 ctl |= AXEN_RXCTL_START; 541 USETW(wval, ctl); 542 axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 543 544 /* set monitor mode (enable) */ 545 val = AXEN_MONITOR_PMETYPE | AXEN_MONITOR_PMEPOL | AXEN_MONITOR_RWMP; 546 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_MONITOR_MODE, &val); 547 axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_MONITOR_MODE, &val); 548 DPRINTF(("axen: Monitor mode = 0x%02x\n", val)); 549 550 /* set medium type */ 551 ctl = AXEN_MEDIUM_GIGA | AXEN_MEDIUM_FDX | AXEN_MEDIUM_ALWAYS_ONE | 552 AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN; 553 ctl |= AXEN_MEDIUM_RECV_EN; 554 USETW(wval, ctl); 555 DPRINTF(("axen: set to medium mode: 0x%04x\n", UGETW(wval))); 556 axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); 557 usbd_delay_ms(sc->axen_udev, 100); 558 559 axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_MEDIUM_STATUS, &wval); 560 DPRINTF(("axen: current medium mode: 0x%04x\n", UGETW(wval))); 561 axen_unlock_mii(sc); 562 563 #if 0 /* XXX: TBD.... */ 564 #define GMII_LED_ACTIVE 0x1a 565 #define GMII_PHY_PAGE_SEL 0x1e 566 #define GMII_PHY_PAGE_SEL 0x1f 567 #define GMII_PAGE_EXT 0x0007 568 axen_miibus_writereg(&sc->axen_dev, sc->axen_phyno, GMII_PHY_PAGE_SEL, 569 GMII_PAGE_EXT); 570 axen_miibus_writereg(&sc->axen_dev, sc->axen_phyno, GMII_PHY_PAGE, 571 0x002c); 572 #endif 573 574 #if 1 /* XXX: phy hack ? */ 575 axen_miibus_writereg(&sc->axen_dev, sc->axen_phyno, 0x1F, 0x0005); 576 axen_miibus_writereg(&sc->axen_dev, sc->axen_phyno, 0x0C, 0x0000); 577 val = axen_miibus_readreg(&sc->axen_dev, sc->axen_phyno, 0x0001); 578 axen_miibus_writereg(&sc->axen_dev, sc->axen_phyno, 0x01, 579 val | 0x0080); 580 axen_miibus_writereg(&sc->axen_dev, sc->axen_phyno, 0x1F, 0x0000); 581 #endif 582 } 583 584 int 585 axen_match(struct device *parent, void *match, void *aux) 586 { 587 struct usb_attach_arg *uaa = aux; 588 589 if (uaa->iface == NULL || uaa->configno != 1) 590 return (UMATCH_NONE); 591 592 return (axen_lookup(uaa->vendor, uaa->product) != NULL ? 593 UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE); 594 } 595 596 void 597 axen_attach(struct device *parent, struct device *self, void *aux) 598 { 599 struct axen_softc *sc = (struct axen_softc *)self; 600 struct usb_attach_arg *uaa = aux; 601 usb_interface_descriptor_t *id; 602 usb_endpoint_descriptor_t *ed; 603 usb_device_descriptor_t *dd; 604 struct mii_data *mii; 605 u_char eaddr[ETHER_ADDR_LEN]; 606 char *devname = sc->axen_dev.dv_xname; 607 struct ifnet *ifp; 608 int i, s; 609 610 sc->axen_unit = self->dv_unit; /*device_get_unit(self);*/ 611 sc->axen_udev = uaa->device; 612 sc->axen_iface = uaa->iface; 613 sc->axen_flags = axen_lookup(uaa->vendor, uaa->product)->axen_flags; 614 615 usb_init_task(&sc->axen_tick_task, axen_tick_task, sc, 616 USB_TASK_TYPE_GENERIC); 617 rw_init(&sc->axen_mii_lock, "axenmii"); 618 usb_init_task(&sc->axen_stop_task, (void (*)(void *))axen_stop, sc, 619 USB_TASK_TYPE_GENERIC); 620 621 sc->axen_product = uaa->product; 622 sc->axen_vendor = uaa->vendor; 623 624 id = usbd_get_interface_descriptor(sc->axen_iface); 625 626 /* decide on what our bufsize will be */ 627 switch (sc->axen_udev->speed) { 628 case USB_SPEED_FULL: 629 sc->axen_bufsz = AXEN_BUFSZ_LS * 1024; 630 break; 631 case USB_SPEED_HIGH: 632 sc->axen_bufsz = AXEN_BUFSZ_HS * 1024; 633 break; 634 case USB_SPEED_SUPER: 635 sc->axen_bufsz = AXEN_BUFSZ_SS * 1024; 636 break; 637 default: 638 printf("%s: not supported usb bus type", sc->axen_dev.dv_xname); 639 return; 640 } 641 642 /* Find endpoints. */ 643 for (i = 0; i < id->bNumEndpoints; i++) { 644 ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i); 645 if (!ed) { 646 printf("%s: couldn't get ep %d\n", 647 sc->axen_dev.dv_xname, i); 648 return; 649 } 650 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 651 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 652 sc->axen_ed[AXEN_ENDPT_RX] = ed->bEndpointAddress; 653 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 654 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 655 sc->axen_ed[AXEN_ENDPT_TX] = ed->bEndpointAddress; 656 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 657 UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { 658 sc->axen_ed[AXEN_ENDPT_INTR] = ed->bEndpointAddress; 659 } 660 } 661 662 dd = usbd_get_device_descriptor(sc->axen_udev); 663 switch (UGETW(dd->bcdDevice)) { 664 case 0x200: 665 sc->axen_flags = AX179A; 666 break; 667 case 0x300: 668 sc->axen_flags = AX772D; 669 break; 670 } 671 672 s = splnet(); 673 674 sc->axen_phyno = AXEN_PHY_ID; 675 DPRINTF((" get_phyno %d\n", sc->axen_phyno)); 676 677 /* 678 * Get station address. 679 */ 680 /* use MAC command */ 681 axen_lock_mii(sc); 682 axen_cmd(sc, AXEN_CMD_MAC_READ_ETHER, ETHER_ADDR_LEN, 683 AXEN_CMD_MAC_NODE_ID, &eaddr); 684 axen_unlock_mii(sc); 685 686 /* 687 * An ASIX chip was detected. Inform the world. 688 */ 689 printf("%s:", sc->axen_dev.dv_xname); 690 if (sc->axen_flags & AX178A) 691 printf(" AX88178a"); 692 else if (sc->axen_flags & AX179) 693 printf(" AX88179"); 694 else if (sc->axen_flags & AX772D) 695 printf(" AX88772D"); 696 else 697 printf(" AX88179A"); 698 printf(", address %s\n", ether_sprintf(eaddr)); 699 700 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 701 702 axen_ax88179_init(sc); 703 704 /* Initialize interface info. */ 705 ifp = &sc->arpcom.ac_if; 706 ifp->if_softc = sc; 707 strlcpy(ifp->if_xname, devname, IFNAMSIZ); 708 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 709 ifp->if_ioctl = axen_ioctl; 710 ifp->if_start = axen_start; 711 ifp->if_watchdog = axen_watchdog; 712 713 ifp->if_capabilities = IFCAP_VLAN_MTU; 714 #ifdef AXEN_TOE 715 ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | 716 IFCAP_CSUM_UDPv4 | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6; 717 #endif 718 719 /* Initialize MII/media info. */ 720 mii = &sc->axen_mii; 721 mii->mii_ifp = ifp; 722 mii->mii_readreg = axen_miibus_readreg; 723 mii->mii_writereg = axen_miibus_writereg; 724 mii->mii_statchg = axen_miibus_statchg; 725 mii->mii_flags = MIIF_AUTOTSLEEP; 726 727 ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts); 728 mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); 729 730 if (LIST_FIRST(&mii->mii_phys) == NULL) { 731 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); 732 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); 733 } else 734 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 735 736 /* Attach the interface. */ 737 if_attach(ifp); 738 ether_ifattach(ifp); 739 740 timeout_set(&sc->axen_stat_ch, axen_tick, sc); 741 742 splx(s); 743 } 744 745 int 746 axen_detach(struct device *self, int flags) 747 { 748 struct axen_softc *sc = (struct axen_softc *)self; 749 int s; 750 struct ifnet *ifp = GET_IFP(sc); 751 752 DPRINTFN(2,("%s: %s: enter\n", sc->axen_dev.dv_xname, __func__)); 753 754 if (timeout_initialized(&sc->axen_stat_ch)) 755 timeout_del(&sc->axen_stat_ch); 756 757 if (sc->axen_ep[AXEN_ENDPT_TX] != NULL) 758 usbd_abort_pipe(sc->axen_ep[AXEN_ENDPT_TX]); 759 if (sc->axen_ep[AXEN_ENDPT_RX] != NULL) 760 usbd_abort_pipe(sc->axen_ep[AXEN_ENDPT_RX]); 761 if (sc->axen_ep[AXEN_ENDPT_INTR] != NULL) 762 usbd_abort_pipe(sc->axen_ep[AXEN_ENDPT_INTR]); 763 764 /* 765 * Remove any pending tasks. They cannot be executing because they run 766 * in the same thread as detach. 767 */ 768 usb_rem_task(sc->axen_udev, &sc->axen_tick_task); 769 usb_rem_task(sc->axen_udev, &sc->axen_stop_task); 770 771 s = splusb(); 772 773 if (--sc->axen_refcnt >= 0) { 774 /* Wait for processes to go away */ 775 usb_detach_wait(&sc->axen_dev); 776 } 777 778 if (ifp->if_flags & IFF_RUNNING) 779 axen_stop(sc); 780 781 mii_detach(&sc->axen_mii, MII_PHY_ANY, MII_OFFSET_ANY); 782 ifmedia_delete_instance(&sc->axen_mii.mii_media, IFM_INST_ANY); 783 if (ifp->if_softc != NULL) { 784 ether_ifdetach(ifp); 785 if_detach(ifp); 786 } 787 788 #ifdef DIAGNOSTIC 789 if (sc->axen_ep[AXEN_ENDPT_TX] != NULL || 790 sc->axen_ep[AXEN_ENDPT_RX] != NULL || 791 sc->axen_ep[AXEN_ENDPT_INTR] != NULL) 792 printf("%s: detach has active endpoints\n", 793 sc->axen_dev.dv_xname); 794 #endif 795 796 splx(s); 797 798 return 0; 799 } 800 801 struct mbuf * 802 axen_newbuf(void) 803 { 804 struct mbuf *m; 805 806 MGETHDR(m, M_DONTWAIT, MT_DATA); 807 if (m == NULL) 808 return NULL; 809 810 MCLGET(m, M_DONTWAIT); 811 if (!(m->m_flags & M_EXT)) { 812 m_freem(m); 813 return NULL; 814 } 815 816 m->m_len = m->m_pkthdr.len = MCLBYTES; 817 m_adj(m, ETHER_ALIGN); 818 819 return m; 820 } 821 822 int 823 axen_rx_list_init(struct axen_softc *sc) 824 { 825 struct axen_cdata *cd; 826 struct axen_chain *c; 827 int i; 828 829 DPRINTF(("%s: %s: enter\n", sc->axen_dev.dv_xname, __func__)); 830 831 cd = &sc->axen_cdata; 832 for (i = 0; i < AXEN_RX_LIST_CNT; i++) { 833 c = &cd->axen_rx_chain[i]; 834 c->axen_sc = sc; 835 c->axen_idx = i; 836 c->axen_mbuf = NULL; 837 if (c->axen_xfer == NULL) { 838 c->axen_xfer = usbd_alloc_xfer(sc->axen_udev); 839 if (c->axen_xfer == NULL) 840 return ENOBUFS; 841 c->axen_buf = usbd_alloc_buffer(c->axen_xfer, 842 sc->axen_bufsz); 843 if (c->axen_buf == NULL) { 844 usbd_free_xfer(c->axen_xfer); 845 return ENOBUFS; 846 } 847 } 848 } 849 850 return 0; 851 } 852 853 int 854 axen_tx_list_init(struct axen_softc *sc) 855 { 856 struct axen_cdata *cd; 857 struct axen_chain *c; 858 int i; 859 860 DPRINTF(("%s: %s: enter\n", sc->axen_dev.dv_xname, __func__)); 861 862 cd = &sc->axen_cdata; 863 for (i = 0; i < AXEN_TX_LIST_CNT; i++) { 864 c = &cd->axen_tx_chain[i]; 865 c->axen_sc = sc; 866 c->axen_idx = i; 867 c->axen_mbuf = NULL; 868 if (c->axen_xfer == NULL) { 869 c->axen_xfer = usbd_alloc_xfer(sc->axen_udev); 870 if (c->axen_xfer == NULL) 871 return ENOBUFS; 872 c->axen_buf = usbd_alloc_buffer(c->axen_xfer, 873 sc->axen_bufsz); 874 if (c->axen_buf == NULL) { 875 usbd_free_xfer(c->axen_xfer); 876 return ENOBUFS; 877 } 878 } 879 } 880 881 return 0; 882 } 883 884 /* 885 * A frame has been uploaded: pass the resulting mbuf chain up to 886 * the higher level protocols. 887 */ 888 void 889 axen_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 890 { 891 struct axen_chain *c = (struct axen_chain *)priv; 892 struct axen_softc *sc = c->axen_sc; 893 struct ifnet *ifp = GET_IFP(sc); 894 u_char *buf = c->axen_buf; 895 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 896 struct mbuf *m; 897 u_int32_t total_len; 898 u_int32_t rx_hdr, pkt_hdr; 899 u_int32_t *hdr_p; 900 u_int16_t hdr_offset, pkt_count; 901 size_t pkt_len; 902 size_t temp; 903 int padlen, s; 904 905 DPRINTFN(10,("%s: %s: enter\n", sc->axen_dev.dv_xname,__func__)); 906 907 if (usbd_is_dying(sc->axen_udev)) 908 return; 909 910 if (!(ifp->if_flags & IFF_RUNNING)) 911 return; 912 913 if (status != USBD_NORMAL_COMPLETION) { 914 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 915 return; 916 if (usbd_ratecheck(&sc->axen_rx_notice)) { 917 printf("%s: usb errors on rx: %s\n", 918 sc->axen_dev.dv_xname, usbd_errstr(status)); 919 } 920 if (status == USBD_STALLED) 921 usbd_clear_endpoint_stall_async(sc->axen_ep[AXEN_ENDPT_RX]); 922 goto done; 923 } 924 925 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 926 927 if (total_len < sizeof(pkt_hdr)) { 928 ifp->if_ierrors++; 929 goto done; 930 } 931 932 /* 933 * buffer map 934 * 935 * for ax88179 936 * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr] 937 * 938 * for ax88179a 939 * [packet #0]...[packet #n][pkt hdr#0][dummy_hdr].. 940 * [pkt hdr#n][dummy_hdr][recv_hdr] 941 * 942 * each packet has 0xeeee as pseudo header.. 943 */ 944 hdr_p = (u_int32_t *)(buf + total_len - sizeof(u_int32_t)); 945 rx_hdr = letoh32(*hdr_p); 946 hdr_offset = (u_int16_t)(rx_hdr >> 16); 947 pkt_count = (u_int16_t)(rx_hdr & 0xffff); 948 949 if (total_len > sc->axen_bufsz) { 950 printf("%s: rxeof: too large transfer\n", 951 sc->axen_dev.dv_xname); 952 goto done; 953 } 954 955 /* sanity check */ 956 if (hdr_offset > total_len) { 957 ifp->if_ierrors++; 958 goto done; 959 } 960 961 /* point first packet header */ 962 hdr_p = (u_int32_t*)(buf + hdr_offset); 963 964 /* 965 * ax88179 will pack multiple ip packet to a USB transaction. 966 * process all of packets in the buffer 967 */ 968 969 #if 1 /* XXX: paranoiac check. need to remove later */ 970 #define AXEN_MAX_PACKED_PACKET 200 971 if (pkt_count > AXEN_MAX_PACKED_PACKET) { 972 DPRINTF(("Too many packets (%d) in a transaction, discard.\n", 973 pkt_count)); 974 goto done; 975 } 976 #endif 977 978 /* skip pseudo header (2byte) */ 979 padlen = 2; 980 /* skip trailer padding (4Byte) for ax88179 */ 981 if (!(sc->axen_flags & (AX179A | AX772D))) 982 padlen += 4; 983 984 do { 985 pkt_hdr = letoh32(*hdr_p); 986 pkt_len = (pkt_hdr >> 16) & 0x1fff; 987 988 DPRINTFN(10,("rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n", 989 pkt_count, pkt_hdr, pkt_len)); 990 991 /* skip dummy packet header */ 992 if (pkt_len == 0) 993 goto nextpkt; 994 995 if ((buf[0] != 0xee) || (buf[1] != 0xee)){ 996 printf("%s: invalid buffer(pkt#%d), continue\n", 997 sc->axen_dev.dv_xname, pkt_count); 998 ifp->if_ierrors += pkt_count; 999 goto done; 1000 } 1001 1002 if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) || 1003 (pkt_hdr & AXEN_RXHDR_DROP_ERR)) { 1004 ifp->if_ierrors++; 1005 /* move to next pkt header */ 1006 DPRINTF(("crc err(pkt#%d)\n", pkt_count)); 1007 goto nextpkt; 1008 } 1009 1010 /* process each packet */ 1011 /* allocate mbuf */ 1012 m = axen_newbuf(); 1013 if (m == NULL) { 1014 ifp->if_ierrors++; 1015 goto nextpkt; 1016 } 1017 1018 m->m_pkthdr.len = m->m_len = pkt_len - padlen; 1019 1020 #ifdef AXEN_TOE 1021 /* checksum err */ 1022 if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) || 1023 (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) { 1024 printf("%s: checksum err (pkt#%d)\n", 1025 sc->axen_dev.dv_xname, pkt_count); 1026 goto nextpkt; 1027 } else { 1028 m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK; 1029 } 1030 1031 int l4_type; 1032 l4_type = (pkt_hdr & AXEN_RXHDR_L4_TYPE_MASK) >> 1033 AXEN_RXHDR_L4_TYPE_OFFSET; 1034 1035 if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) || 1036 (l4_type == AXEN_RXHDR_L4_TYPE_UDP)) 1037 m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK | 1038 M_UDP_CSUM_IN_OK; 1039 #endif 1040 1041 memcpy(mtod(m, char *), buf + 2, pkt_len - padlen); 1042 1043 ml_enqueue(&ml, m); 1044 1045 nextpkt: 1046 /* 1047 * prepare next packet 1048 * as each packet will be aligned 8byte boundary, 1049 * need to fix up the start point of the buffer. 1050 */ 1051 temp = ((pkt_len + 7) & 0xfff8); 1052 buf = buf + temp; 1053 hdr_p++; 1054 pkt_count--; 1055 } while( pkt_count > 0); 1056 1057 done: 1058 /* push the packet up */ 1059 s = splnet(); 1060 if_input(ifp, &ml); 1061 splx(s); 1062 1063 /* clear buffer for next transaction */ 1064 memset(c->axen_buf, 0, sc->axen_bufsz); 1065 1066 /* Setup new transfer. */ 1067 usbd_setup_xfer(xfer, sc->axen_ep[AXEN_ENDPT_RX], 1068 c, c->axen_buf, sc->axen_bufsz, 1069 USBD_SHORT_XFER_OK | USBD_NO_COPY, 1070 USBD_NO_TIMEOUT, axen_rxeof); 1071 usbd_transfer(xfer); 1072 1073 DPRINTFN(10,("%s: %s: start rx\n", sc->axen_dev.dv_xname, __func__)); 1074 } 1075 1076 /* 1077 * A frame was downloaded to the chip. It's safe for us to clean up 1078 * the list buffers. 1079 */ 1080 void 1081 axen_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1082 { 1083 struct axen_softc *sc; 1084 struct axen_chain *c; 1085 struct ifnet *ifp; 1086 int s; 1087 1088 c = priv; 1089 sc = c->axen_sc; 1090 ifp = &sc->arpcom.ac_if; 1091 1092 if (usbd_is_dying(sc->axen_udev)) 1093 return; 1094 1095 s = splnet(); 1096 1097 if (status != USBD_NORMAL_COMPLETION) { 1098 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1099 splx(s); 1100 return; 1101 } 1102 ifp->if_oerrors++; 1103 printf("axen%d: usb error on tx: %s\n", sc->axen_unit, 1104 usbd_errstr(status)); 1105 if (status == USBD_STALLED) 1106 usbd_clear_endpoint_stall_async(sc->axen_ep[AXEN_ENDPT_TX]); 1107 splx(s); 1108 return; 1109 } 1110 1111 ifp->if_timer = 0; 1112 ifq_clr_oactive(&ifp->if_snd); 1113 1114 m_freem(c->axen_mbuf); 1115 c->axen_mbuf = NULL; 1116 1117 if (ifq_empty(&ifp->if_snd) == 0) 1118 axen_start(ifp); 1119 1120 splx(s); 1121 } 1122 1123 void 1124 axen_tick(void *xsc) 1125 { 1126 struct axen_softc *sc = xsc; 1127 1128 if (sc == NULL) 1129 return; 1130 1131 DPRINTFN(0xff, ("%s: %s: enter\n", sc->axen_dev.dv_xname, 1132 __func__)); 1133 1134 if (usbd_is_dying(sc->axen_udev)) 1135 return; 1136 1137 /* Perform periodic stuff in process context */ 1138 usb_add_task(sc->axen_udev, &sc->axen_tick_task); 1139 } 1140 1141 void 1142 axen_tick_task(void *xsc) 1143 { 1144 int s; 1145 struct axen_softc *sc; 1146 struct mii_data *mii; 1147 1148 sc = xsc; 1149 1150 if (sc == NULL) 1151 return; 1152 1153 if (usbd_is_dying(sc->axen_udev)) 1154 return; 1155 1156 mii = GET_MII(sc); 1157 if (mii == NULL) 1158 return; 1159 1160 s = splnet(); 1161 1162 mii_tick(mii); 1163 if (sc->axen_link == 0) 1164 axen_miibus_statchg(&sc->axen_dev); 1165 timeout_add_sec(&sc->axen_stat_ch, 1); 1166 1167 splx(s); 1168 } 1169 1170 int 1171 axen_encap(struct axen_softc *sc, struct mbuf *m, int idx) 1172 { 1173 struct axen_chain *c; 1174 usbd_status err; 1175 struct axen_sframe_hdr hdr; 1176 int length, boundary; 1177 1178 c = &sc->axen_cdata.axen_tx_chain[idx]; 1179 1180 switch (sc->axen_udev->speed) { 1181 case USB_SPEED_FULL: 1182 boundary = 64; 1183 break; 1184 case USB_SPEED_HIGH: 1185 boundary = 512; 1186 break; 1187 case USB_SPEED_SUPER: 1188 boundary = 4096; /* XXX */ 1189 break; 1190 default: 1191 printf("%s: not supported usb bus type", sc->axen_dev.dv_xname); 1192 return EIO; 1193 } 1194 1195 hdr.plen = htole32(m->m_pkthdr.len); 1196 hdr.gso = 0; /* disable segmentation offloading */ 1197 1198 memcpy(c->axen_buf, &hdr, sizeof(hdr)); 1199 length = sizeof(hdr); 1200 1201 m_copydata(m, 0, m->m_pkthdr.len, c->axen_buf + length); 1202 length += m->m_pkthdr.len; 1203 1204 if ((length % boundary) == 0) { 1205 hdr.plen = 0x0; 1206 hdr.gso |= 0x80008000; /* enable padding */ 1207 memcpy(c->axen_buf + length, &hdr, sizeof(hdr)); 1208 length += sizeof(hdr); 1209 } 1210 1211 c->axen_mbuf = m; 1212 1213 usbd_setup_xfer(c->axen_xfer, sc->axen_ep[AXEN_ENDPT_TX], 1214 c, c->axen_buf, length, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 1215 10000, axen_txeof); 1216 1217 /* Transmit */ 1218 err = usbd_transfer(c->axen_xfer); 1219 if (err != USBD_IN_PROGRESS) { 1220 c->axen_mbuf = NULL; 1221 axen_stop(sc); 1222 return EIO; 1223 } 1224 1225 sc->axen_cdata.axen_tx_cnt++; 1226 1227 return 0; 1228 } 1229 1230 void 1231 axen_start(struct ifnet *ifp) 1232 { 1233 struct axen_softc *sc; 1234 struct mbuf *m_head = NULL; 1235 1236 sc = ifp->if_softc; 1237 1238 if (!sc->axen_link) 1239 return; 1240 1241 if (ifq_is_oactive(&ifp->if_snd)) 1242 return; 1243 1244 m_head = ifq_dequeue(&ifp->if_snd); 1245 if (m_head == NULL) 1246 return; 1247 1248 if (axen_encap(sc, m_head, 0)) { 1249 m_freem(m_head); 1250 ifq_set_oactive(&ifp->if_snd); 1251 return; 1252 } 1253 1254 /* 1255 * If there's a BPF listener, bounce a copy of this frame 1256 * to him. 1257 */ 1258 #if NBPFILTER > 0 1259 if (ifp->if_bpf) 1260 bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT); 1261 #endif 1262 1263 ifq_set_oactive(&ifp->if_snd); 1264 1265 /* 1266 * Set a timeout in case the chip goes out to lunch. 1267 */ 1268 ifp->if_timer = 5; 1269 } 1270 1271 void 1272 axen_init(void *xsc) 1273 { 1274 struct axen_softc *sc = xsc; 1275 struct ifnet *ifp = &sc->arpcom.ac_if; 1276 struct axen_chain *c; 1277 usbd_status err; 1278 int i, s; 1279 uByte bval; 1280 uWord wval; 1281 uint16_t rxmode; 1282 1283 s = splnet(); 1284 1285 /* 1286 * Cancel pending I/O and free all RX/TX buffers. 1287 */ 1288 axen_reset(sc); 1289 1290 /* XXX: ? */ 1291 bval = 0x01; 1292 axen_lock_mii(sc); 1293 axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_UNK_28, &bval); 1294 axen_unlock_mii(sc); 1295 1296 /* Init RX ring. */ 1297 if (axen_rx_list_init(sc) == ENOBUFS) { 1298 printf("axen%d: rx list init failed\n", sc->axen_unit); 1299 splx(s); 1300 return; 1301 } 1302 1303 /* Init TX ring. */ 1304 if (axen_tx_list_init(sc) == ENOBUFS) { 1305 printf("axen%d: tx list init failed\n", sc->axen_unit); 1306 splx(s); 1307 return; 1308 } 1309 1310 /* Program promiscuous mode and multicast filters. */ 1311 axen_iff(sc); 1312 1313 /* Enable receiver, set RX mode */ 1314 axen_lock_mii(sc); 1315 axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_MAC_RXCTL, &wval); 1316 rxmode = UGETW(wval); 1317 rxmode |= AXEN_RXCTL_START; 1318 USETW(wval, rxmode); 1319 axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MAC_RXCTL, &wval); 1320 axen_unlock_mii(sc); 1321 1322 /* Open RX and TX pipes. */ 1323 err = usbd_open_pipe(sc->axen_iface, sc->axen_ed[AXEN_ENDPT_RX], 1324 USBD_EXCLUSIVE_USE, &sc->axen_ep[AXEN_ENDPT_RX]); 1325 if (err) { 1326 printf("axen%d: open rx pipe failed: %s\n", 1327 sc->axen_unit, usbd_errstr(err)); 1328 splx(s); 1329 return; 1330 } 1331 1332 err = usbd_open_pipe(sc->axen_iface, sc->axen_ed[AXEN_ENDPT_TX], 1333 USBD_EXCLUSIVE_USE, &sc->axen_ep[AXEN_ENDPT_TX]); 1334 if (err) { 1335 printf("axen%d: open tx pipe failed: %s\n", 1336 sc->axen_unit, usbd_errstr(err)); 1337 splx(s); 1338 return; 1339 } 1340 1341 /* Start up the receive pipe. */ 1342 for (i = 0; i < AXEN_RX_LIST_CNT; i++) { 1343 c = &sc->axen_cdata.axen_rx_chain[i]; 1344 usbd_setup_xfer(c->axen_xfer, sc->axen_ep[AXEN_ENDPT_RX], 1345 c, c->axen_buf, sc->axen_bufsz, 1346 USBD_SHORT_XFER_OK | USBD_NO_COPY, 1347 USBD_NO_TIMEOUT, axen_rxeof); 1348 usbd_transfer(c->axen_xfer); 1349 } 1350 1351 sc->axen_link = 0; 1352 ifp->if_flags |= IFF_RUNNING; 1353 ifq_clr_oactive(&ifp->if_snd); 1354 1355 splx(s); 1356 1357 timeout_add_sec(&sc->axen_stat_ch, 1); 1358 return; 1359 } 1360 1361 int 1362 axen_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 1363 { 1364 struct axen_softc *sc = ifp->if_softc; 1365 struct ifreq *ifr = (struct ifreq *)data; 1366 int s; 1367 int error = 0; 1368 1369 s = splnet(); 1370 1371 switch(cmd) { 1372 case SIOCSIFADDR: 1373 ifp->if_flags |= IFF_UP; 1374 if (!(ifp->if_flags & IFF_RUNNING)) 1375 axen_init(sc); 1376 break; 1377 1378 case SIOCSIFFLAGS: 1379 if (ifp->if_flags & IFF_UP) { 1380 if (ifp->if_flags & IFF_RUNNING) 1381 error = ENETRESET; 1382 else 1383 axen_init(sc); 1384 } else { 1385 if (ifp->if_flags & IFF_RUNNING) 1386 axen_stop(sc); 1387 } 1388 break; 1389 1390 case SIOCGIFMEDIA: 1391 case SIOCSIFMEDIA: 1392 error = ifmedia_ioctl(ifp, ifr, &sc->axen_mii.mii_media, cmd); 1393 break; 1394 1395 #if 0 1396 case SCIOCSIFMTU: 1397 /* XXX need to set AX_MEDIUM_JUMBO_EN here? */ 1398 /* fall through */ 1399 #endif 1400 default: 1401 error = ether_ioctl(ifp, &sc->arpcom, cmd, data); 1402 } 1403 1404 if (error == ENETRESET) { 1405 if (ifp->if_flags & IFF_RUNNING) 1406 axen_iff(sc); 1407 error = 0; 1408 } 1409 1410 splx(s); 1411 1412 return error; 1413 } 1414 1415 void 1416 axen_watchdog(struct ifnet *ifp) 1417 { 1418 struct axen_softc *sc; 1419 struct axen_chain *c; 1420 usbd_status stat; 1421 int s; 1422 1423 sc = ifp->if_softc; 1424 1425 ifp->if_oerrors++; 1426 printf("axen%d: watchdog timeout\n", sc->axen_unit); 1427 1428 s = splusb(); 1429 c = &sc->axen_cdata.axen_tx_chain[0]; 1430 usbd_get_xfer_status(c->axen_xfer, NULL, NULL, NULL, &stat); 1431 axen_txeof(c->axen_xfer, c, stat); 1432 1433 if (!ifq_empty(&ifp->if_snd)) 1434 axen_start(ifp); 1435 splx(s); 1436 } 1437 1438 /* 1439 * Stop the adapter and free any mbufs allocated to the 1440 * RX and TX lists. 1441 */ 1442 void 1443 axen_stop(struct axen_softc *sc) 1444 { 1445 usbd_status err; 1446 struct ifnet *ifp; 1447 int i; 1448 1449 axen_reset(sc); 1450 1451 ifp = &sc->arpcom.ac_if; 1452 ifp->if_timer = 0; 1453 ifp->if_flags &= ~IFF_RUNNING; 1454 ifq_clr_oactive(&ifp->if_snd); 1455 1456 timeout_del(&sc->axen_stat_ch); 1457 1458 /* Stop transfers. */ 1459 if (sc->axen_ep[AXEN_ENDPT_RX] != NULL) { 1460 err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_RX]); 1461 if (err) { 1462 printf("axen%d: close rx pipe failed: %s\n", 1463 sc->axen_unit, usbd_errstr(err)); 1464 } 1465 sc->axen_ep[AXEN_ENDPT_RX] = NULL; 1466 } 1467 1468 if (sc->axen_ep[AXEN_ENDPT_TX] != NULL) { 1469 err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_TX]); 1470 if (err) { 1471 printf("axen%d: close tx pipe failed: %s\n", 1472 sc->axen_unit, usbd_errstr(err)); 1473 } 1474 sc->axen_ep[AXEN_ENDPT_TX] = NULL; 1475 } 1476 1477 if (sc->axen_ep[AXEN_ENDPT_INTR] != NULL) { 1478 err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_INTR]); 1479 if (err) { 1480 printf("axen%d: close intr pipe failed: %s\n", 1481 sc->axen_unit, usbd_errstr(err)); 1482 } 1483 sc->axen_ep[AXEN_ENDPT_INTR] = NULL; 1484 } 1485 1486 /* Free RX resources. */ 1487 for (i = 0; i < AXEN_RX_LIST_CNT; i++) { 1488 if (sc->axen_cdata.axen_rx_chain[i].axen_mbuf != NULL) { 1489 m_freem(sc->axen_cdata.axen_rx_chain[i].axen_mbuf); 1490 sc->axen_cdata.axen_rx_chain[i].axen_mbuf = NULL; 1491 } 1492 if (sc->axen_cdata.axen_rx_chain[i].axen_xfer != NULL) { 1493 usbd_free_xfer(sc->axen_cdata.axen_rx_chain[i].axen_xfer); 1494 sc->axen_cdata.axen_rx_chain[i].axen_xfer = NULL; 1495 } 1496 } 1497 1498 /* Free TX resources. */ 1499 for (i = 0; i < AXEN_TX_LIST_CNT; i++) { 1500 1501 if (sc->axen_cdata.axen_tx_chain[i].axen_mbuf != NULL) { 1502 m_freem(sc->axen_cdata.axen_tx_chain[i].axen_mbuf); 1503 sc->axen_cdata.axen_tx_chain[i].axen_mbuf = NULL; 1504 } 1505 if (sc->axen_cdata.axen_tx_chain[i].axen_xfer != NULL) { 1506 usbd_free_xfer(sc->axen_cdata.axen_tx_chain[i].axen_xfer); 1507 sc->axen_cdata.axen_tx_chain[i].axen_xfer = NULL; 1508 } 1509 } 1510 1511 sc->axen_link = 0; 1512 } 1513