]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
WIP - cleaner MTU change mtureset
authorMichael Brown <mcb30@ipxe.org>
Tue, 14 Mar 2023 13:37:24 +0000 (13:37 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 14 Mar 2023 13:37:24 +0000 (13:37 +0000)
src/drivers/net/netvsc.c
src/include/ipxe/netdevice.h
src/net/netdev_settings.c
src/net/netdevice.c

index 5be52fb8ec909ac787ab6c13b8c85fe22082337d..f75386825cd43e8f9823317c9f745da71dbaf8b7 100644 (file)
@@ -852,16 +852,9 @@ static int netvsc_reset ( struct vmbus_device *vmdev ) {
        struct net_device *netdev = rndis->netdev;
        int rc;
 
-       /* A closed device holds no NetVSC (or RNDIS) state, so there
-        * is nothing to reset.
-        */
-       if ( ! netdev_is_open ( netdev ) )
-               return 0;
-
-       /* Close and reopen device to reset any stale state */
-       netdev_close ( netdev );
-       if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
-               DBGC ( netvsc, "NETVSC %s could not reopen: %s\n",
+       /* Reset network device */
+       if ( ( rc = netdev_reset ( netdev ) ) != 0 ) {
+               DBGC ( netvsc, "NETVSC %s could not reset: %s\n",
                       netvsc->name, strerror ( rc ) );
                return rc;
        }
index af932c25984ab9ba270901ca100ab973c731491a..0c6fe9c0de430978c5ae674412c347cfae2e46f5 100644 (file)
@@ -723,6 +723,7 @@ extern struct net_device * alloc_netdev ( size_t priv_size );
 extern int register_netdev ( struct net_device *netdev );
 extern int netdev_open ( struct net_device *netdev );
 extern void netdev_close ( struct net_device *netdev );
+extern int netdev_reset ( struct net_device *netdev );
 extern void unregister_netdev ( struct net_device *netdev );
 extern void netdev_irq ( struct net_device *netdev, int enable );
 extern struct net_device * find_netdev ( const char *name );
index fb98663ca0edc1d4b4e8eddd43c6190e52537cea..2c08a6aefff34f2410a03d3caa7633d5d8229009 100644 (file)
@@ -453,11 +453,10 @@ static int apply_netdev_settings ( void ) {
                               netdev->name, mtu );
                }
 
-               /* Close and reopen network device if MTU has increased */
+               /* Reset network device if MTU has increased */
                if ( netdev_is_open ( netdev ) && ( mtu > old_mtu ) ) {
-                       netdev_close ( netdev );
-                       if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
-                               DBGC ( netdev, "NETDEV %s could not reopen: "
+                       if ( ( rc = netdev_reset ( netdev ) ) != 0 ) {
+                               DBGC ( netdev, "NETDEV %s could not reset: "
                                       "%s\n", netdev->name, strerror ( rc ) );
                                return rc;
                        }
index 07961bf2033897d9ae9596b2b5e097f3840ab59d..db33794e57de7d59f756bcc4ddb93d23aa7c11f8 100644 (file)
@@ -612,6 +612,23 @@ static void netdev_rx_flush ( struct net_device *netdev ) {
        }
 }
 
+/**
+ * Flush device's transmit and receive queues
+ *
+ * @v netdev           Network device
+ */
+static void netdev_flush ( struct net_device *netdev ) {
+
+       /* Sanity check */
+       assert ( ! ( netdev->state & NETDEV_OPEN ) );
+
+       /* Flush TX queue */
+       netdev_tx_flush ( netdev );
+
+       /* Flush RX queue */
+       netdev_rx_flush ( netdev );
+}
+
 /**
  * Finish network device configuration
  *
@@ -657,8 +674,7 @@ static void free_netdev ( struct refcnt *refcnt ) {
                container_of ( refcnt, struct net_device, refcnt );
 
        stop_timer ( &netdev->link_block );
-       netdev_tx_flush ( netdev );
-       netdev_rx_flush ( netdev );
+       netdev_flush ( netdev );
        clear_settings ( netdev_settings ( netdev ) );
        free ( netdev );
 }
@@ -880,8 +896,47 @@ void netdev_close ( struct net_device *netdev ) {
        netdev->op->close ( netdev );
 
        /* Flush TX and RX queues */
-       netdev_tx_flush ( netdev );
-       netdev_rx_flush ( netdev );
+       netdev_flush ( netdev );
+}
+
+/**
+ * Reset transmit and receive queues
+ *
+ * @v netdev           Network device
+ * @ret rc             Return status code
+ */
+int netdev_reset ( struct net_device *netdev ) {
+       int rc;
+
+       /* Do nothing unless device is open */
+       if ( ! ( netdev->state & NETDEV_OPEN ) )
+               return 0;
+
+       DBGC ( netdev, "NETDEV %s resetting\n", netdev->name );
+
+       /* Mark as closed */
+       netdev->state &= ~NETDEV_OPEN;
+
+       /* Close the device */
+       netdev->op->close ( netdev );
+
+       /* Flush TX and RX queues */
+       netdev_flush ( netdev );
+
+       /* Mark as opened */
+       netdev->state |= NETDEV_OPEN;
+
+       /* Reopen device */
+       if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
+               goto err;
+
+       return 0;
+
+ err:
+       netdev->state &= ~NETDEV_OPEN;
+       list_del ( &netdev->open_list );
+       netdev_notify ( netdev );
+       return rc;
 }
 
 /**