Browse Source

[efi] Default to releasing network devices for use via SNP

We currently treat network devices as available for use via the SNP
API only if RX queue processing has been frozen.  (This is similar in
spirit to the way that RX queue processing is frozen for the network
device currently exposed via the PXE API.)

The default state of a freshly created network device is for the RX
queue to not be frozen, and thus to be unavailable for use via SNP.
This causes problems when devices are added through code paths other
than _efidrv_start() (which explicitly releases devices for use via
SNP).

We don't actually need to freeze RX queue processing, since calls via
the SNP API will always use netdev_poll() rather than net_poll(), and
so will never trigger the RX queue processing code path anyway.

We can therefore simplify the code to use a single global flag to
indicate whether network devices are claimed for use by iPXE or
available for use via SNP.  Using a global flag allows the default
state for dynamically created network devices to behave sensibly.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
dc18fd7648

+ 0
- 4
src/arch/x86/prefix/efidrvprefix.c View File

22
 #include <stdlib.h>
22
 #include <stdlib.h>
23
 #include <ipxe/init.h>
23
 #include <ipxe/init.h>
24
 #include <ipxe/efi/efi.h>
24
 #include <ipxe/efi/efi.h>
25
-#include <ipxe/efi/efi_snp.h>
26
 
25
 
27
 /**
26
 /**
28
  * EFI entry point
27
  * EFI entry point
43
 	initialise();
42
 	initialise();
44
 	startup();
43
 	startup();
45
 
44
 
46
-	/* Release network devices for use via SNP */
47
-	efi_snp_release();
48
-
49
 	return 0;
45
 	return 0;
50
 }
46
 }

+ 5
- 0
src/arch/x86/prefix/efiprefix.c View File

24
 #include <ipxe/device.h>
24
 #include <ipxe/device.h>
25
 #include <ipxe/efi/efi.h>
25
 #include <ipxe/efi/efi.h>
26
 #include <ipxe/efi/efi_driver.h>
26
 #include <ipxe/efi/efi_driver.h>
27
+#include <ipxe/efi/efi_snp.h>
27
 #include <ipxe/efi/efi_autoboot.h>
28
 #include <ipxe/efi/efi_autoboot.h>
28
 
29
 
29
 /**
30
 /**
45
 	/* Record autoboot device (if any) */
46
 	/* Record autoboot device (if any) */
46
 	efi_set_autoboot();
47
 	efi_set_autoboot();
47
 
48
 
49
+	/* Claim SNP devices for use by iPXE */
50
+	efi_snp_claim();
51
+
48
 	/* Call to main() */
52
 	/* Call to main() */
49
 	if ( ( rc = main() ) != 0 ) {
53
 	if ( ( rc = main() ) != 0 ) {
50
 		efirc = EFIRC ( rc );
54
 		efirc = EFIRC ( rc );
52
 	}
56
 	}
53
 
57
 
54
  err_main:
58
  err_main:
59
+	efi_snp_release();
55
 	efi_loaded_image->Unload ( image_handle );
60
 	efi_loaded_image->Unload ( image_handle );
56
 	efi_driver_reconnect_all();
61
 	efi_driver_reconnect_all();
57
  err_init:
62
  err_init:

+ 17
- 2
src/include/ipxe/efi/efi_snp.h View File

78
 extern void efi_snp_hii_uninstall ( struct efi_snp_device *snpdev );
78
 extern void efi_snp_hii_uninstall ( struct efi_snp_device *snpdev );
79
 extern struct efi_snp_device * find_snpdev ( EFI_HANDLE handle );
79
 extern struct efi_snp_device * find_snpdev ( EFI_HANDLE handle );
80
 extern struct efi_snp_device * last_opened_snpdev ( void );
80
 extern struct efi_snp_device * last_opened_snpdev ( void );
81
-extern void efi_snp_claim ( void );
82
-extern void efi_snp_release ( void );
81
+extern void efi_snp_set_claimed ( int claimed );
82
+
83
+/**
84
+ * Claim network devices for use by iPXE
85
+ *
86
+ */
87
+static inline void efi_snp_claim ( void ) {
88
+	efi_snp_set_claimed ( 1 );
89
+}
90
+
91
+/**
92
+ * Release network devices for use via SNP
93
+ *
94
+ */
95
+static inline void efi_snp_release ( void ) {
96
+	efi_snp_set_claimed ( 0 );
97
+}
83
 
98
 
84
 #endif /* _IPXE_EFI_SNP_H */
99
 #endif /* _IPXE_EFI_SNP_H */

+ 4
- 0
src/interface/efi/efi_download.c View File

26
 #include <ipxe/iobuf.h>
26
 #include <ipxe/iobuf.h>
27
 #include <ipxe/xfer.h>
27
 #include <ipxe/xfer.h>
28
 #include <ipxe/efi/efi.h>
28
 #include <ipxe/efi/efi.h>
29
+#include <ipxe/efi/efi_snp.h>
29
 #include <ipxe/efi/efi_download.h>
30
 #include <ipxe/efi/efi_download.h>
30
 
31
 
31
 /** iPXE download protocol GUID */
32
 /** iPXE download protocol GUID */
63
 	file->finish_callback ( file->context, EFIRC ( rc ) );
64
 	file->finish_callback ( file->context, EFIRC ( rc ) );
64
 
65
 
65
 	intf_shutdown ( &file->xfer, rc );
66
 	intf_shutdown ( &file->xfer, rc );
67
+
68
+	efi_snp_release();
66
 }
69
 }
67
 
70
 
68
 /**
71
 /**
147
 		return EFIRC ( rc );
150
 		return EFIRC ( rc );
148
 	}
151
 	}
149
 
152
 
153
+	efi_snp_claim();
150
 	file->pos = 0;
154
 	file->pos = 0;
151
 	file->data_callback = DataCallback;
155
 	file->data_callback = DataCallback;
152
 	file->finish_callback = FinishCallback;
156
 	file->finish_callback = FinishCallback;

+ 27
- 30
src/interface/efi/efi_snp.c View File

67
 /** List of SNP devices */
67
 /** List of SNP devices */
68
 static LIST_HEAD ( efi_snp_devices );
68
 static LIST_HEAD ( efi_snp_devices );
69
 
69
 
70
+/** Network devices are currently claimed for use by iPXE */
71
+static int efi_snp_claimed;
72
+
70
 /**
73
 /**
71
  * Set EFI SNP mode state
74
  * Set EFI SNP mode state
72
  *
75
  *
83
 	} else if ( ! netdev_is_open ( netdev ) ) {
86
 	} else if ( ! netdev_is_open ( netdev ) ) {
84
 		/* Network device not opened; report as Started */
87
 		/* Network device not opened; report as Started */
85
 		mode->State = EfiSimpleNetworkStarted;
88
 		mode->State = EfiSimpleNetworkStarted;
86
-	} else if ( ! netdev_rx_frozen ( netdev ) ) {
89
+	} else if ( efi_snp_claimed ) {
87
 		/* Network device opened but claimed for use by iPXE; report
90
 		/* Network device opened but claimed for use by iPXE; report
88
 		 * as Started to inhibit receive polling.
91
 		 * as Started to inhibit receive polling.
89
 		 */
92
 		 */
162
 	DBGC2 ( snpdev, "SNPDEV %p START\n", snpdev );
165
 	DBGC2 ( snpdev, "SNPDEV %p START\n", snpdev );
163
 
166
 
164
 	/* Fail if net device is currently claimed for use by iPXE */
167
 	/* Fail if net device is currently claimed for use by iPXE */
165
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
168
+	if ( efi_snp_claimed )
166
 		return EFI_NOT_READY;
169
 		return EFI_NOT_READY;
167
 
170
 
168
 	snpdev->started = 1;
171
 	snpdev->started = 1;
184
 	DBGC2 ( snpdev, "SNPDEV %p STOP\n", snpdev );
187
 	DBGC2 ( snpdev, "SNPDEV %p STOP\n", snpdev );
185
 
188
 
186
 	/* Fail if net device is currently claimed for use by iPXE */
189
 	/* Fail if net device is currently claimed for use by iPXE */
187
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
190
+	if ( efi_snp_claimed )
188
 		return EFI_NOT_READY;
191
 		return EFI_NOT_READY;
189
 
192
 
190
 	snpdev->started = 0;
193
 	snpdev->started = 0;
212
 		( ( unsigned long ) extra_tx_bufsize ) );
215
 		( ( unsigned long ) extra_tx_bufsize ) );
213
 
216
 
214
 	/* Fail if net device is currently claimed for use by iPXE */
217
 	/* Fail if net device is currently claimed for use by iPXE */
215
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
218
+	if ( efi_snp_claimed )
216
 		return EFI_NOT_READY;
219
 		return EFI_NOT_READY;
217
 
220
 
218
 	if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
221
 	if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
242
 		snpdev, ( ext_verify ? "with" : "without" ) );
245
 		snpdev, ( ext_verify ? "with" : "without" ) );
243
 
246
 
244
 	/* Fail if net device is currently claimed for use by iPXE */
247
 	/* Fail if net device is currently claimed for use by iPXE */
245
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
248
+	if ( efi_snp_claimed )
246
 		return EFI_NOT_READY;
249
 		return EFI_NOT_READY;
247
 
250
 
248
 	netdev_close ( snpdev->netdev );
251
 	netdev_close ( snpdev->netdev );
272
 	DBGC2 ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
275
 	DBGC2 ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
273
 
276
 
274
 	/* Fail if net device is currently claimed for use by iPXE */
277
 	/* Fail if net device is currently claimed for use by iPXE */
275
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
278
+	if ( efi_snp_claimed )
276
 		return EFI_NOT_READY;
279
 		return EFI_NOT_READY;
277
 
280
 
278
 	netdev_close ( snpdev->netdev );
281
 	netdev_close ( snpdev->netdev );
309
 	}
312
 	}
310
 
313
 
311
 	/* Fail if net device is currently claimed for use by iPXE */
314
 	/* Fail if net device is currently claimed for use by iPXE */
312
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
315
+	if ( efi_snp_claimed )
313
 		return EFI_NOT_READY;
316
 		return EFI_NOT_READY;
314
 
317
 
315
 	/* Lie through our teeth, otherwise MNP refuses to accept us */
318
 	/* Lie through our teeth, otherwise MNP refuses to accept us */
335
 		( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
338
 		( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
336
 
339
 
337
 	/* Fail if net device is currently claimed for use by iPXE */
340
 	/* Fail if net device is currently claimed for use by iPXE */
338
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
341
+	if ( efi_snp_claimed )
339
 		return EFI_NOT_READY;
342
 		return EFI_NOT_READY;
340
 
343
 
341
 	/* Set the MAC address */
344
 	/* Set the MAC address */
372
 		( reset ? " reset" : "" ) );
375
 		( reset ? " reset" : "" ) );
373
 
376
 
374
 	/* Fail if net device is currently claimed for use by iPXE */
377
 	/* Fail if net device is currently claimed for use by iPXE */
375
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
378
+	if ( efi_snp_claimed )
376
 		return EFI_NOT_READY;
379
 		return EFI_NOT_READY;
377
 
380
 
378
 	/* Gather statistics */
381
 	/* Gather statistics */
424
 	DBGC2 ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
427
 	DBGC2 ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
425
 
428
 
426
 	/* Fail if net device is currently claimed for use by iPXE */
429
 	/* Fail if net device is currently claimed for use by iPXE */
427
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
430
+	if ( efi_snp_claimed )
428
 		return EFI_NOT_READY;
431
 		return EFI_NOT_READY;
429
 
432
 
430
 	/* Try to hash the address */
433
 	/* Try to hash the address */
461
 		DBGC2_HDA ( snpdev, offset, data, len );
464
 		DBGC2_HDA ( snpdev, offset, data, len );
462
 
465
 
463
 	/* Fail if net device is currently claimed for use by iPXE */
466
 	/* Fail if net device is currently claimed for use by iPXE */
464
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
467
+	if ( efi_snp_claimed )
465
 		return EFI_NOT_READY;
468
 		return EFI_NOT_READY;
466
 
469
 
467
 	return EFI_UNSUPPORTED;
470
 	return EFI_UNSUPPORTED;
484
 	DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
487
 	DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
485
 
488
 
486
 	/* Fail if net device is currently claimed for use by iPXE */
489
 	/* Fail if net device is currently claimed for use by iPXE */
487
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
490
+	if ( efi_snp_claimed )
488
 		return EFI_NOT_READY;
491
 		return EFI_NOT_READY;
489
 
492
 
490
 	/* Poll the network device */
493
 	/* Poll the network device */
583
 	DBGC2 ( snpdev, "\n" );
586
 	DBGC2 ( snpdev, "\n" );
584
 
587
 
585
 	/* Fail if net device is currently claimed for use by iPXE */
588
 	/* Fail if net device is currently claimed for use by iPXE */
586
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
589
+	if ( efi_snp_claimed )
587
 		return EFI_NOT_READY;
590
 		return EFI_NOT_READY;
588
 
591
 
589
 	/* Sanity checks */
592
 	/* Sanity checks */
695
 		( ( unsigned long ) *len ) );
698
 		( ( unsigned long ) *len ) );
696
 
699
 
697
 	/* Fail if net device is currently claimed for use by iPXE */
700
 	/* Fail if net device is currently claimed for use by iPXE */
698
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
701
+	if ( efi_snp_claimed )
699
 		return EFI_NOT_READY;
702
 		return EFI_NOT_READY;
700
 
703
 
701
 	/* Poll the network device */
704
 	/* Poll the network device */
759
 		return;
762
 		return;
760
 
763
 
761
 	/* Do nothing if net device is currently claimed for use by iPXE */
764
 	/* Do nothing if net device is currently claimed for use by iPXE */
762
-	if ( ! netdev_rx_frozen ( snpdev->netdev ) )
765
+	if ( efi_snp_claimed )
763
 		return;
766
 		return;
764
 
767
 
765
 	/* Poll the network device */
768
 	/* Poll the network device */
1184
 }
1187
 }
1185
 
1188
 
1186
 /**
1189
 /**
1187
- * Claim network devices for use by iPXE
1190
+ * Set SNP claimed/released state
1188
  *
1191
  *
1192
+ * @v claimed		Network devices are claimed for use by iPXE
1189
  */
1193
  */
1190
-void efi_snp_claim ( void ) {
1191
-	struct net_device *netdev;
1192
-
1193
-	for_each_netdev ( netdev )
1194
-		netdev_rx_unfreeze ( netdev );
1195
-}
1194
+void efi_snp_set_claimed ( int claimed ) {
1195
+	struct efi_snp_device *snpdev;
1196
 
1196
 
1197
-/**
1198
- * Release network devices for use via SNP
1199
- *
1200
- */
1201
-void efi_snp_release ( void ) {
1202
-	struct net_device *netdev;
1197
+	/* Claim SNP devices */
1198
+	efi_snp_claimed = claimed;
1203
 
1199
 
1204
-	for_each_netdev ( netdev )
1205
-		netdev_rx_freeze ( netdev );
1200
+	/* Update SNP mode state for each interface */
1201
+	list_for_each_entry ( snpdev, &efi_snp_devices, list )
1202
+		efi_snp_set_state ( snpdev );
1206
 }
1203
 }

Loading…
Cancel
Save