Browse Source

[netdevice] Allow network devices to disclaim IRQ support at runtime

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>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
b20d4a1522
3 changed files with 18 additions and 1 deletions
  1. 10
    1
      src/include/ipxe/netdevice.h
  2. 4
    0
      src/net/80211/net80211.c
  3. 4
    0
      src/net/vlan.c

+ 10
- 1
src/include/ipxe/netdevice.h View File

@@ -430,6 +430,14 @@ struct net_device {
430 430
 /** Network device receive queue processing is frozen */
431 431
 #define NETDEV_RX_FROZEN 0x0004
432 432
 
433
+/** Network device interrupts are unsupported
434
+ *
435
+ * This flag can be used by a network device to indicate that
436
+ * interrupts are not supported despite the presence of an irq()
437
+ * method.
438
+ */
439
+#define NETDEV_IRQ_UNSUPPORTED 0x0008
440
+
433 441
 /** Link-layer protocol table */
434 442
 #define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
435 443
 
@@ -646,7 +654,8 @@ netdev_is_open ( struct net_device *netdev ) {
646 654
  */
647 655
 static inline __attribute__ (( always_inline )) int
648 656
 netdev_irq_supported ( struct net_device *netdev ) {
649
-	return ( netdev->op->irq != NULL );
657
+	return ( ( netdev->op->irq != NULL ) &&
658
+		 ! ( netdev->state & NETDEV_IRQ_UNSUPPORTED ) );
650 659
 }
651 660
 
652 661
 /**

+ 4
- 0
src/net/80211/net80211.c View File

@@ -805,6 +805,10 @@ int net80211_register ( struct net80211_device *dev,
805 805
 		 NET80211_MAX_CHANNELS * sizeof ( dev->channels[0] ) );
806 806
 	dev->channel = 0;
807 807
 
808
+	/* Mark device as not supporting interrupts, if applicable */
809
+	if ( ! ops->irq )
810
+		dev->netdev->state |= NETDEV_IRQ_UNSUPPORTED;
811
+
808 812
 	list_add_tail ( &dev->list, &net80211_devices );
809 813
 	return register_netdev ( dev->netdev );
810 814
 }

+ 4
- 0
src/net/vlan.c View File

@@ -389,6 +389,10 @@ int vlan_create ( struct net_device *trunk, unsigned int tag,
389 389
 	snprintf ( netdev->name, sizeof ( netdev->name ), "%s-%d",
390 390
 		   trunk->name, vlan->tag );
391 391
 
392
+	/* Mark device as not supporting interrupts, if applicable */
393
+	if ( ! netdev_irq_supported ( trunk ) )
394
+		netdev->state |= NETDEV_IRQ_UNSUPPORTED;
395
+
392 396
 	/* Register VLAN device */
393 397
 	if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
394 398
 		DBGC ( netdev, "VLAN %s could not register: %s\n",

Loading…
Cancel
Save