| 
				
			 | 
			
			
				
				@@ -97,29 +97,44 @@ static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) { 
			 | 
		
		
	
		
			
			| 
				97
			 | 
			
				97
			 | 
			
			
				
				 	mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE ); 
			 | 
		
		
	
		
			
			| 
				98
			 | 
			
				98
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				99
			 | 
			
				99
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				
				+ * Flush transmit ring and receive queue 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				
				+ * @v snpdev		SNP device 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				
				+static void efi_snp_flush ( struct efi_snp_device *snpdev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+	struct io_buffer *iobuf; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+	struct io_buffer *tmp; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				
				+	/* Reset transmit completion ring */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				110
			 | 
			
			
				
				+	snpdev->tx_prod = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				111
			 | 
			
			
				
				+	snpdev->tx_cons = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				112
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				113
			 | 
			
			
				
				+	/* Discard any queued receive buffers */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				114
			 | 
			
			
				
				+	list_for_each_entry_safe ( iobuf, tmp, &snpdev->rx, list ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				115
			 | 
			
			
				
				+		list_del ( &iobuf->list ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				116
			 | 
			
			
				
				+		free_iob ( iobuf ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				118
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				119
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				100
			 | 
			
				120
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				101
			 | 
			
				121
			 | 
			
			
				
				  * Poll net device and count received packets 
			 | 
		
		
	
		
			
			| 
				102
			 | 
			
				122
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				103
			 | 
			
				123
			 | 
			
			
				
				  * @v snpdev		SNP device 
			 | 
		
		
	
		
			
			| 
				104
			 | 
			
				124
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				105
			 | 
			
				125
			 | 
			
			
				
				 static void efi_snp_poll ( struct efi_snp_device *snpdev ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				126
			 | 
			
			
				
				+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices; 
			 | 
		
		
	
		
			
			| 
				106
			 | 
			
				127
			 | 
			
			
				
				 	struct io_buffer *iobuf; 
			 | 
		
		
	
		
			
			| 
				107
			 | 
			
				
			 | 
			
			
				
				-	unsigned int before = 0; 
			 | 
		
		
	
		
			
			| 
				108
			 | 
			
				
			 | 
			
			
				
				-	unsigned int after = 0; 
			 | 
		
		
	
		
			
			| 
				109
			 | 
			
				
			 | 
			
			
				
				-	unsigned int arrived; 
			 | 
		
		
	
		
			
			| 
				110
			 | 
			
				128
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				111
			 | 
			
				
			 | 
			
			
				
				-	/* We have to report packet arrivals, and this is the easiest 
			 | 
		
		
	
		
			
			| 
				112
			 | 
			
				
			 | 
			
			
				
				-	 * way to fake it. 
			 | 
		
		
	
		
			
			| 
				113
			 | 
			
				
			 | 
			
			
				
				-	 */ 
			 | 
		
		
	
		
			
			| 
				114
			 | 
			
				
			 | 
			
			
				
				-	list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list ) 
			 | 
		
		
	
		
			
			| 
				115
			 | 
			
				
			 | 
			
			
				
				-		before++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				129
			 | 
			
			
				
				+	/* Poll network device */ 
			 | 
		
		
	
		
			
			| 
				116
			 | 
			
				130
			 | 
			
			
				
				 	netdev_poll ( snpdev->netdev ); 
			 | 
		
		
	
		
			
			| 
				117
			 | 
			
				
			 | 
			
			
				
				-	list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list ) 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				
			 | 
			
			
				
				-		after++; 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				
			 | 
			
			
				
				-	arrived = ( after - before ); 
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				131
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				
			 | 
			
			
				
				-	snpdev->rx_count_interrupts += arrived; 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				
			 | 
			
			
				
				-	snpdev->rx_count_events += arrived; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				132
			 | 
			
			
				
				+	/* Retrieve any received packets */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				133
			 | 
			
			
				
				+	while ( ( iobuf = netdev_rx_dequeue ( snpdev->netdev ) ) ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				134
			 | 
			
			
				
				+		list_add_tail ( &iobuf->list, &snpdev->rx ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				135
			 | 
			
			
				
				+		snpdev->interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				136
			 | 
			
			
				
				+		bs->SignalEvent ( &snpdev->snp.WaitForPacket ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				137
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				138
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				124
			 | 
			
				139
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				125
			 | 
			
				140
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -221,6 +236,7 @@ efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) { 
			 | 
		
		
	
		
			
			| 
				221
			 | 
			
				236
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				222
			 | 
			
				237
			 | 
			
			
				
				 	netdev_close ( snpdev->netdev ); 
			 | 
		
		
	
		
			
			| 
				223
			 | 
			
				238
			 | 
			
			
				
				 	efi_snp_set_state ( snpdev ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				239
			 | 
			
			
				
				+	efi_snp_flush ( snpdev ); 
			 | 
		
		
	
		
			
			| 
				224
			 | 
			
				240
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				225
			 | 
			
				241
			 | 
			
			
				
				 	if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) { 
			 | 
		
		
	
		
			
			| 
				226
			 | 
			
				242
			 | 
			
			
				
				 		DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n", 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -251,6 +267,7 @@ efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) { 
			 | 
		
		
	
		
			
			| 
				251
			 | 
			
				267
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				252
			 | 
			
				268
			 | 
			
			
				
				 	netdev_close ( snpdev->netdev ); 
			 | 
		
		
	
		
			
			| 
				253
			 | 
			
				269
			 | 
			
			
				
				 	efi_snp_set_state ( snpdev ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				270
			 | 
			
			
				
				+	efi_snp_flush ( snpdev ); 
			 | 
		
		
	
		
			
			| 
				254
			 | 
			
				271
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				255
			 | 
			
				272
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				256
			 | 
			
				273
			 | 
			
			
				
				 } 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -446,20 +463,22 @@ efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read, 
			 | 
		
		
	
		
			
			| 
				446
			 | 
			
				463
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				447
			 | 
			
				464
			 | 
			
			
				
				  * @v snp		SNP interface 
			 | 
		
		
	
		
			
			| 
				448
			 | 
			
				465
			 | 
			
			
				
				  * @v interrupts	Interrupt status, or NULL 
			 | 
		
		
	
		
			
			| 
				449
			 | 
			
				
			 | 
			
			
				
				- * @v txbufs		Recycled transmit buffer address, or NULL 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				466
			 | 
			
			
				
				+ * @v txbuf		Recycled transmit buffer address, or NULL 
			 | 
		
		
	
		
			
			| 
				450
			 | 
			
				467
			 | 
			
			
				
				  * @ret efirc		EFI status code 
			 | 
		
		
	
		
			
			| 
				451
			 | 
			
				468
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				452
			 | 
			
				469
			 | 
			
			
				
				 static EFI_STATUS EFIAPI 
			 | 
		
		
	
		
			
			| 
				453
			 | 
			
				470
			 | 
			
			
				
				 efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, 
			 | 
		
		
	
		
			
			| 
				454
			 | 
			
				
			 | 
			
			
				
				-		     UINT32 *interrupts, VOID **txbufs ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				471
			 | 
			
			
				
				+		     UINT32 *interrupts, VOID **txbuf ) { 
			 | 
		
		
	
		
			
			| 
				455
			 | 
			
				472
			 | 
			
			
				
				 	struct efi_snp_device *snpdev = 
			 | 
		
		
	
		
			
			| 
				456
			 | 
			
				473
			 | 
			
			
				
				 		container_of ( snp, struct efi_snp_device, snp ); 
			 | 
		
		
	
		
			
			| 
				457
			 | 
			
				474
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				458
			 | 
			
				475
			 | 
			
			
				
				 	DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev ); 
			 | 
		
		
	
		
			
			| 
				459
			 | 
			
				476
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				460
			 | 
			
				477
			 | 
			
			
				
				 	/* Fail if net device is currently claimed for use by iPXE */ 
			 | 
		
		
	
		
			
			| 
				461
			 | 
			
				
			 | 
			
			
				
				-	if ( efi_snp_claimed ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				478
			 | 
			
			
				
				+	if ( efi_snp_claimed ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				479
			 | 
			
			
				
				+		DBGC2 ( snpdev, "\n" ); 
			 | 
		
		
	
		
			
			| 
				462
			 | 
			
				480
			 | 
			
			
				
				 		return EFI_NOT_READY; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				481
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				463
			 | 
			
				482
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				464
			 | 
			
				483
			 | 
			
			
				
				 	/* Poll the network device */ 
			 | 
		
		
	
		
			
			| 
				465
			 | 
			
				484
			 | 
			
			
				
				 	efi_snp_poll ( snpdev ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -468,47 +487,19 @@ efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, 
			 | 
		
		
	
		
			
			| 
				468
			 | 
			
				487
			 | 
			
			
				
				 	 * to detect TX completions. 
			 | 
		
		
	
		
			
			| 
				469
			 | 
			
				488
			 | 
			
			
				
				 	 */ 
			 | 
		
		
	
		
			
			| 
				470
			 | 
			
				489
			 | 
			
			
				
				 	if ( interrupts ) { 
			 | 
		
		
	
		
			
			| 
				471
			 | 
			
				
			 | 
			
			
				
				-		*interrupts = 0; 
			 | 
		
		
	
		
			
			| 
				472
			 | 
			
				
			 | 
			
			
				
				-		/* Report TX completions once queue is empty; this 
			 | 
		
		
	
		
			
			| 
				473
			 | 
			
				
			 | 
			
			
				
				-		 * avoids having to add hooks in the net device layer. 
			 | 
		
		
	
		
			
			| 
				474
			 | 
			
				
			 | 
			
			
				
				-		 */ 
			 | 
		
		
	
		
			
			| 
				475
			 | 
			
				
			 | 
			
			
				
				-		if ( snpdev->tx_count_interrupts && 
			 | 
		
		
	
		
			
			| 
				476
			 | 
			
				
			 | 
			
			
				
				-		     list_empty ( &snpdev->netdev->tx_queue ) ) { 
			 | 
		
		
	
		
			
			| 
				477
			 | 
			
				
			 | 
			
			
				
				-			*interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; 
			 | 
		
		
	
		
			
			| 
				478
			 | 
			
				
			 | 
			
			
				
				-			snpdev->tx_count_interrupts--; 
			 | 
		
		
	
		
			
			| 
				479
			 | 
			
				
			 | 
			
			
				
				-		} 
			 | 
		
		
	
		
			
			| 
				480
			 | 
			
				
			 | 
			
			
				
				-		/* Report RX */ 
			 | 
		
		
	
		
			
			| 
				481
			 | 
			
				
			 | 
			
			
				
				-		if ( snpdev->rx_count_interrupts ) { 
			 | 
		
		
	
		
			
			| 
				482
			 | 
			
				
			 | 
			
			
				
				-			*interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT; 
			 | 
		
		
	
		
			
			| 
				483
			 | 
			
				
			 | 
			
			
				
				-			snpdev->rx_count_interrupts--; 
			 | 
		
		
	
		
			
			| 
				484
			 | 
			
				
			 | 
			
			
				
				-		} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				490
			 | 
			
			
				
				+		*interrupts = snpdev->interrupts; 
			 | 
		
		
	
		
			
			| 
				485
			 | 
			
				491
			 | 
			
			
				
				 		DBGC2 ( snpdev, " INTS:%02x", *interrupts ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				492
			 | 
			
			
				
				+		snpdev->interrupts = 0; 
			 | 
		
		
	
		
			
			| 
				486
			 | 
			
				493
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				487
			 | 
			
				494
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				488
			 | 
			
				
			 | 
			
			
				
				-	/* TX completions.  It would be possible to design a more 
			 | 
		
		
	
		
			
			| 
				489
			 | 
			
				
			 | 
			
			
				
				-	 * idiotic scheme for this, but it would be a challenge. 
			 | 
		
		
	
		
			
			| 
				490
			 | 
			
				
			 | 
			
			
				
				-	 * According to the UEFI header file, txbufs will be filled in 
			 | 
		
		
	
		
			
			| 
				491
			 | 
			
				
			 | 
			
			
				
				-	 * with a list of "recycled transmit buffers" (i.e. completed 
			 | 
		
		
	
		
			
			| 
				492
			 | 
			
				
			 | 
			
			
				
				-	 * TX buffers).  Observant readers may care to note that 
			 | 
		
		
	
		
			
			| 
				493
			 | 
			
				
			 | 
			
			
				
				-	 * *txbufs is a void pointer.  Precisely how a list of 
			 | 
		
		
	
		
			
			| 
				494
			 | 
			
				
			 | 
			
			
				
				-	 * completed transmit buffers is meant to be represented as an 
			 | 
		
		
	
		
			
			| 
				495
			 | 
			
				
			 | 
			
			
				
				-	 * array of voids is left as an exercise for the reader. 
			 | 
		
		
	
		
			
			| 
				496
			 | 
			
				
			 | 
			
			
				
				-	 * 
			 | 
		
		
	
		
			
			| 
				497
			 | 
			
				
			 | 
			
			
				
				-	 * The only users of this interface (MnpDxe/MnpIo.c and 
			 | 
		
		
	
		
			
			| 
				498
			 | 
			
				
			 | 
			
			
				
				-	 * PxeBcDxe/Bc.c within the EFI dev kit) both just poll until 
			 | 
		
		
	
		
			
			| 
				499
			 | 
			
				
			 | 
			
			
				
				-	 * seeing a non-NULL result return in txbufs.  This is valid 
			 | 
		
		
	
		
			
			| 
				500
			 | 
			
				
			 | 
			
			
				
				-	 * provided that they do not ever attempt to transmit more 
			 | 
		
		
	
		
			
			| 
				501
			 | 
			
				
			 | 
			
			
				
				-	 * than one packet concurrently (and that TX never times out). 
			 | 
		
		
	
		
			
			| 
				502
			 | 
			
				
			 | 
			
			
				
				-	 */ 
			 | 
		
		
	
		
			
			| 
				503
			 | 
			
				
			 | 
			
			
				
				-	if ( txbufs ) { 
			 | 
		
		
	
		
			
			| 
				504
			 | 
			
				
			 | 
			
			
				
				-		if ( snpdev->tx_count_txbufs && 
			 | 
		
		
	
		
			
			| 
				505
			 | 
			
				
			 | 
			
			
				
				-		     list_empty ( &snpdev->netdev->tx_queue ) ) { 
			 | 
		
		
	
		
			
			| 
				506
			 | 
			
				
			 | 
			
			
				
				-			*txbufs = "Which idiot designed this API?"; 
			 | 
		
		
	
		
			
			| 
				507
			 | 
			
				
			 | 
			
			
				
				-			snpdev->tx_count_txbufs--; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				495
			 | 
			
			
				
				+	/* TX completions */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				496
			 | 
			
			
				
				+	if ( txbuf ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				497
			 | 
			
			
				
				+		if ( snpdev->tx_prod != snpdev->tx_cons ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				498
			 | 
			
			
				
				+			*txbuf = snpdev->tx[snpdev->tx_cons++ % EFI_SNP_NUM_TX]; 
			 | 
		
		
	
		
			
			| 
				508
			 | 
			
				499
			 | 
			
			
				
				 		} else { 
			 | 
		
		
	
		
			
			| 
				509
			 | 
			
				
			 | 
			
			
				
				-			*txbufs = NULL; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				500
			 | 
			
			
				
				+			*txbuf = NULL; 
			 | 
		
		
	
		
			
			| 
				510
			 | 
			
				501
			 | 
			
			
				
				 		} 
			 | 
		
		
	
		
			
			| 
				511
			 | 
			
				
			 | 
			
			
				
				-		DBGC2 ( snpdev, " TX:%s", ( *txbufs ? "some" : "none" ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				502
			 | 
			
			
				
				+		DBGC2 ( snpdev, " TX:%p", *txbuf ); 
			 | 
		
		
	
		
			
			| 
				512
			 | 
			
				503
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				513
			 | 
			
				504
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				514
			 | 
			
				505
			 | 
			
			
				
				 	DBGC2 ( snpdev, "\n" ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -537,6 +528,7 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, 
			 | 
		
		
	
		
			
			| 
				537
			 | 
			
				528
			 | 
			
			
				
				 	struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol; 
			 | 
		
		
	
		
			
			| 
				538
			 | 
			
				529
			 | 
			
			
				
				 	struct io_buffer *iobuf; 
			 | 
		
		
	
		
			
			| 
				539
			 | 
			
				530
			 | 
			
			
				
				 	size_t payload_len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				531
			 | 
			
			
				
				+	unsigned int tx_fill; 
			 | 
		
		
	
		
			
			| 
				540
			 | 
			
				532
			 | 
			
			
				
				 	int rc; 
			 | 
		
		
	
		
			
			| 
				541
			 | 
			
				533
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				542
			 | 
			
				534
			 | 
			
			
				
				 	DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data, 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -624,12 +616,27 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, 
			 | 
		
		
	
		
			
			| 
				624
			 | 
			
				616
			 | 
			
			
				
				 		goto err_tx; 
			 | 
		
		
	
		
			
			| 
				625
			 | 
			
				617
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				626
			 | 
			
				618
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				627
			 | 
			
				
			 | 
			
			
				
				-	/* Record transmission as outstanding */ 
			 | 
		
		
	
		
			
			| 
				628
			 | 
			
				
			 | 
			
			
				
				-	snpdev->tx_count_interrupts++; 
			 | 
		
		
	
		
			
			| 
				629
			 | 
			
				
			 | 
			
			
				
				-	snpdev->tx_count_txbufs++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				619
			 | 
			
			
				
				+	/* Record in transmit completion ring.  If we run out of 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				620
			 | 
			
			
				
				+	 * space, report the failure even though we have already 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				621
			 | 
			
			
				
				+	 * transmitted the packet. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				622
			 | 
			
			
				
				+	 * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				623
			 | 
			
			
				
				+	 * This allows us to report completions only for packets for 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				624
			 | 
			
			
				
				+	 * which we had reported successfully initiating transmission, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				625
			 | 
			
			
				
				+	 * while continuing to support clients that never poll for 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				626
			 | 
			
			
				
				+	 * transmit completions. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				627
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				628
			 | 
			
			
				
				+	tx_fill = ( snpdev->tx_prod - snpdev->tx_cons ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				629
			 | 
			
			
				
				+	if ( tx_fill >= EFI_SNP_NUM_TX ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				630
			 | 
			
			
				
				+		DBGC ( snpdev, "SNPDEV %p TX completion ring full\n", snpdev ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				631
			 | 
			
			
				
				+		rc = -ENOBUFS; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				632
			 | 
			
			
				
				+		goto err_ring_full; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				633
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				634
			 | 
			
			
				
				+	snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				635
			 | 
			
			
				
				+	snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; 
			 | 
		
		
	
		
			
			| 
				630
			 | 
			
				636
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				631
			 | 
			
				637
			 | 
			
			
				
				 	return 0; 
			 | 
		
		
	
		
			
			| 
				632
			 | 
			
				638
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				639
			 | 
			
			
				
				+ err_ring_full: 
			 | 
		
		
	
		
			
			| 
				633
			 | 
			
				640
			 | 
			
			
				
				  err_tx: 
			 | 
		
		
	
		
			
			| 
				634
			 | 
			
				641
			 | 
			
			
				
				  err_ll_push: 
			 | 
		
		
	
		
			
			| 
				635
			 | 
			
				642
			 | 
			
			
				
				 	free_iob ( iobuf ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -676,12 +683,13 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, 
			 | 
		
		
	
		
			
			| 
				676
			 | 
			
				683
			 | 
			
			
				
				 	efi_snp_poll ( snpdev ); 
			 | 
		
		
	
		
			
			| 
				677
			 | 
			
				684
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				678
			 | 
			
				685
			 | 
			
			
				
				 	/* Dequeue a packet, if one is available */ 
			 | 
		
		
	
		
			
			| 
				679
			 | 
			
				
			 | 
			
			
				
				-	iobuf = netdev_rx_dequeue ( snpdev->netdev ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				686
			 | 
			
			
				
				+	iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list ); 
			 | 
		
		
	
		
			
			| 
				680
			 | 
			
				687
			 | 
			
			
				
				 	if ( ! iobuf ) { 
			 | 
		
		
	
		
			
			| 
				681
			 | 
			
				688
			 | 
			
			
				
				 		DBGC2 ( snpdev, "\n" ); 
			 | 
		
		
	
		
			
			| 
				682
			 | 
			
				689
			 | 
			
			
				
				 		rc = -EAGAIN; 
			 | 
		
		
	
		
			
			| 
				683
			 | 
			
				690
			 | 
			
			
				
				 		goto out_no_packet; 
			 | 
		
		
	
		
			
			| 
				684
			 | 
			
				691
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				692
			 | 
			
			
				
				+	list_del ( &iobuf->list ); 
			 | 
		
		
	
		
			
			| 
				685
			 | 
			
				693
			 | 
			
			
				
				 	DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) ); 
			 | 
		
		
	
		
			
			| 
				686
			 | 
			
				694
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				687
			 | 
			
				695
			 | 
			
			
				
				 	/* Return packet to caller */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -721,9 +729,8 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, 
			 | 
		
		
	
		
			
			| 
				721
			 | 
			
				729
			 | 
			
			
				
				  * @v event		Event 
			 | 
		
		
	
		
			
			| 
				722
			 | 
			
				730
			 | 
			
			
				
				  * @v context		Event context 
			 | 
		
		
	
		
			
			| 
				723
			 | 
			
				731
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				724
			 | 
			
				
			 | 
			
			
				
				-static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				732
			 | 
			
			
				
				+static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused, 
			 | 
		
		
	
		
			
			| 
				725
			 | 
			
				733
			 | 
			
			
				
				 					     VOID *context ) { 
			 | 
		
		
	
		
			
			| 
				726
			 | 
			
				
			 | 
			
			
				
				-	EFI_BOOT_SERVICES *bs = efi_systab->BootServices; 
			 | 
		
		
	
		
			
			| 
				727
			 | 
			
				734
			 | 
			
			
				
				 	struct efi_snp_device *snpdev = context; 
			 | 
		
		
	
		
			
			| 
				728
			 | 
			
				735
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				729
			 | 
			
				736
			 | 
			
			
				
				 	DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -738,14 +745,6 @@ static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event, 
			 | 
		
		
	
		
			
			| 
				738
			 | 
			
				745
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				739
			 | 
			
				746
			 | 
			
			
				
				 	/* Poll the network device */ 
			 | 
		
		
	
		
			
			| 
				740
			 | 
			
				747
			 | 
			
			
				
				 	efi_snp_poll ( snpdev ); 
			 | 
		
		
	
		
			
			| 
				741
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				742
			 | 
			
				
			 | 
			
			
				
				-	/* Fire event if packets have been received */ 
			 | 
		
		
	
		
			
			| 
				743
			 | 
			
				
			 | 
			
			
				
				-	if ( snpdev->rx_count_events != 0 ) { 
			 | 
		
		
	
		
			
			| 
				744
			 | 
			
				
			 | 
			
			
				
				-		DBGC2 ( snpdev, "SNPDEV %p firing WaitForPacket event\n", 
			 | 
		
		
	
		
			
			| 
				745
			 | 
			
				
			 | 
			
			
				
				-			snpdev ); 
			 | 
		
		
	
		
			
			| 
				746
			 | 
			
				
			 | 
			
			
				
				-		bs->SignalEvent ( event ); 
			 | 
		
		
	
		
			
			| 
				747
			 | 
			
				
			 | 
			
			
				
				-		snpdev->rx_count_events--; 
			 | 
		
		
	
		
			
			| 
				748
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				749
			 | 
			
				748
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				750
			 | 
			
				749
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				751
			 | 
			
				750
			 | 
			
			
				
				 /** SNP interface */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -922,6 +921,7 @@ static int efi_snp_probe ( struct net_device *netdev ) { 
			 | 
		
		
	
		
			
			| 
				922
			 | 
			
				921
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				923
			 | 
			
				922
			 | 
			
			
				
				 	snpdev->netdev = netdev_get ( netdev ); 
			 | 
		
		
	
		
			
			| 
				924
			 | 
			
				923
			 | 
			
			
				
				 	snpdev->efidev = efidev; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				924
			 | 
			
			
				
				+	INIT_LIST_HEAD ( &snpdev->rx ); 
			 | 
		
		
	
		
			
			| 
				925
			 | 
			
				925
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				926
			 | 
			
				926
			 | 
			
			
				
				 	/* Sanity check */ 
			 | 
		
		
	
		
			
			| 
				927
			 | 
			
				927
			 | 
			
			
				
				 	if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) { 
			 |