aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2020-07-03 20:17:25 +0100
committerMichael Brown <mcb30@ipxe.org>2020-07-03 20:23:39 +0100
commitf727ed8a112355c964b25a472e6da361864ee574 (patch)
treef4681138f6abf1c799e8d4ec482c18ad9872f11e
parent0f5d23433514de62eca1fadceb8c31df5c569431 (diff)
downloadipxe-f727ed8a112355c964b25a472e6da361864ee574.zip
ipxe-f727ed8a112355c964b25a472e6da361864ee574.tar.gz
ipxe-f727ed8a112355c964b25a472e6da361864ee574.tar.bz2
[axge] Reapply USB device configuration when opening network device
When connected to a USB3 port, the AX88179 seems to have an approximately 50% chance of producing a USB transaction error on each of its three endpoints after being closed and reopened. The root cause is unclear, but rewriting the USB device configuration value seems to clear whatever internal error state has accumulated. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/drivers/net/axge.c9
-rw-r--r--src/drivers/net/axge.h2
2 files changed, 11 insertions, 0 deletions
diff --git a/src/drivers/net/axge.c b/src/drivers/net/axge.c
index 1106c1e..fb274d2 100644
--- a/src/drivers/net/axge.c
+++ b/src/drivers/net/axge.c
@@ -531,6 +531,13 @@ static int axge_open ( struct net_device *netdev ) {
uint16_t rcr;
int rc;
+ /* Reapply device configuration to avoid transaction errors */
+ if ( ( rc = usb_set_configuration ( axge->usb, axge->config ) ) != 0 ) {
+ DBGC ( axge, "AXGE %p could not set configuration: %s\n",
+ axge, strerror ( rc ) );
+ goto err_set_configuration;
+ }
+
/* Open USB network device */
if ( ( rc = usbnet_open ( &axge->usbnet ) ) != 0 ) {
DBGC ( axge, "AXGE %p could not open: %s\n",
@@ -567,6 +574,7 @@ static int axge_open ( struct net_device *netdev ) {
err_write_mac:
usbnet_close ( &axge->usbnet );
err_open:
+ err_set_configuration:
return rc;
}
@@ -674,6 +682,7 @@ static int axge_probe ( struct usb_function *func,
axge->usb = usb;
axge->bus = usb->port->hub->bus;
axge->netdev = netdev;
+ axge->config = config->config;
usbnet_init ( &axge->usbnet, func, &axge_intr_operations,
&axge_in_operations, &axge_out_operations );
usb_refill_init ( &axge->usbnet.intr, 0, 0, AXGE_INTR_MAX_FILL );
diff --git a/src/drivers/net/axge.h b/src/drivers/net/axge.h
index 6183b4e..e22e0ec 100644
--- a/src/drivers/net/axge.h
+++ b/src/drivers/net/axge.h
@@ -145,6 +145,8 @@ struct axge_device {
struct net_device *netdev;
/** USB network device */
struct usbnet_device usbnet;
+ /** Device configuration */
+ unsigned int config;
/** Link state has changed */
int check_link;
};