Browse Source

[netdevice] Allow per-device receive queue processing to be frozen

Several use cases (e.g. the UNDI API and the EFI SNP API) require
access to the raw network device receive queue, and so currently use
manual calls to netdev_poll() on a specific network device in order to
prevent received packets from being processed by the network stack.

As an alternative, provide a flag that allows receive queue processing
to be frozen on a per-device basis.  When receive queue processing is
frozen, packets will be enqueued as normal, but will not be
automatically dequeued and passed up the network stack.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
4576c2da58
2 changed files with 57 additions and 6 deletions
  1. 37
    2
      src/include/ipxe/netdevice.h
  2. 20
    4
      src/net/netdevice.c

+ 37
- 2
src/include/ipxe/netdevice.h View File

343
 /** Network device interrupts are enabled */
343
 /** Network device interrupts are enabled */
344
 #define NETDEV_IRQ_ENABLED 0x0002
344
 #define NETDEV_IRQ_ENABLED 0x0002
345
 
345
 
346
+/** Network device receive queue processing is frozen */
347
+#define NETDEV_RX_FROZEN 0x0004
348
+
346
 /** Link-layer protocol table */
349
 /** Link-layer protocol table */
347
 #define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
350
 #define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
348
 
351
 
505
  * Check whether or not network device is open
508
  * Check whether or not network device is open
506
  *
509
  *
507
  * @v netdev		Network device
510
  * @v netdev		Network device
508
- * @v is_open		Network device is open
511
+ * @ret is_open		Network device is open
509
  */
512
  */
510
 static inline __attribute__ (( always_inline )) int
513
 static inline __attribute__ (( always_inline )) int
511
 netdev_is_open ( struct net_device *netdev ) {
514
 netdev_is_open ( struct net_device *netdev ) {
516
  * Check whether or not network device interrupts are currently enabled
519
  * Check whether or not network device interrupts are currently enabled
517
  *
520
  *
518
  * @v netdev		Network device
521
  * @v netdev		Network device
519
- * @v irq_enabled	Network device interrupts are enabled
522
+ * @ret irq_enabled	Network device interrupts are enabled
520
  */
523
  */
521
 static inline __attribute__ (( always_inline )) int
524
 static inline __attribute__ (( always_inline )) int
522
 netdev_irq_enabled ( struct net_device *netdev ) {
525
 netdev_irq_enabled ( struct net_device *netdev ) {
523
 	return ( netdev->state & NETDEV_IRQ_ENABLED );
526
 	return ( netdev->state & NETDEV_IRQ_ENABLED );
524
 }
527
 }
525
 
528
 
529
+/**
530
+ * Check whether or not network device receive queue processing is frozen
531
+ *
532
+ * @v netdev		Network device
533
+ * @ret rx_frozen	Network device receive queue processing is frozen
534
+ */
535
+static inline __attribute__ (( always_inline )) int
536
+netdev_rx_frozen ( struct net_device *netdev ) {
537
+	return ( netdev->state & NETDEV_RX_FROZEN );
538
+}
539
+
526
 extern void netdev_link_err ( struct net_device *netdev, int rc );
540
 extern void netdev_link_err ( struct net_device *netdev, int rc );
527
 extern void netdev_link_down ( struct net_device *netdev );
541
 extern void netdev_link_down ( struct net_device *netdev );
528
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
542
 extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
550
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
564
 extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
551
 		    uint16_t net_proto, const void *ll_dest,
565
 		    uint16_t net_proto, const void *ll_dest,
552
 		    const void *ll_source );
566
 		    const void *ll_source );
567
+extern void net_poll ( void );
553
 
568
 
554
 /**
569
 /**
555
  * Complete network transmission
570
  * Complete network transmission
585
 	netdev_link_err ( netdev, 0 );
600
 	netdev_link_err ( netdev, 0 );
586
 }
601
 }
587
 
602
 
603
+/**
604
+ * Freeze network device receive queue processing
605
+ *
606
+ * @v netdev		Network device
607
+ */
608
+static inline __attribute__ (( always_inline )) void
609
+netdev_rx_freeze ( struct net_device *netdev ) {
610
+	netdev->state |= NETDEV_RX_FROZEN;
611
+}
612
+
613
+/**
614
+ * Unfreeze network device receive queue processing
615
+ *
616
+ * @v netdev		Network device
617
+ */
618
+static inline __attribute__ (( always_inline )) void
619
+netdev_rx_unfreeze ( struct net_device *netdev ) {
620
+	netdev->state &= ~NETDEV_RX_FROZEN;
621
+}
622
+
588
 #endif /* _IPXE_NETDEVICE_H */
623
 #endif /* _IPXE_NETDEVICE_H */

+ 20
- 4
src/net/netdevice.c View File

669
 }
669
 }
670
 
670
 
671
 /**
671
 /**
672
- * Single-step the network stack
673
- *
674
- * @v process		Network stack process
672
+ * Poll the network stack
675
  *
673
  *
676
  * This polls all interfaces for received packets, and processes
674
  * This polls all interfaces for received packets, and processes
677
  * packets from the RX queue.
675
  * packets from the RX queue.
678
  */
676
  */
679
-static void net_step ( struct process *process __unused ) {
677
+void net_poll ( void ) {
680
 	struct net_device *netdev;
678
 	struct net_device *netdev;
681
 	struct io_buffer *iobuf;
679
 	struct io_buffer *iobuf;
682
 	struct ll_protocol *ll_protocol;
680
 	struct ll_protocol *ll_protocol;
691
 		/* Poll for new packets */
689
 		/* Poll for new packets */
692
 		netdev_poll ( netdev );
690
 		netdev_poll ( netdev );
693
 
691
 
692
+		/* Leave received packets on the queue if receive
693
+		 * queue processing is currently frozen.  This will
694
+		 * happen when the raw packets are to be manually
695
+		 * dequeued using netdev_rx_dequeue(), rather than
696
+		 * processed via the usual networking stack.
697
+		 */
698
+		if ( netdev_rx_frozen ( netdev ) )
699
+			continue;
700
+
694
 		/* Process at most one received packet.  Give priority
701
 		/* Process at most one received packet.  Give priority
695
 		 * to getting packets out of the NIC over processing
702
 		 * to getting packets out of the NIC over processing
696
 		 * the received packets, because we advertise a window
703
 		 * the received packets, because we advertise a window
723
 	}
730
 	}
724
 }
731
 }
725
 
732
 
733
+/**
734
+ * Single-step the network stack
735
+ *
736
+ * @v process		Network stack process
737
+ */
738
+static void net_step ( struct process *process __unused ) {
739
+	net_poll();
740
+}
741
+
726
 /** Networking stack process */
742
 /** Networking stack process */
727
 struct process net_process __permanent_process = {
743
 struct process net_process __permanent_process = {
728
 	.list = LIST_HEAD_INIT ( net_process.list ),
744
 	.list = LIST_HEAD_INIT ( net_process.list ),

Loading…
Cancel
Save