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;