I've observed poor receive performance in 100baseTx-FD mode from ax8817x devices in all versions of usbnet.c. Half-duplex received performance is actually better than full duplex. After some investigation, I found that the MEDIUM_MODE wasn't being written, and this seems to affect "Pause frame" full duplex flow control.

The attached patch to 2.6.10, which sets the medium mode in an ax8817x_reset function, doubled my full duplex performance (from ~45Mbps to >90Mbps).
--Jamie


--- linux-2.6.10/drivers/usb/net/usbnet.c       2004-12-24 14:34:58.000000000 
-0700
+++ new-2.6.10/drivers/usb/net/usbnet.c 2005-02-13 13:57:06.026817728 -0700
@@ -443,6 +443,7 @@
 #define AX_CMD_WRITE_MULTI_FILTER      0x16
 #define AX_CMD_READ_NODE_ID            0x17
 #define AX_CMD_READ_PHY_ID             0x19
+#define AX_CMD_READ_MEDIUM_STATUS       0x1a
 #define AX_CMD_WRITE_MEDIUM_MODE       0x1b
 #define AX_CMD_READ_MONITOR_MODE       0x1c
 #define AX_CMD_WRITE_MONITOR_MODE      0x1d
@@ -453,6 +454,11 @@
 #define AX_MONITOR_MAGIC               0x04
 #define AX_MONITOR_HSFS                        0x10
 
+// BitMask for MEDIUM_STATUS and MEDIUM_MODE
+#define AX_MEDIUM_FULL_DUPLEX          0x02
+#define AX_MEDIUM_TX_ABORT_ALLOW       0x04
+#define AX_MEDIUM_FLOW_CONTROL_EN      0x10
+
 #define AX_MCAST_FILTER_SIZE           8
 #define AX_MAX_MCAST                   64
 
@@ -832,10 +838,31 @@
        kfree(data->int_buf);
 }
 
+static int ax8817x_reset_mm(struct usbnet *dev) {
+       int lpa;
+       int mode;
+
+       /* Initialize fullduplex flow control */
+       mode = 0;
+       ax8817x_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 1, &mode);
+       devdbg( dev, "Medium status before: 0x%02x", mode );
+
+       mode = AX_MEDIUM_TX_ABORT_ALLOW|AX_MEDIUM_FLOW_CONTROL_EN;
+       lpa = ax8817x_mdio_read(dev->net,dev->mii.phy_id, MII_LPA);
+       if ((lpa & (LPA_100FULL|LPA_100BASE4)) != 0) /* 100baseTx-FD */
+               mode |= AX_MEDIUM_FULL_DUPLEX;
+       ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
+
+       ax8817x_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 1, &mode);
+       devdbg( dev, "Medium status after: 0x%02x", mode );
+       return 0;
+}
+
 static const struct driver_info ax8817x_info = {
        .description = "ASIX AX8817x USB 2.0 Ethernet",
        .bind = ax8817x_bind,
        .unbind = ax8817x_unbind,
+       .reset = ax8817x_reset_mm,
        .flags =  FLAG_ETHER,
        .data = 0x00130103,
 };
@@ -844,6 +871,7 @@
        .description = "DLink DUB-E100 USB Ethernet",
        .bind = ax8817x_bind,
        .unbind = ax8817x_unbind,
+       .reset = ax8817x_reset_mm,
        .flags =  FLAG_ETHER,
        .data = 0x009f9d9f,
 };
@@ -852,6 +880,7 @@
        .description = "Netgear FA-120 USB Ethernet",
        .bind = ax8817x_bind,
        .unbind = ax8817x_unbind,
+       .reset = ax8817x_reset_mm,
        .flags =  FLAG_ETHER,
        .data = 0x00130103,
 };
@@ -860,6 +889,7 @@
        .description = "Hawking UF200 USB Ethernet",
        .bind = ax8817x_bind,
        .unbind = ax8817x_unbind,
+       .reset = ax8817x_reset_mm,
        .flags =  FLAG_ETHER,
        .data = 0x001f1d1f,
 };

Reply via email to