I've recently acquired a usb3.0->gigabit ethernet adapter. It did not attach reliably, pass traffic reliably, and it made my machine panic when I unplugged it. Takahiro HAYASHI suggested that the reset code doesn't do anything and that it should initialize the chip. Indeed that does seem to help. I also adopted a change that netbsd made to lock the mii before trying to write to it during initialization.
It appears that the eeprom code is going to be left to rot, so I deleted that as well. I've only been able to test this on my device. Feedback is welcomed. Index: dev/usb/if_axen.c =================================================================== RCS file: /home/bmercer/cvs/src/sys/dev/usb/if_axen.c,v retrieving revision 1.20 diff -u -p -u -p -r1.20 if_axen.c --- dev/usb/if_axen.c 25 Nov 2015 03:10:00 -0000 1.20 +++ dev/usb/if_axen.c 19 Mar 2016 20:31:13 -0000 @@ -115,10 +115,6 @@ int axen_cmd(struct axen_softc *, int, i int axen_ifmedia_upd(struct ifnet *); void axen_ifmedia_sts(struct ifnet *, struct ifmediareq *); void axen_reset(struct axen_softc *sc); -#if 0 /* not used */ -int axen_ax88179_eeprom(struct axen_softc *, void *); -#endif - void axen_iff(struct axen_softc *); void axen_lock_mii(struct axen_softc *sc); void axen_unlock_mii(struct axen_softc *sc); @@ -399,69 +395,13 @@ axen_reset(struct axen_softc *sc) if (usbd_is_dying(sc->axen_udev)) return; /* XXX What to reset? */ + axen_ax88179_init(sc); /* Wait a little while for the chip to get its brains in order. */ DELAY(1000); return; } -#if 0 /* not used */ -#define AXEN_GPIO_WRITE(x,y) do { \ - axen_cmd(sc, AXEN_CMD_WRITE_GPIO, 0, (x), NULL); \ - usbd_delay_ms(sc->axen_udev, (y)); \ -} while (0) - -int -axen_ax88179_eeprom(struct axen_softc *sc, void *addr) -{ - int i, retry; - uWord buf; - uint8_t eeprom[20]; - uint16_t csum; - - for (i = 0; i < 6; i++) { - /* set eeprom address */ - USETW(buf, i); - axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_ADDR, buf); - - /* set eeprom command */ - USETW(buf, AXEN_EEPROM_READ); - axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_MAC_EEPROM_CMD, buf); - - /* check the value is ready */ - retry = 3; - do { - USETW(buf, AXEN_EEPROM_READ); - usbd_delay_ms(sc->axen_udev, 10); - axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_MAC_EEPROM_CMD, - buf); - retry--; - if (retry < 0) - return EINVAL; - } while ((UGETW(buf) & 0xff) & AXEN_EEPROM_BUSY); - - /* read data */ - axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_EEPROM_READ, - &eeprom[i * 2]); - - /* sanity check */ - if ((i == 0) && (eeprom[0] == 0xff)) - return EINVAL; - } - - /* check checksum */ - csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9]; - csum = (csum >> 8) + (csum & 0xff) + eeprom[10]; - if (csum != 0xff) { - printf("eeprom checksum mismatchi(0x%02x)\n", csum); - return EINVAL; - } - - memcpy(addr, eeprom, ETHER_ADDR_LEN); - return 0; -} -#endif - void axen_ax88179_init(struct axen_softc *sc) { @@ -720,16 +660,10 @@ axen_attach(struct device *parent, struc /* * Get station address. */ -#if 0 /* read from eeprom */ - if (axen_ax88179_eeprom(sc, &eaddr)) { - printf("EEPROM checksum error\n"); - return; - } -#else /* use MAC command */ + /* use MAC command */ axen_lock_mii(sc); axen_cmd(sc, AXEN_CMD_MAC_READ_ETHER, 6, AXEN_CMD_MAC_NODE_ID, &eaddr); axen_unlock_mii(sc); -#endif axen_ax88179_init(sc); @@ -1321,7 +1255,9 @@ axen_init(void *xsc) /* XXX: ? */ bval = 0x01; + axen_lock_mii(sc); axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_UNK_28, &bval); + axen_unlock_mii(sc); /* Init RX ring. */ if (axen_rx_list_init(sc) == ENOBUFS) {