Hi,
On 2018/07/27 09:14, Denis wrote:
Every time (after 2-3 minutes of work) ASIX Electronics USB-Ethernet
device reports:
axen0: usb errors on rx: IOERROR
axen0: usb errors on rx: IOERROR
axen0: usb errors on tx: IOERROR
axen0: watchdog timeout
axen0: usb errors on tx: IOERROR
The device hangs and must be reattached to have it working again for 2-3
minutes.
Do you want to try this patch?
-
- header: fix comments
- header: fix unused L3 type mask definition
- rxeof: Avoid allocating mbuf if checksum errors are detected.
- rxeof: Avoid loop to extract packets if pkt_count is 0.
- rxeof: Add more sanity checks.
- rxeof: Increament if_ierror in some error paths.
- qctrl: Apply queuing control parameters from FreeBSD axge(4).
- qctrl: Set qctrl in miireg_statchg dynamically, not statically.
- Use DMA buffer aligned at 64KB boundary to avoid xhci bug.
--- sys/dev/usb/if_axenreg.hFri Sep 16 22:17:07 2016
+++ sys/dev/usb/if_axenreg.hMon Jun 19 10:54:28 2017
@@ -26,8 +26,8 @@
* || ++-L3_type (1:ipv4, 0/2:ipv6)
*pkt_len(13) || ||+ ++-L4_type(0: icmp, 1: UDP, 4: TCP)
* |765|43210 76543210|7654 3210 7654 3210|
- * ||+-crc_err |+-L4_err |+-L4_CSUM_ERR
- * |+-mii_err +--L3_err +--L3_CSUM_ERR
+ * ||+-crc_err |+-L4_err |+-L4_CSUM_ERR
+ * |+-mii_err+--L3_err +--L3_CSUM_ERR
* +-drop_err
*
* ex) pkt_hdr 0x00680820
@@ -70,7 +70,7 @@
#define AXEN_RXHDR_L4_TYPE_TCP 0x4
/* L3 packet type (2bit) */
-#define AXEN_RXHDR_L3_TYPE_MASK0x0600
+#define AXEN_RXHDR_L3_TYPE_MASK0x0060
#define AXEN_RXHDR_L3_TYPE_OFFSET 5
#define AXEN_RXHDR_L3_TYPE_UNDEF 0x0
#define AXEN_RXHDR_L3_TYPE_IPV4 0x1
--- sys/dev/usb/if_axen.c.orig Tue Jun 12 15:36:59 2018
+++ sys/dev/usb/if_axen.c Sun Jul 29 01:53:43 2018
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
@@ -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_tval;
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);
@@ -471,27 +502,12 @@ axen_ax88179_init(struct axen_so