Hi, On 2018/08/14 08:19, Denis wrote: > I have 6.3 kernel compiled with option XHCI_debug and axen2.diff > implemented. > > I'm using lladdr option for /etc/hostname.axen0 to have the same IP addr > each session for different Ehternet adapters. > > Here is debug output when axen is connected:
Thank you for sending report. It looks someone (maybe DHCP) makes the interface down and up repeatedly. That causes TXERR (transaction error) on RX pipe. I guess there is something inconsistent between the state of xhci and the device. xhci spec 1.1 sec 4.3.5 requires the driver shall do set_config and configure endpoint. I added set_config part to axen2.diff and attached as axen3.diff. Can you try attached axen3.diff? Thanks. > > xhci0: port=2 change=0x04 > xhci0: port=2 change=0x04 > xhci0: xhci_cmd_slot_control > xhci0: dev 1, input=0xffffff0001988000 slot=0xffffff0001988020 > ep0=0xffffff0001988040 > xhci0: dev 1, setting DCBAA to 0x0000000001989000 > xhci_pipe_init: pipe=0xffff800000a8d000 addr=0 depth=1 port=2 speed=4 > dev 1 dci 1 (epAddr=0x0) > xhci0: xhci_cmd_set_address BSR=1 > xhci0: xhci_cmd_set_address BSR=0 > xhci0: dev 1 addr 1 > axen0 at uhub0 port 2 configuration 1 interface 0 "ASIX Elec. Corp. > AX88179" rev 3.00/1.00 addr 2 > axen0: AX88179, address xx:xx:xx:xx:xx:xx > ukphy0 at axen0 phy 3: Generic IEEE 802.3u media interface, rev. 5: OUI > 0x000732, model 0x0011 > xhci_pipe_init: pipe=0xffff800000b38000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 5 (epAddr=0x82) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff800000bfc000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 6 (epAddr=0x3) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_abort_xfer: xfer=0xffffff044e6aee10 status=IN_PROGRESS > err=CANCELLED actlen=0 len=65536 idx=0 > xhci0: xhci_cmd_stop_ep dev 1 dci 5 > xhci_event_xfer: stopped xfer=0xffffff044e6aee10 > xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5 > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff800000b3a000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 5 (epAddr=0x82) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff800000b3e000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 6 (epAddr=0x3) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_abort_xfer: xfer=0xffffff044e6aed20 status=IN_PROGRESS > err=CANCELLED actlen=0 len=65536 idx=42 > xhci0: xhci_cmd_stop_ep dev 1 dci 5 > xhci_event_xfer: stopped xfer=0xffffff044e6aed20 > xhci0: xhci_cmd_set_tr_deq_async dev 1 dci 5 > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff800000790000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 5 (epAddr=0x82) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff800000791000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 6 (epAddr=0x3) > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: txerr? code 4 > axen0: usb errors on rx: IOERROR > xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED > err=CANCELLED actlen=0 len=65536 idx=-1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff8000007a9000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 5 (epAddr=0x82) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff8000007aa000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 6 (epAddr=0x3) > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: txerr? code 4 > axen0: usb errors on rx: IOERROR > xhci0: txerr? code 4 > axen0: usb error on tx: IOERROR > axen0: watchdog timeout > axen0: usb error on tx: IOERROR > xhci_abort_xfer: xfer=0xffffff044e6aed20 status=NOT_STARTED > err=CANCELLED actlen=0 len=65536 idx=-1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff800000865000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 5 (epAddr=0x82) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff800000866000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 6 (epAddr=0x3) > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: txerr? code 4 > axen0: usb errors on rx: IOERROR > xhci0: txerr? code 4 > axen0: usb error on tx: IOERROR > xhci_abort_xfer: xfer=0xffffff044e6aee10 status=NOT_STARTED > err=CANCELLED actlen=0 len=65536 idx=-1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff80000087e000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 5 (epAddr=0x82) > xhci0: xhci_cmd_configure_ep dev 1 > xhci_pipe_init: pipe=0xffff80000087f000 addr=2 depth=1 port=2 speed=4 > dev 1 dci 6 (epAddr=0x3) > xhci0: xhci_cmd_configure_ep dev 1 > xhci0: txerr? code 4 > axen0: usb errors on rx: IOERROR > xhci0: txerr? code 4 > axen0: usb error on tx: IOERROR > axen0: watchdog timeout > >
--- sys/dev/usb/if_axen.c.orig Sun Jan 22 10:17:39 2017 +++ sys/dev/usb/if_axen.c Tue Aug 14 22:11:18 2018 @@ -53,6 +53,7 @@ #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdivar.h> #include <dev/usb/usbdevs.h> +#include <dev/usb/usb_mem.h> #include <dev/usb/if_axenreg.h> @@ -121,6 +122,13 @@ void axen_unlock_mii(struct axen_softc *sc); void axen_ax88179_init(struct axen_softc *); +struct axen_qctrl axen_bulk_size[] = { + { 7, 0x4f, 0x00, 0x12, 0xff }, + { 7, 0x20, 0x03, 0x16, 0xff }, + { 7, 0xae, 0x07, 0x18, 0xff }, + { 7, 0xcc, 0x4c, 0x18, 0x08 } +}; + /* Get exclusive access to the MII registers */ void axen_lock_mii(struct axen_softc *sc) @@ -238,6 +246,8 @@ axen_miibus_statchg(struct device *dev) int err; uint16_t val; uWord wval; + uint8_t linkstat = 0; + int qctrl; ifp = GET_IFP(sc); if (mii == NULL || ifp == NULL || @@ -265,27 +275,49 @@ axen_miibus_statchg(struct device *dev) return; val = 0; - if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { val |= AXEN_MEDIUM_FDX; + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) + val |= AXEN_MEDIUM_TXFLOW_CTRL_EN; + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) + val |= AXEN_MEDIUM_RXFLOW_CTRL_EN; + } - val |= (AXEN_MEDIUM_RECV_EN | AXEN_MEDIUM_ALWAYS_ONE); - val |= (AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN); + val |= AXEN_MEDIUM_RECV_EN; + /* bulkin queue setting */ + axen_lock_mii(sc); + axen_cmd(sc, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &linkstat); + axen_unlock_mii(sc); + switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_1000_T: val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ; + if (linkstat & AXEN_USB_SS) + qctrl = 0; + else if (linkstat & AXEN_USB_HS) + qctrl = 1; + else + qctrl = 3; break; case IFM_100_TX: val |= AXEN_MEDIUM_PS; + if (linkstat & (AXEN_USB_SS | AXEN_USB_HS)) + qctrl = 2; + else + qctrl = 3; break; case IFM_10_T: - /* doesn't need to be handled */ + default: + qctrl = 3; break; } DPRINTF(("axen_miibus_statchg: val=0x%x\n", val)); USETW(wval, val); axen_lock_mii(sc); + axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, + &axen_bulk_size[qctrl]); err = axen_cmd(sc, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval); axen_unlock_mii(sc); if (err) { @@ -408,7 +440,6 @@ axen_ax88179_init(struct axen_softc *sc) uWord wval; uByte val; u_int16_t ctl, temp; - struct axen_qctrl qctrl; axen_lock_mii(sc); @@ -470,34 +501,18 @@ axen_ax88179_init(struct axen_softc *sc) switch (val) { case AXEN_USB_FS: DPRINTF(("uplink: USB1.1\n")); - qctrl.ctrl = 0x07; - qctrl.timer_low = 0xcc; - qctrl.timer_high= 0x4c; - qctrl.bufsize = AXEN_BUFSZ_LS - 1; - qctrl.ifg = 0x08; break; case AXEN_USB_HS: DPRINTF(("uplink: USB2.0\n")); - qctrl.ctrl = 0x07; - qctrl.timer_low = 0x02; - qctrl.timer_high= 0xa0; - qctrl.bufsize = AXEN_BUFSZ_HS - 1; - qctrl.ifg = 0xff; break; case AXEN_USB_SS: DPRINTF(("uplink: USB3.0\n")); - qctrl.ctrl = 0x07; - qctrl.timer_low = 0x4f; - qctrl.timer_high= 0x00; - qctrl.bufsize = AXEN_BUFSZ_SS - 1; - qctrl.ifg = 0xff; break; default: printf("unknown uplink bus:0x%02x\n", val); axen_unlock_mii(sc); return; } - axen_cmd(sc, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL, &qctrl); /* Set MAC address. */ axen_cmd(sc, AXEN_CMD_MAC_WRITE_ETHER, ETHER_ADDR_LEN, @@ -620,22 +635,8 @@ axen_attach(struct device *parent, struct device *self id = usbd_get_interface_descriptor(sc->axen_iface); - /* decide on what our bufsize will be */ - switch (sc->axen_udev->speed) { - case USB_SPEED_FULL: - sc->axen_bufsz = AXEN_BUFSZ_LS * 1024; - break; - case USB_SPEED_HIGH: - sc->axen_bufsz = AXEN_BUFSZ_HS * 1024; - break; - case USB_SPEED_SUPER: - sc->axen_bufsz = AXEN_BUFSZ_SS * 1024; - break; - default: - printf("%s: not supported usb bus type", sc->axen_dev.dv_xname); - return; - } - + sc->axen_bufsz = 64 * 1024; + /* Find endpoints. */ for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->axen_iface, i); @@ -708,7 +709,8 @@ axen_attach(struct device *parent, struct device *self mii->mii_flags = MIIF_AUTOTSLEEP; ifmedia_init(&mii->mii_media, 0, axen_ifmedia_upd, axen_ifmedia_sts); - mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); + mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, + MIIF_DOPAUSE); if (LIST_FIRST(&mii->mii_phys) == NULL) { ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); @@ -806,6 +808,23 @@ axen_newbuf(void) return m; } +static void * +axen_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size) +{ + struct usbd_bus *bus = xfer->device->bus; + usbd_status err; + +#ifdef DIAGNOSTIC + if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) + printf("axen_alloc_buffer: xfer already has a buffer\n"); +#endif + err = usb_allocmem(bus, size, 65536, &xfer->dmabuf); + if (err) + return (NULL); + xfer->rqflags |= URQ_DEV_DMABUF; + return (KERNADDR(&xfer->dmabuf, 0)); +} + int axen_rx_list_init(struct axen_softc *sc) { @@ -825,7 +844,7 @@ axen_rx_list_init(struct axen_softc *sc) c->axen_xfer = usbd_alloc_xfer(sc->axen_udev); if (c->axen_xfer == NULL) return ENOBUFS; - c->axen_buf = usbd_alloc_buffer(c->axen_xfer, + c->axen_buf = axen_alloc_buffer(c->axen_xfer, sc->axen_bufsz); if (c->axen_buf == NULL) { usbd_free_xfer(c->axen_xfer); @@ -856,7 +875,7 @@ axen_tx_list_init(struct axen_softc *sc) c->axen_xfer = usbd_alloc_xfer(sc->axen_udev); if (c->axen_xfer == NULL) return ENOBUFS; - c->axen_buf = usbd_alloc_buffer(c->axen_xfer, + c->axen_buf = axen_alloc_buffer(c->axen_xfer, sc->axen_bufsz); if (c->axen_buf == NULL) { usbd_free_xfer(c->axen_xfer); @@ -1255,6 +1274,14 @@ axen_init(void *xsc) * Cancel pending I/O and free all RX/TX buffers. */ axen_reset(sc); + +#define AXEN_CONFIG_NO 1 +#define AXEN_IFACE_IDX 0 + if (usbd_set_config_no(sc->axen_udev, AXEN_CONFIG_NO, 1) || + usbd_device2interface_handle(sc->axen_udev, AXEN_IFACE_IDX, + &sc->axen_iface)) + printf("%s: set_config failed\n", sc->axen_dev.dv_xname); + usbd_delay_ms(sc->axen_udev, 10); /* XXX: ? */ bval = 0x01;