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