1/* $NetBSD: if_axe.c,v 1.151 2022/08/20 14:08:59 riastradh Exp $ */ 2/* $OpenBSD: if_axe.c,v 1.137 2016/04/13 11:03:37 mpi Exp $ */ 3 4/* 5 * Copyright (c) 2005, 2006, 2007 Jonathan Gray <jsg@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 * Copyright (c) 1997, 1998, 1999, 2000-2003 22 * Bill Paul <wpaul@windriver.com>. All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. All advertising materials mentioning features or use of this software 33 * must display the following acknowledgement: 34 * This product includes software developed by Bill Paul. 35 * 4. Neither the name of the author nor the names of any co-contributors 36 * may be used to endorse or promote products derived from this software 37 * without specific prior written permission. 38 * 39 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 42 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 43 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 44 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 45 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 46 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 49 * THE POSSIBILITY OF SUCH DAMAGE. 50 */ 51 52/* 53 * ASIX Electronics AX88172/AX88178/AX88778 USB 2.0 ethernet driver. 54 * Used in the LinkSys USB200M and various other adapters. 55 * 56 * Written by Bill Paul <wpaul@windriver.com> 57 * Senior Engineer 58 * Wind River Systems 59 */ 60 61/* 62 * The AX88172 provides USB ethernet supports at 10 and 100Mbps. 63 * It uses an external PHY (reference designs use a RealTek chip), 64 * and has a 64-bit multicast hash filter. There is some information 65 * missing from the manual which one needs to know in order to make 66 * the chip function: 67 * 68 * - You must set bit 7 in the RX control register, otherwise the 69 * chip won't receive any packets. 70 * - You must initialize all 3 IPG registers, or you won't be able 71 * to send any packets. 72 * 73 * Note that this device appears to only support loading the station 74 * address via autoload from the EEPROM (i.e. there's no way to manually 75 * set it). 76 * 77 * (Adam Weinberger wanted me to name this driver if_gir.c.) 78 */ 79 80/* 81 * Ax88178 and Ax88772 support backported from the OpenBSD driver. 82 * 2007/02/12, J.R. Oldroyd, fbsd@opal.com 83 * 84 * Manual here: 85 * http://www.asix.com.tw/FrootAttach/datasheet/AX88178_datasheet_Rev10.pdf 86 * http://www.asix.com.tw/FrootAttach/datasheet/AX88772_datasheet_Rev10.pdf 87 */ 88 89#include <sys/cdefs.h> 90__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.151 2022/08/20 14:08:59 riastradh Exp $"); 91 92#ifdef _KERNEL_OPT 93#include "opt_usb.h" 94#include "opt_net_mpsafe.h" 95#endif 96 97#include <sys/param.h> 98 99#include <dev/usb/usbnet.h> 100#include <dev/usb/usbhist.h> 101#include <dev/usb/if_axereg.h> 102 103struct axe_type { 104 struct usb_devno axe_dev; 105 uint16_t axe_flags; 106}; 107 108struct axe_softc { 109 struct usbnet axe_un; 110 111 /* usbnet:un_flags values */ 112#define AX178 __BIT(0) /* AX88178 */ 113#define AX772 __BIT(1) /* AX88772 */ 114#define AX772A __BIT(2) /* AX88772A */ 115#define AX772B __BIT(3) /* AX88772B */ 116#define AXSTD_FRAME __BIT(12) 117#define AXCSUM_FRAME __BIT(13) 118 119 uint8_t axe_ipgs[3]; 120 uint8_t axe_phyaddrs[2]; 121 uint16_t sc_pwrcfg; 122 uint16_t sc_lenmask; 123 124}; 125 126#define AXE_IS_178_FAMILY(un) \ 127 ((un)->un_flags & (AX178 | AX772 | AX772A | AX772B)) 128 129#define AXE_IS_772(un) \ 130 ((un)->un_flags & (AX772 | AX772A | AX772B)) 131 132#define AXE_IS_172(un) (AXE_IS_178_FAMILY(un) == 0) 133 134#define AX_RXCSUM \ 135 (IFCAP_CSUM_IPv4_Rx | \ 136 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | \ 137 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx) 138 139#define AX_TXCSUM \ 140 (IFCAP_CSUM_IPv4_Tx | \ 141 IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx | \ 142 IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx) 143 144/* 145 * AXE_178_MAX_FRAME_BURST 146 * max frame burst size for Ax88178 and Ax88772 147 * 0 2048 bytes 148 * 1 4096 bytes 149 * 2 8192 bytes 150 * 3 16384 bytes 151 * use the largest your system can handle without USB stalling. 152 * 153 * NB: 88772 parts appear to generate lots of input errors with 154 * a 2K rx buffer and 8K is only slightly faster than 4K on an 155 * EHCI port on a T42 so change at your own risk. 156 */ 157#define AXE_178_MAX_FRAME_BURST 1 158 159 160#ifdef USB_DEBUG 161#ifndef AXE_DEBUG 162#define axedebug 0 163#else 164static int axedebug = 0; 165 166SYSCTL_SETUP(sysctl_hw_axe_setup, "sysctl hw.axe setup") 167{ 168 int err; 169 const struct sysctlnode *rnode; 170 const struct sysctlnode *cnode; 171 172 err = sysctl_createv(clog, 0, NULL, &rnode, 173 CTLFLAG_PERMANENT, CTLTYPE_NODE, "axe", 174 SYSCTL_DESCR("axe global controls"), 175 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 176 177 if (err) 178 goto fail; 179 180 /* control debugging printfs */ 181 err = sysctl_createv(clog, 0, &rnode, &cnode, 182 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 183 "debug", SYSCTL_DESCR("Enable debugging output"), 184 NULL, 0, &axedebug, sizeof(axedebug), CTL_CREATE, CTL_EOL); 185 if (err) 186 goto fail; 187 188 return; 189fail: 190 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 191} 192 193#endif /* AXE_DEBUG */ 194#endif /* USB_DEBUG */ 195 196#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(axedebug,1,FMT,A,B,C,D) 197#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(axedebug,N,FMT,A,B,C,D) 198#define AXEHIST_FUNC() USBHIST_FUNC() 199#define AXEHIST_CALLED(name) USBHIST_CALLED(axedebug) 200 201/* 202 * Various supported device vendors/products. 203 */ 204static const struct axe_type axe_devs[] = { 205 { { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_UFE2000 }, 0 }, 206 { { USB_VENDOR_ACERCM, USB_PRODUCT_ACERCM_EP1427X2 }, 0 }, 207 { { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ETHERNET }, AX772 }, 208 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88172 }, 0 }, 209 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772 }, AX772 }, 210 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772A }, AX772 }, 211 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B }, AX772B }, 212 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88772B_1 }, AX772B }, 213 { { USB_VENDOR_ASIX, USB_PRODUCT_ASIX_AX88178 }, AX178 }, 214 { { USB_VENDOR_ATEN, USB_PRODUCT_ATEN_UC210T }, 0 }, 215 { { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D5055 }, AX178 }, 216 { { USB_VENDOR_BILLIONTON, USB_PRODUCT_BILLIONTON_USB2AR }, 0}, 217 { { USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_USB200MV2 }, AX772A }, 218 { { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_FETHER_USB2_TX }, 0 }, 219 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100 }, 0 }, 220 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100B1 }, AX772 }, 221 { { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DUBE100B1 }, AX772 }, 222 { { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DUBE100C1 }, AX772B }, 223 { { USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_GWUSB2E }, 0 }, 224 { { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_ETGUS2 }, AX178 }, 225 { { USB_VENDOR_JVC, USB_PRODUCT_JVC_MP_PRX1 }, 0 }, 226 { { USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_ETHERNET }, AX772B }, 227 { { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_HG20F9 }, AX772B }, 228 { { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_USB200M }, 0 }, 229 { { USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_USB1000 }, AX178 }, 230 { { USB_VENDOR_LOGITEC, USB_PRODUCT_LOGITEC_LAN_GTJU2 }, AX178 }, 231 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2GT }, AX178 }, 232 { { USB_VENDOR_MELCO, USB_PRODUCT_MELCO_LUAU2KTX }, 0 }, 233 { { USB_VENDOR_MSI, USB_PRODUCT_MSI_AX88772A }, AX772 }, 234 { { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_FA120 }, 0 }, 235 { { USB_VENDOR_OQO, USB_PRODUCT_OQO_ETHER01PLUS }, AX772 }, 236 { { USB_VENDOR_PLANEX3, USB_PRODUCT_PLANEX3_GU1000T }, AX178 }, 237 { { USB_VENDOR_SITECOM, USB_PRODUCT_SITECOM_LN029 }, 0 }, 238 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN028 }, AX178 }, 239 { { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_LN031 }, AX178 }, 240 { { USB_VENDOR_SYSTEMTALKS, USB_PRODUCT_SYSTEMTALKS_SGCX2UL }, 0 }, 241}; 242#define axe_lookup(v, p) ((const struct axe_type *)usb_lookup(axe_devs, v, p)) 243 244static const struct ax88772b_mfb ax88772b_mfb_table[] = { 245 { 0x8000, 0x8001, 2048 }, 246 { 0x8100, 0x8147, 4096 }, 247 { 0x8200, 0x81EB, 6144 }, 248 { 0x8300, 0x83D7, 8192 }, 249 { 0x8400, 0x851E, 16384 }, 250 { 0x8500, 0x8666, 20480 }, 251 { 0x8600, 0x87AE, 24576 }, 252 { 0x8700, 0x8A3D, 32768 } 253}; 254 255static int axe_match(device_t, cfdata_t, void *); 256static void axe_attach(device_t, device_t, void *); 257 258CFATTACH_DECL_NEW(axe, sizeof(struct axe_softc), 259 axe_match, axe_attach, usbnet_detach, usbnet_activate); 260 261static void axe_uno_stop(struct ifnet *, int); 262static void axe_uno_mcast(struct ifnet *); 263static int axe_uno_init(struct ifnet *); 264static int axe_uno_mii_read_reg(struct usbnet *, int, int, uint16_t *); 265static int axe_uno_mii_write_reg(struct usbnet *, int, int, uint16_t); 266static void axe_uno_mii_statchg(struct ifnet *); 267static void axe_uno_rx_loop(struct usbnet *, struct usbnet_chain *, 268 uint32_t); 269static unsigned axe_uno_tx_prepare(struct usbnet *, struct mbuf *, 270 struct usbnet_chain *); 271 272static void axe_ax88178_init(struct axe_softc *); 273static void axe_ax88772_init(struct axe_softc *); 274static void axe_ax88772a_init(struct axe_softc *); 275static void axe_ax88772b_init(struct axe_softc *); 276 277static const struct usbnet_ops axe_ops = { 278 .uno_stop = axe_uno_stop, 279 .uno_mcast = axe_uno_mcast, 280 .uno_read_reg = axe_uno_mii_read_reg, 281 .uno_write_reg = axe_uno_mii_write_reg, 282 .uno_statchg = axe_uno_mii_statchg, 283 .uno_tx_prepare = axe_uno_tx_prepare, 284 .uno_rx_loop = axe_uno_rx_loop, 285 .uno_init = axe_uno_init, 286}; 287 288static usbd_status 289axe_cmd(struct axe_softc *sc, int cmd, int index, int val, void *buf) 290{ 291 AXEHIST_FUNC(); AXEHIST_CALLED(); 292 struct usbnet * const un = &sc->axe_un; 293 usb_device_request_t req; 294 usbd_status err; 295 296 if (usbnet_isdying(un)) 297 return -1; 298 299 DPRINTFN(20, "cmd %#jx index %#jx val %#jx", cmd, index, val, 0); 300 301 if (AXE_CMD_DIR(cmd)) 302 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 303 else 304 req.bmRequestType = UT_READ_VENDOR_DEVICE; 305 req.bRequest = AXE_CMD_CMD(cmd); 306 USETW(req.wValue, val); 307 USETW(req.wIndex, index); 308 USETW(req.wLength, AXE_CMD_LEN(cmd)); 309 310 err = usbd_do_request(un->un_udev, &req, buf); 311 if (err) 312 DPRINTF("cmd %jd err %jd", cmd, err, 0, 0); 313 314 return err; 315} 316 317static int 318axe_uno_mii_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 319{ 320 AXEHIST_FUNC(); AXEHIST_CALLED(); 321 struct axe_softc * const sc = usbnet_softc(un); 322 usbd_status err; 323 uint16_t data; 324 325 DPRINTFN(30, "phy %#jx reg %#jx\n", phy, reg, 0, 0); 326 327 if (un->un_phyno != phy) { 328 *val = 0; 329 return EINVAL; 330 } 331 332 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 333 334 err = axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &data); 335 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); 336 337 if (err) { 338 device_printf(un->un_dev, "read PHY failed\n"); 339 *val = 0; 340 return EIO; 341 } 342 343 *val = le16toh(data); 344 if (AXE_IS_772(un) && reg == MII_BMSR) { 345 /* 346 * BMSR of AX88772 indicates that it supports extended 347 * capability but the extended status register is 348 * reserved for embedded ethernet PHY. So clear the 349 * extended capability bit of BMSR. 350 */ 351 *val &= ~BMSR_EXTCAP; 352 } 353 354 DPRINTFN(30, "phy %#jx reg %#jx val %#jx", phy, reg, *val, 0); 355 356 return 0; 357} 358 359static int 360axe_uno_mii_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 361{ 362 struct axe_softc * const sc = usbnet_softc(un); 363 usbd_status err; 364 uint16_t aval; 365 366 if (un->un_phyno != phy) 367 return EINVAL; 368 369 aval = htole16(val); 370 371 axe_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL); 372 err = axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &aval); 373 axe_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL); 374 375 if (err) 376 return EIO; 377 return 0; 378} 379 380static void 381axe_uno_mii_statchg(struct ifnet *ifp) 382{ 383 AXEHIST_FUNC(); AXEHIST_CALLED(); 384 385 struct usbnet * const un = ifp->if_softc; 386 struct axe_softc * const sc = usbnet_softc(un); 387 struct mii_data *mii = usbnet_mii(un); 388 int val, err; 389 390 if (usbnet_isdying(un)) 391 return; 392 393 val = 0; 394 if (AXE_IS_172(un)) { 395 if (mii->mii_media_active & IFM_FDX) 396 val |= AXE_MEDIA_FULL_DUPLEX; 397 } else { 398 if (mii->mii_media_active & IFM_FDX) { 399 val |= AXE_MEDIA_FULL_DUPLEX; 400 if (mii->mii_media_active & IFM_ETH_TXPAUSE) 401 val |= AXE_178_MEDIA_TXFLOW_CONTROL_EN; 402 if (mii->mii_media_active & IFM_ETH_RXPAUSE) 403 val |= AXE_178_MEDIA_RXFLOW_CONTROL_EN; 404 } 405 val |= AXE_178_MEDIA_RX_EN | AXE_178_MEDIA_MAGIC; 406 if (un->un_flags & AX178) 407 val |= AXE_178_MEDIA_ENCK; 408 switch (IFM_SUBTYPE(mii->mii_media_active)) { 409 case IFM_1000_T: 410 val |= AXE_178_MEDIA_GMII | AXE_178_MEDIA_ENCK; 411 usbnet_set_link(un, true); 412 break; 413 case IFM_100_TX: 414 val |= AXE_178_MEDIA_100TX; 415 usbnet_set_link(un, true); 416 break; 417 case IFM_10_T: 418 usbnet_set_link(un, true); 419 break; 420 } 421 } 422 423 DPRINTF("val=%#jx", val, 0, 0, 0); 424 err = axe_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL); 425 if (err) 426 device_printf(un->un_dev, "media change failed\n"); 427} 428 429static void 430axe_uno_mcast(struct ifnet *ifp) 431{ 432 AXEHIST_FUNC(); AXEHIST_CALLED(); 433 struct usbnet * const un = ifp->if_softc; 434 struct axe_softc * const sc = usbnet_softc(un); 435 struct ethercom *ec = usbnet_ec(un); 436 struct ether_multi *enm; 437 struct ether_multistep step; 438 uint16_t rxmode; 439 uint32_t h = 0; 440 uint8_t mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 441 442 if (usbnet_isdying(un)) 443 return; 444 445 if (axe_cmd(sc, AXE_CMD_RXCTL_READ, 0, 0, &rxmode)) { 446 device_printf(un->un_dev, "can't read rxmode"); 447 return; 448 } 449 rxmode = le16toh(rxmode); 450 451 rxmode &= 452 ~(AXE_RXCMD_ALLMULTI | AXE_RXCMD_PROMISC | AXE_RXCMD_MULTICAST); 453 454 ETHER_LOCK(ec); 455 if (usbnet_ispromisc(un)) { 456 ec->ec_flags |= ETHER_F_ALLMULTI; 457 ETHER_UNLOCK(ec); 458 /* run promisc. mode */ 459 rxmode |= AXE_RXCMD_ALLMULTI; /* ??? */ 460 rxmode |= AXE_RXCMD_PROMISC; 461 goto update; 462 } 463 ec->ec_flags &= ~ETHER_F_ALLMULTI; 464 ETHER_FIRST_MULTI(step, ec, enm); 465 while (enm != NULL) { 466 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 467 ec->ec_flags |= ETHER_F_ALLMULTI; 468 ETHER_UNLOCK(ec); 469 /* accept all mcast frames */ 470 rxmode |= AXE_RXCMD_ALLMULTI; 471 goto update; 472 } 473 h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 474 mchash[h >> 29] |= 1U << ((h >> 26) & 7); 475 ETHER_NEXT_MULTI(step, enm); 476 } 477 ETHER_UNLOCK(ec); 478 if (h != 0) 479 rxmode |= AXE_RXCMD_MULTICAST; /* activate mcast hash filter */ 480 axe_cmd(sc, AXE_CMD_WRITE_MCAST, 0, 0, mchash); 481 update: 482 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 483} 484 485static void 486axe_ax_init(struct usbnet *un) 487{ 488 struct axe_softc * const sc = usbnet_softc(un); 489 490 int cmd = AXE_178_CMD_READ_NODEID; 491 492 if (un->un_flags & AX178) { 493 axe_ax88178_init(sc); 494 } else if (un->un_flags & AX772) { 495 axe_ax88772_init(sc); 496 } else if (un->un_flags & AX772A) { 497 axe_ax88772a_init(sc); 498 } else if (un->un_flags & AX772B) { 499 axe_ax88772b_init(sc); 500 return; 501 } else { 502 cmd = AXE_172_CMD_READ_NODEID; 503 } 504 505 if (axe_cmd(sc, cmd, 0, 0, un->un_eaddr)) { 506 aprint_error_dev(un->un_dev, 507 "failed to read ethernet address\n"); 508 } 509} 510 511 512static void 513axe_reset(struct usbnet *un) 514{ 515 516 if (usbnet_isdying(un)) 517 return; 518 519 /* 520 * softnet_lock can be taken when NET_MPAFE is not defined when calling 521 * if_addr_init -> if_init. This doesn't mix well with the 522 * usbd_delay_ms calls in the init routines as things like nd6_slowtimo 523 * can fire during the wait and attempt to take softnet_lock and then 524 * block the softclk thread meaning the wait never ends. 525 */ 526#ifndef NET_MPSAFE 527 /* XXX What to reset? */ 528 529 /* Wait a little while for the chip to get its brains in order. */ 530 DELAY(1000); 531#else 532 axe_ax_init(un); 533#endif 534} 535 536static int 537axe_get_phyno(struct axe_softc *sc, int sel) 538{ 539 int phyno; 540 541 switch (AXE_PHY_TYPE(sc->axe_phyaddrs[sel])) { 542 case PHY_TYPE_100_HOME: 543 /* FALLTHROUGH */ 544 case PHY_TYPE_GIG: 545 phyno = AXE_PHY_NO(sc->axe_phyaddrs[sel]); 546 break; 547 case PHY_TYPE_SPECIAL: 548 /* FALLTHROUGH */ 549 case PHY_TYPE_RSVD: 550 /* FALLTHROUGH */ 551 case PHY_TYPE_NON_SUP: 552 /* FALLTHROUGH */ 553 default: 554 phyno = -1; 555 break; 556 } 557 558 return phyno; 559} 560 561#define AXE_GPIO_WRITE(x, y) do { \ 562 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, (x), NULL); \ 563 usbd_delay_ms(sc->axe_un.un_udev, hztoms(y)); \ 564} while (0) 565 566static void 567axe_ax88178_init(struct axe_softc *sc) 568{ 569 AXEHIST_FUNC(); AXEHIST_CALLED(); 570 struct usbnet * const un = &sc->axe_un; 571 int gpio0, ledmode, phymode; 572 uint16_t eeprom, val; 573 574 axe_cmd(sc, AXE_CMD_SROM_WR_ENABLE, 0, 0, NULL); 575 /* XXX magic */ 576 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, 0x0017, &eeprom) != 0) 577 eeprom = 0xffff; 578 axe_cmd(sc, AXE_CMD_SROM_WR_DISABLE, 0, 0, NULL); 579 580 eeprom = le16toh(eeprom); 581 582 DPRINTF("EEPROM is %#jx", eeprom, 0, 0, 0); 583 584 /* if EEPROM is invalid we have to use to GPIO0 */ 585 if (eeprom == 0xffff) { 586 phymode = AXE_PHY_MODE_MARVELL; 587 gpio0 = 1; 588 ledmode = 0; 589 } else { 590 phymode = eeprom & 0x7f; 591 gpio0 = (eeprom & 0x80) ? 0 : 1; 592 ledmode = eeprom >> 8; 593 } 594 595 DPRINTF("use gpio0: %jd, phymode %jd", gpio0, phymode, 0, 0); 596 597 /* Program GPIOs depending on PHY hardware. */ 598 switch (phymode) { 599 case AXE_PHY_MODE_MARVELL: 600 if (gpio0 == 1) { 601 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0_EN, 602 hz / 32); 603 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN, 604 hz / 32); 605 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2_EN, hz / 4); 606 AXE_GPIO_WRITE(AXE_GPIO0_EN | AXE_GPIO2 | AXE_GPIO2_EN, 607 hz / 32); 608 } else { 609 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 | 610 AXE_GPIO1_EN, hz / 3); 611 if (ledmode == 1) { 612 AXE_GPIO_WRITE(AXE_GPIO1_EN, hz / 3); 613 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN, 614 hz / 3); 615 } else { 616 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | 617 AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 618 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | 619 AXE_GPIO2_EN, hz / 4); 620 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | 621 AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 622 } 623 } 624 break; 625 case AXE_PHY_MODE_CICADA: 626 case AXE_PHY_MODE_CICADA_V2: 627 case AXE_PHY_MODE_CICADA_V2_ASIX: 628 if (gpio0 == 1) 629 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO0 | 630 AXE_GPIO0_EN, hz / 32); 631 else 632 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 | 633 AXE_GPIO1_EN, hz / 32); 634 break; 635 case AXE_PHY_MODE_AGERE: 636 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM | AXE_GPIO1 | 637 AXE_GPIO1_EN, hz / 32); 638 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 | 639 AXE_GPIO2_EN, hz / 32); 640 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2_EN, hz / 4); 641 AXE_GPIO_WRITE(AXE_GPIO1 | AXE_GPIO1_EN | AXE_GPIO2 | 642 AXE_GPIO2_EN, hz / 32); 643 break; 644 case AXE_PHY_MODE_REALTEK_8211CL: 645 case AXE_PHY_MODE_REALTEK_8211BN: 646 case AXE_PHY_MODE_REALTEK_8251CL: 647 val = gpio0 == 1 ? AXE_GPIO0 | AXE_GPIO0_EN : 648 AXE_GPIO1 | AXE_GPIO1_EN; 649 AXE_GPIO_WRITE(val, hz / 32); 650 AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 651 AXE_GPIO_WRITE(val | AXE_GPIO2_EN, hz / 4); 652 AXE_GPIO_WRITE(val | AXE_GPIO2 | AXE_GPIO2_EN, hz / 32); 653 if (phymode == AXE_PHY_MODE_REALTEK_8211CL) { 654 axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0005); 655 axe_uno_mii_write_reg(un, un->un_phyno, 0x0C, 0x0000); 656 axe_uno_mii_read_reg(un, un->un_phyno, 0x0001, &val); 657 axe_uno_mii_write_reg(un, un->un_phyno, 0x01, val | 0x0080); 658 axe_uno_mii_write_reg(un, un->un_phyno, 0x1F, 0x0000); 659 } 660 break; 661 default: 662 /* Unknown PHY model or no need to program GPIOs. */ 663 break; 664 } 665 666 /* soft reset */ 667 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 668 usbd_delay_ms(un->un_udev, 150); 669 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 670 AXE_SW_RESET_PRL | AXE_178_RESET_MAGIC, NULL); 671 usbd_delay_ms(un->un_udev, 150); 672 /* Enable MII/GMII/RGMII interface to work with external PHY. */ 673 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 0, NULL); 674 usbd_delay_ms(un->un_udev, 10); 675 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 676} 677 678static void 679axe_ax88772_init(struct axe_softc *sc) 680{ 681 AXEHIST_FUNC(); AXEHIST_CALLED(); 682 struct usbnet * const un = &sc->axe_un; 683 684 axe_cmd(sc, AXE_CMD_WRITE_GPIO, 0, 0x00b0, NULL); 685 usbd_delay_ms(un->un_udev, 40); 686 687 if (un->un_phyno == AXE_772_PHY_NO_EPHY) { 688 /* ask for the embedded PHY */ 689 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 690 AXE_SW_PHY_SELECT_EMBEDDED, NULL); 691 usbd_delay_ms(un->un_udev, 10); 692 693 /* power down and reset state, pin reset state */ 694 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 695 usbd_delay_ms(un->un_udev, 60); 696 697 /* power down/reset state, pin operating state */ 698 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 699 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 700 usbd_delay_ms(un->un_udev, 150); 701 702 /* power up, reset */ 703 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRL, NULL); 704 705 /* power up, operating */ 706 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 707 AXE_SW_RESET_IPRL | AXE_SW_RESET_PRL, NULL); 708 } else { 709 /* ask for external PHY */ 710 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_EXT, 711 NULL); 712 usbd_delay_ms(un->un_udev, 10); 713 714 /* power down internal PHY */ 715 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, 716 AXE_SW_RESET_IPPD | AXE_SW_RESET_PRL, NULL); 717 } 718 719 usbd_delay_ms(un->un_udev, 150); 720 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 721} 722 723static void 724axe_ax88772_phywake(struct axe_softc *sc) 725{ 726 AXEHIST_FUNC(); AXEHIST_CALLED(); 727 struct usbnet * const un = &sc->axe_un; 728 729 if (un->un_phyno == AXE_772_PHY_NO_EPHY) { 730 /* Manually select internal(embedded) PHY - MAC mode. */ 731 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, 732 AXE_SW_PHY_SELECT_EMBEDDED, NULL); 733 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 734 } else { 735 /* 736 * Manually select external PHY - MAC mode. 737 * Reverse MII/RMII is for AX88772A PHY mode. 738 */ 739 axe_cmd(sc, AXE_CMD_SW_PHY_SELECT, 0, AXE_SW_PHY_SELECT_SS_ENB | 740 AXE_SW_PHY_SELECT_EXT | AXE_SW_PHY_SELECT_SS_MII, NULL); 741 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 742 } 743 744 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPPD | 745 AXE_SW_RESET_IPRL, NULL); 746 747 /* T1 = min 500ns everywhere */ 748 usbd_delay_ms(un->un_udev, 150); 749 750 /* Take PHY out of power down. */ 751 if (un->un_phyno == AXE_772_PHY_NO_EPHY) { 752 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL); 753 } else { 754 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_PRTE, NULL); 755 } 756 757 /* 772 T2 is 60ms. 772A T2 is 160ms, 772B T2 is 600ms */ 758 usbd_delay_ms(un->un_udev, 600); 759 760 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_CLEAR, NULL); 761 762 /* T3 = 500ns everywhere */ 763 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 764 axe_cmd(sc, AXE_CMD_SW_RESET_REG, 0, AXE_SW_RESET_IPRL, NULL); 765 usbd_delay_ms(un->un_udev, hztoms(hz / 32)); 766} 767 768static void 769axe_ax88772a_init(struct axe_softc *sc) 770{ 771 AXEHIST_FUNC(); AXEHIST_CALLED(); 772 773 /* Reload EEPROM. */ 774 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM, hz / 32); 775 axe_ax88772_phywake(sc); 776 /* Stop MAC. */ 777 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 778} 779 780static void 781axe_ax88772b_init(struct axe_softc *sc) 782{ 783 AXEHIST_FUNC(); AXEHIST_CALLED(); 784 struct usbnet * const un = &sc->axe_un; 785 uint16_t eeprom; 786 int i; 787 788 /* Reload EEPROM. */ 789 AXE_GPIO_WRITE(AXE_GPIO_RELOAD_EEPROM , hz / 32); 790 791 /* 792 * Save PHY power saving configuration(high byte) and 793 * clear EEPROM checksum value(low byte). 794 */ 795 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, AXE_EEPROM_772B_PHY_PWRCFG, 796 &eeprom)) { 797 aprint_error_dev(un->un_dev, "failed to read eeprom\n"); 798 return; 799 } 800 801 sc->sc_pwrcfg = le16toh(eeprom) & 0xFF00; 802 803 /* 804 * Auto-loaded default station address from internal ROM is 805 * 00:00:00:00:00:00 such that an explicit access to EEPROM 806 * is required to get real station address. 807 */ 808 uint8_t *eaddr = un->un_eaddr; 809 for (i = 0; i < ETHER_ADDR_LEN / 2; i++) { 810 if (axe_cmd(sc, AXE_CMD_SROM_READ, 0, 811 AXE_EEPROM_772B_NODE_ID + i, &eeprom)) { 812 aprint_error_dev(un->un_dev, 813 "failed to read eeprom\n"); 814 eeprom = 0; 815 } 816 eeprom = le16toh(eeprom); 817 *eaddr++ = (uint8_t)(eeprom & 0xFF); 818 *eaddr++ = (uint8_t)((eeprom >> 8) & 0xFF); 819 } 820 /* Wakeup PHY. */ 821 axe_ax88772_phywake(sc); 822 /* Stop MAC. */ 823 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, 0, NULL); 824} 825 826#undef AXE_GPIO_WRITE 827 828/* 829 * Probe for a AX88172 chip. 830 */ 831static int 832axe_match(device_t parent, cfdata_t match, void *aux) 833{ 834 struct usb_attach_arg *uaa = aux; 835 836 return axe_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 837 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 838} 839 840/* 841 * Attach the interface. Allocate softc structures, do ifmedia 842 * setup and ethernet/BPF attach. 843 */ 844static void 845axe_attach(device_t parent, device_t self, void *aux) 846{ 847 AXEHIST_FUNC(); AXEHIST_CALLED(); 848 USBNET_MII_DECL_DEFAULT(unm); 849 struct axe_softc *sc = device_private(self); 850 struct usbnet * const un = &sc->axe_un; 851 struct usb_attach_arg *uaa = aux; 852 struct usbd_device *dev = uaa->uaa_device; 853 usbd_status err; 854 usb_interface_descriptor_t *id; 855 usb_endpoint_descriptor_t *ed; 856 char *devinfop; 857 unsigned bufsz; 858 int i; 859 860 KASSERT((void *)sc == un); 861 862 aprint_naive("\n"); 863 aprint_normal("\n"); 864 devinfop = usbd_devinfo_alloc(dev, 0); 865 aprint_normal_dev(self, "%s\n", devinfop); 866 usbd_devinfo_free(devinfop); 867 868 un->un_dev = self; 869 un->un_udev = dev; 870 un->un_sc = sc; 871 un->un_ops = &axe_ops; 872 un->un_rx_xfer_flags = USBD_SHORT_XFER_OK; 873 un->un_tx_xfer_flags = USBD_FORCE_SHORT_XFER; 874 un->un_rx_list_cnt = AXE_RX_LIST_CNT; 875 un->un_tx_list_cnt = AXE_TX_LIST_CNT; 876 877 err = usbd_set_config_no(dev, AXE_CONFIG_NO, 1); 878 if (err) { 879 aprint_error_dev(self, "failed to set configuration" 880 ", err=%s\n", usbd_errstr(err)); 881 return; 882 } 883 884 un->un_flags = axe_lookup(uaa->uaa_vendor, uaa->uaa_product)->axe_flags; 885 886 err = usbd_device2interface_handle(dev, AXE_IFACE_IDX, &un->un_iface); 887 if (err) { 888 aprint_error_dev(self, "getting interface handle failed\n"); 889 return; 890 } 891 892 id = usbd_get_interface_descriptor(un->un_iface); 893 894 /* decide on what our bufsize will be */ 895 if (AXE_IS_172(un)) 896 bufsz = AXE_172_BUFSZ; 897 else 898 bufsz = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? 899 AXE_178_MAX_BUFSZ : AXE_178_MIN_BUFSZ; 900 un->un_rx_bufsz = un->un_tx_bufsz = bufsz; 901 902 un->un_ed[USBNET_ENDPT_RX] = 0; 903 un->un_ed[USBNET_ENDPT_TX] = 0; 904 un->un_ed[USBNET_ENDPT_INTR] = 0; 905 906 /* Find endpoints. */ 907 for (i = 0; i < id->bNumEndpoints; i++) { 908 ed = usbd_interface2endpoint_descriptor(un->un_iface, i); 909 if (ed == NULL) { 910 aprint_error_dev(self, "couldn't get ep %d\n", i); 911 return; 912 } 913 const uint8_t xt = UE_GET_XFERTYPE(ed->bmAttributes); 914 const uint8_t dir = UE_GET_DIR(ed->bEndpointAddress); 915 916 if (dir == UE_DIR_IN && xt == UE_BULK && 917 un->un_ed[USBNET_ENDPT_RX] == 0) { 918 un->un_ed[USBNET_ENDPT_RX] = ed->bEndpointAddress; 919 } else if (dir == UE_DIR_OUT && xt == UE_BULK && 920 un->un_ed[USBNET_ENDPT_TX] == 0) { 921 un->un_ed[USBNET_ENDPT_TX] = ed->bEndpointAddress; 922 } else if (dir == UE_DIR_IN && xt == UE_INTERRUPT) { 923 un->un_ed[USBNET_ENDPT_INTR] = ed->bEndpointAddress; 924 } 925 } 926 927 /* Set these up now for axe_cmd(). */ 928 usbnet_attach(un); 929 930 /* We need the PHYID for init dance in some cases */ 931 if (axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, &sc->axe_phyaddrs)) { 932 aprint_error_dev(self, "failed to read phyaddrs\n"); 933 return; 934 } 935 936 DPRINTF(" phyaddrs[0]: %jx phyaddrs[1]: %jx", 937 sc->axe_phyaddrs[0], sc->axe_phyaddrs[1], 0, 0); 938 un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); 939 if (un->un_phyno == -1) 940 un->un_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); 941 if (un->un_phyno == -1) { 942 DPRINTF(" no valid PHY address found, assuming PHY address 0", 943 0, 0, 0, 0); 944 un->un_phyno = 0; 945 } 946 947 /* Initialize controller and get station address. */ 948 949 axe_ax_init(un); 950 951 /* 952 * Fetch IPG values. 953 */ 954 if (un->un_flags & (AX772A | AX772B)) { 955 /* Set IPG values. */ 956 sc->axe_ipgs[0] = AXE_IPG0_DEFAULT; 957 sc->axe_ipgs[1] = AXE_IPG1_DEFAULT; 958 sc->axe_ipgs[2] = AXE_IPG2_DEFAULT; 959 } else { 960 if (axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->axe_ipgs)) { 961 aprint_error_dev(self, "failed to read ipg\n"); 962 return; 963 } 964 } 965 966 if (!AXE_IS_172(un)) 967 usbnet_ec(un)->ec_capabilities = ETHERCAP_VLAN_MTU; 968 if (un->un_flags & AX772B) { 969 struct ifnet *ifp = usbnet_ifp(un); 970 971 ifp->if_capabilities = 972 IFCAP_CSUM_IPv4_Rx | 973 IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx | 974 IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx; 975 /* 976 * Checksum offloading of AX88772B also works with VLAN 977 * tagged frames but there is no way to take advantage 978 * of the feature because vlan(4) assumes 979 * IFCAP_VLAN_HWTAGGING is prerequisite condition to 980 * support checksum offloading with VLAN. VLAN hardware 981 * tagging support of AX88772B is very limited so it's 982 * not possible to announce IFCAP_VLAN_HWTAGGING. 983 */ 984 } 985 if (un->un_flags & (AX772A | AX772B | AX178)) 986 unm.un_mii_flags = MIIF_DOPAUSE; 987 988 usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST, 989 0, &unm); 990} 991 992static void 993axe_uno_rx_loop(struct usbnet * un, struct usbnet_chain *c, uint32_t total_len) 994{ 995 AXEHIST_FUNC(); AXEHIST_CALLED(); 996 struct axe_softc * const sc = usbnet_softc(un); 997 struct ifnet *ifp = usbnet_ifp(un); 998 uint8_t *buf = c->unc_buf; 999 1000 do { 1001 u_int pktlen = 0; 1002 u_int rxlen = 0; 1003 int flags = 0; 1004 1005 if ((un->un_flags & AXSTD_FRAME) != 0) { 1006 struct axe_sframe_hdr hdr; 1007 1008 if (total_len < sizeof(hdr)) { 1009 if_statinc(ifp, if_ierrors); 1010 break; 1011 } 1012 1013 memcpy(&hdr, buf, sizeof(hdr)); 1014 1015 DPRINTFN(20, "total_len %#jx len %#jx ilen %#jx", 1016 total_len, 1017 (le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK), 1018 (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK), 0); 1019 1020 total_len -= sizeof(hdr); 1021 buf += sizeof(hdr); 1022 1023 if (((le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK) ^ 1024 (le16toh(hdr.ilen) & AXE_RH1M_RXLEN_MASK)) != 1025 AXE_RH1M_RXLEN_MASK) { 1026 if_statinc(ifp, if_ierrors); 1027 break; 1028 } 1029 1030 rxlen = le16toh(hdr.len) & AXE_RH1M_RXLEN_MASK; 1031 if (total_len < rxlen) { 1032 pktlen = total_len; 1033 total_len = 0; 1034 } else { 1035 pktlen = rxlen; 1036 rxlen = roundup2(rxlen, 2); 1037 total_len -= rxlen; 1038 } 1039 1040 } else if ((un->un_flags & AXCSUM_FRAME) != 0) { 1041 struct axe_csum_hdr csum_hdr; 1042 1043 if (total_len < sizeof(csum_hdr)) { 1044 if_statinc(ifp, if_ierrors); 1045 break; 1046 } 1047 1048 memcpy(&csum_hdr, buf, sizeof(csum_hdr)); 1049 1050 csum_hdr.len = le16toh(csum_hdr.len); 1051 csum_hdr.ilen = le16toh(csum_hdr.ilen); 1052 csum_hdr.cstatus = le16toh(csum_hdr.cstatus); 1053 1054 DPRINTFN(20, "total_len %#jx len %#jx ilen %#jx" 1055 " cstatus %#jx", total_len, 1056 csum_hdr.len, csum_hdr.ilen, csum_hdr.cstatus); 1057 1058 if ((AXE_CSUM_RXBYTES(csum_hdr.len) ^ 1059 AXE_CSUM_RXBYTES(csum_hdr.ilen)) != 1060 sc->sc_lenmask) { 1061 /* we lost sync */ 1062 if_statinc(ifp, if_ierrors); 1063 DPRINTFN(20, "len %#jx ilen %#jx lenmask %#jx " 1064 "err", 1065 AXE_CSUM_RXBYTES(csum_hdr.len), 1066 AXE_CSUM_RXBYTES(csum_hdr.ilen), 1067 sc->sc_lenmask, 0); 1068 break; 1069 } 1070 /* 1071 * Get total transferred frame length including 1072 * checksum header. The length should be multiple 1073 * of 4. 1074 */ 1075 pktlen = AXE_CSUM_RXBYTES(csum_hdr.len); 1076 u_int len = sizeof(csum_hdr) + pktlen; 1077 len = (len + 3) & ~3; 1078 if (total_len < len) { 1079 DPRINTFN(20, "total_len %#jx < len %#jx", 1080 total_len, len, 0, 0); 1081 /* invalid length */ 1082 if_statinc(ifp, if_ierrors); 1083 break; 1084 } 1085 buf += sizeof(csum_hdr); 1086 1087 const uint16_t cstatus = csum_hdr.cstatus; 1088 1089 if (cstatus & AXE_CSUM_HDR_L3_TYPE_IPV4) { 1090 if (cstatus & AXE_CSUM_HDR_L4_CSUM_ERR) 1091 flags |= M_CSUM_TCP_UDP_BAD; 1092 if (cstatus & AXE_CSUM_HDR_L3_CSUM_ERR) 1093 flags |= M_CSUM_IPv4_BAD; 1094 1095 const uint16_t l4type = 1096 cstatus & AXE_CSUM_HDR_L4_TYPE_MASK; 1097 1098 if (l4type == AXE_CSUM_HDR_L4_TYPE_TCP) 1099 flags |= M_CSUM_TCPv4; 1100 if (l4type == AXE_CSUM_HDR_L4_TYPE_UDP) 1101 flags |= M_CSUM_UDPv4; 1102 } 1103 if (total_len < len) { 1104 pktlen = total_len; 1105 total_len = 0; 1106 } else { 1107 total_len -= len; 1108 rxlen = len - sizeof(csum_hdr); 1109 } 1110 DPRINTFN(20, "total_len %#jx len %#jx pktlen %#jx" 1111 " rxlen %#jx", total_len, len, pktlen, rxlen); 1112 } else { /* AX172 */ 1113 pktlen = rxlen = total_len; 1114 total_len = 0; 1115 } 1116 1117 usbnet_enqueue(un, buf, pktlen, flags, 0, 0); 1118 buf += rxlen; 1119 1120 } while (total_len > 0); 1121 1122 DPRINTFN(10, "start rx", 0, 0, 0, 0); 1123} 1124 1125static unsigned 1126axe_uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 1127{ 1128 AXEHIST_FUNC(); AXEHIST_CALLED(); 1129 struct axe_sframe_hdr hdr, tlr; 1130 size_t hdr_len = 0, tlr_len = 0; 1131 int length, boundary; 1132 1133 if (!AXE_IS_172(un)) { 1134 /* 1135 * Copy the mbuf data into a contiguous buffer, leaving two 1136 * bytes at the beginning to hold the frame length. 1137 */ 1138 boundary = (un->un_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64; 1139 1140 hdr.len = htole16(m->m_pkthdr.len); 1141 hdr.ilen = ~hdr.len; 1142 hdr_len = sizeof(hdr); 1143 1144 length = hdr_len + m->m_pkthdr.len; 1145 1146 if ((length % boundary) == 0) { 1147 tlr.len = 0x0000; 1148 tlr.ilen = 0xffff; 1149 tlr_len = sizeof(tlr); 1150 } 1151 DPRINTFN(20, "length %jx m_pkthdr.len %jx hdrsize %#jx", 1152 length, m->m_pkthdr.len, sizeof(hdr), 0); 1153 } 1154 1155 if ((unsigned)m->m_pkthdr.len > un->un_tx_bufsz - hdr_len - tlr_len) 1156 return 0; 1157 length = hdr_len + m->m_pkthdr.len + tlr_len; 1158 1159 if (hdr_len) 1160 memcpy(c->unc_buf, &hdr, hdr_len); 1161 m_copydata(m, 0, m->m_pkthdr.len, c->unc_buf + hdr_len); 1162 if (tlr_len) 1163 memcpy(c->unc_buf + length - tlr_len, &tlr, tlr_len); 1164 1165 return length; 1166} 1167 1168static void 1169axe_csum_cfg(struct axe_softc *sc) 1170{ 1171 struct usbnet * const un = &sc->axe_un; 1172 struct ifnet * const ifp = usbnet_ifp(un); 1173 uint16_t csum1, csum2; 1174 1175 if ((un->un_flags & AX772B) != 0) { 1176 csum1 = 0; 1177 csum2 = 0; 1178 if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Tx) != 0) 1179 csum1 |= AXE_TXCSUM_IP; 1180 if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Tx) != 0) 1181 csum1 |= AXE_TXCSUM_TCP; 1182 if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Tx) != 0) 1183 csum1 |= AXE_TXCSUM_UDP; 1184 if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Tx) != 0) 1185 csum1 |= AXE_TXCSUM_TCPV6; 1186 if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Tx) != 0) 1187 csum1 |= AXE_TXCSUM_UDPV6; 1188 axe_cmd(sc, AXE_772B_CMD_WRITE_TXCSUM, csum2, csum1, NULL); 1189 csum1 = 0; 1190 csum2 = 0; 1191 1192 if ((ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) != 0) 1193 csum1 |= AXE_RXCSUM_IP; 1194 if ((ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) != 0) 1195 csum1 |= AXE_RXCSUM_TCP; 1196 if ((ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) != 0) 1197 csum1 |= AXE_RXCSUM_UDP; 1198 if ((ifp->if_capenable & IFCAP_CSUM_TCPv6_Rx) != 0) 1199 csum1 |= AXE_RXCSUM_TCPV6; 1200 if ((ifp->if_capenable & IFCAP_CSUM_UDPv6_Rx) != 0) 1201 csum1 |= AXE_RXCSUM_UDPV6; 1202 axe_cmd(sc, AXE_772B_CMD_WRITE_RXCSUM, csum2, csum1, NULL); 1203 } 1204} 1205 1206static int 1207axe_uno_init(struct ifnet *ifp) 1208{ 1209 AXEHIST_FUNC(); AXEHIST_CALLED(); 1210 struct usbnet * const un = ifp->if_softc; 1211 struct axe_softc * const sc = usbnet_softc(un); 1212 int rxmode; 1213 1214 /* Reset the ethernet interface. */ 1215 axe_reset(un); 1216 1217#if 0 1218 ret = asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | 1219 AX_GPIO_GPO2EN, 5, in_pm); 1220#endif 1221 /* Set MAC address and transmitter IPG values. */ 1222 if (AXE_IS_172(un)) { 1223 axe_cmd(sc, AXE_172_CMD_WRITE_NODEID, 0, 0, un->un_eaddr); 1224 axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->axe_ipgs[0], NULL); 1225 axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->axe_ipgs[1], NULL); 1226 axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->axe_ipgs[2], NULL); 1227 } else { 1228 axe_cmd(sc, AXE_178_CMD_WRITE_NODEID, 0, 0, un->un_eaddr); 1229 axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->axe_ipgs[2], 1230 (sc->axe_ipgs[1] << 8) | (sc->axe_ipgs[0]), NULL); 1231 1232 un->un_flags &= ~(AXSTD_FRAME | AXCSUM_FRAME); 1233 if ((un->un_flags & AX772B) != 0 && 1234 (ifp->if_capenable & AX_RXCSUM) != 0) { 1235 sc->sc_lenmask = AXE_CSUM_HDR_LEN_MASK; 1236 un->un_flags |= AXCSUM_FRAME; 1237 } else { 1238 sc->sc_lenmask = AXE_HDR_LEN_MASK; 1239 un->un_flags |= AXSTD_FRAME; 1240 } 1241 } 1242 1243 /* Configure TX/RX checksum offloading. */ 1244 axe_csum_cfg(sc); 1245 1246 if (un->un_flags & AX772B) { 1247 /* AX88772B uses different maximum frame burst configuration. */ 1248 axe_cmd(sc, AXE_772B_CMD_RXCTL_WRITE_CFG, 1249 ax88772b_mfb_table[AX88772B_MFB_16K].threshold, 1250 ax88772b_mfb_table[AX88772B_MFB_16K].byte_cnt, NULL); 1251 } 1252 /* Enable receiver, set RX mode */ 1253 rxmode = (AXE_RXCMD_BROADCAST | AXE_RXCMD_MULTICAST | AXE_RXCMD_ENABLE); 1254 if (AXE_IS_172(un)) 1255 rxmode |= AXE_172_RXCMD_UNICAST; 1256 else { 1257 if (un->un_flags & AX772B) { 1258 /* 1259 * Select RX header format type 1. Aligning IP 1260 * header on 4 byte boundary is not needed when 1261 * checksum offloading feature is not used 1262 * because we always copy the received frame in 1263 * RX handler. When RX checksum offloading is 1264 * active, aligning IP header is required to 1265 * reflect actual frame length including RX 1266 * header size. 1267 */ 1268 rxmode |= AXE_772B_RXCMD_HDR_TYPE_1; 1269 if (un->un_flags & AXCSUM_FRAME) 1270 rxmode |= AXE_772B_RXCMD_IPHDR_ALIGN; 1271 } else { 1272 /* 1273 * Default Rx buffer size is too small to get 1274 * maximum performance. 1275 */ 1276#if 0 1277 if (un->un_udev->ud_speed == USB_SPEED_HIGH) { 1278 /* Largest possible USB buffer size for AX88178 */ 1279 } 1280#endif 1281 rxmode |= AXE_178_RXCMD_MFB_16384; 1282 } 1283 } 1284 1285 DPRINTF("rxmode %#jx", rxmode, 0, 0, 0); 1286 1287 axe_cmd(sc, AXE_CMD_RXCTL_WRITE, 0, rxmode, NULL); 1288 1289 return 0; 1290} 1291 1292static void 1293axe_uno_stop(struct ifnet *ifp, int disable) 1294{ 1295 struct usbnet * const un = ifp->if_softc; 1296 1297 axe_reset(un); 1298} 1299 1300#ifdef _MODULE 1301#include "ioconf.c" 1302#endif 1303 1304USBNET_MODULE(axe) 1305