]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[netdevice] Allow network devices to disclaim IRQ support at runtime
authorMichael Brown <mcb30@ipxe.org>
Tue, 28 Jul 2015 14:05:44 +0000 (15:05 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 28 Jul 2015 14:14:40 +0000 (15:14 +0100)
VLAN and 802.11 devices use a network device operations structure that
wraps an underlying structure.  For example, the vlan_operations
structure wraps the network device operations structure of the
underlying trunk device.  This can cause false positives from the
current implementation of netdev_irq_supported(), which will always
report that VLAN devices support interrupts since it has no visibility
into the support provided by the underlying trunk device.

Fix by allowing network devices to explicitly flag that interrupts are
not supported, despite the presence of an irq() method.

Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/netdevice.h
src/net/80211/net80211.c
src/net/vlan.c

index f20a81f79c1196377aa31827621b043eb5e33720..a1d207ffc47dcae88aacd0e34487c455e79eb4a6 100644 (file)
@@ -430,6 +430,14 @@ struct net_device {
 /** Network device receive queue processing is frozen */
 #define NETDEV_RX_FROZEN 0x0004
 
+/** Network device interrupts are unsupported
+ *
+ * This flag can be used by a network device to indicate that
+ * interrupts are not supported despite the presence of an irq()
+ * method.
+ */
+#define NETDEV_IRQ_UNSUPPORTED 0x0008
+
 /** Link-layer protocol table */
 #define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
 
@@ -646,7 +654,8 @@ netdev_is_open ( struct net_device *netdev ) {
  */
 static inline __attribute__ (( always_inline )) int
 netdev_irq_supported ( struct net_device *netdev ) {
-       return ( netdev->op->irq != NULL );
+       return ( ( netdev->op->irq != NULL ) &&
+                ! ( netdev->state & NETDEV_IRQ_UNSUPPORTED ) );
 }
 
 /**
index 00794592eaa981c3f7795ea2b4547fb583a8dcad..d4970ad5c571b8fa731bafe24e1927e3d3eb801a 100644 (file)
@@ -805,6 +805,10 @@ int net80211_register ( struct net80211_device *dev,
                 NET80211_MAX_CHANNELS * sizeof ( dev->channels[0] ) );
        dev->channel = 0;
 
+       /* Mark device as not supporting interrupts, if applicable */
+       if ( ! ops->irq )
+               dev->netdev->state |= NETDEV_IRQ_UNSUPPORTED;
+
        list_add_tail ( &dev->list, &net80211_devices );
        return register_netdev ( dev->netdev );
 }
index 49e3257a020ece587e4799a13efef31dc6ea5af2..f515c2dc917365197e3fe40aba639bc4c0fe256a 100644 (file)
@@ -389,6 +389,10 @@ int vlan_create ( struct net_device *trunk, unsigned int tag,
        snprintf ( netdev->name, sizeof ( netdev->name ), "%s-%d",
                   trunk->name, vlan->tag );
 
+       /* Mark device as not supporting interrupts, if applicable */
+       if ( ! netdev_irq_supported ( trunk ) )
+               netdev->state |= NETDEV_IRQ_UNSUPPORTED;
+
        /* Register VLAN device */
        if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
                DBGC ( netdev, "VLAN %s could not register: %s\n",