Browse Source

[efi] Include NII driver within "snp" and "snponly" build targets

End users almost certainly don't care whether the underlying interface
is SNP or NII/UNDI.  Try to minimise surprise and unnecessary
documentation by including the NII driver whenever the SNP driver is
requested.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
af17abf67f
4 changed files with 195 additions and 106 deletions
  1. 4
    43
      src/drivers/net/efi/nii.c
  2. 17
    0
      src/drivers/net/efi/nii.h
  3. 41
    0
      src/drivers/net/efi/snp.c
  4. 133
    63
      src/drivers/net/efi/snponly.c

+ 4
- 43
src/drivers/net/efi/nii.c View File

@@ -28,10 +28,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
28 28
 #include <ipxe/umalloc.h>
29 29
 #include <ipxe/efi/efi.h>
30 30
 #include <ipxe/efi/efi_driver.h>
31
-#include <ipxe/efi/efi_snp.h>
32 31
 #include <ipxe/efi/efi_pci.h>
33 32
 #include <ipxe/efi/efi_utils.h>
33
+#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
34 34
 #include <ipxe/efi/IndustryStandard/Acpi10.h>
35
+#include "nii.h"
35 36
 
36 37
 /** @file
37 38
  *
@@ -955,45 +956,13 @@ static struct net_device_operations nii_operations = {
955 956
 	.poll = nii_poll,
956 957
 };
957 958
 
958
-/**
959
- * Check to see if driver supports a device
960
- *
961
- * @v device		EFI device handle
962
- * @ret rc		Return status code
963
- */
964
-static int nii_supported ( EFI_HANDLE device ) {
965
-	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
966
-	EFI_STATUS efirc;
967
-
968
-	/* Check that this is not a device we are providing ourselves */
969
-	if ( find_snpdev ( device ) != NULL ) {
970
-		DBGCP ( device, "NII %p %s is provided by this binary\n",
971
-			device, efi_handle_name ( device ) );
972
-		return -ENOTTY;
973
-	}
974
-
975
-	/* Test for presence of NII protocol */
976
-	if ( ( efirc = bs->OpenProtocol ( device,
977
-					  &efi_nii31_protocol_guid,
978
-					  NULL, efi_image_handle, device,
979
-					  EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
980
-		DBGCP ( device, "NII %p %s is not an NII device\n",
981
-			device, efi_handle_name ( device ) );
982
-		return -EEFI ( efirc );
983
-	}
984
-	DBGC ( device, "NII %p %s is an NII device\n",
985
-	       device, efi_handle_name ( device ) );
986
-
987
-	return 0;
988
-}
989
-
990 959
 /**
991 960
  * Attach driver to device
992 961
  *
993 962
  * @v efidev		EFI device
994 963
  * @ret rc		Return status code
995 964
  */
996
-static int nii_start ( struct efi_device *efidev ) {
965
+int nii_start ( struct efi_device *efidev ) {
997 966
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
998 967
 	EFI_HANDLE device = efidev->device;
999 968
 	struct net_device *netdev;
@@ -1106,7 +1075,7 @@ static int nii_start ( struct efi_device *efidev ) {
1106 1075
  *
1107 1076
  * @v efidev		EFI device
1108 1077
  */
1109
-static void nii_stop ( struct efi_device *efidev ) {
1078
+void nii_stop ( struct efi_device *efidev ) {
1110 1079
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1111 1080
 	struct net_device *netdev = efidev_get_drvdata ( efidev );
1112 1081
 	struct nii_nic *nii = netdev->priv;
@@ -1130,11 +1099,3 @@ static void nii_stop ( struct efi_device *efidev ) {
1130 1099
 	netdev_nullify ( netdev );
1131 1100
 	netdev_put ( netdev );
1132 1101
 }
1133
-
1134
-/** EFI NII driver */
1135
-struct efi_driver nii_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
1136
-	.name = "NII",
1137
-	.supported = nii_supported,
1138
-	.start = nii_start,
1139
-	.stop = nii_stop,
1140
-};

+ 17
- 0
src/drivers/net/efi/nii.h View File

@@ -0,0 +1,17 @@
1
+#ifndef _NII_H
2
+#define _NII_H
3
+
4
+/** @file
5
+ *
6
+ * NII driver
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+struct efi_device;
13
+
14
+extern int nii_start ( struct efi_device *efidev );
15
+extern void nii_stop ( struct efi_device *efidev );
16
+
17
+#endif /* _NII_H */

+ 41
- 0
src/drivers/net/efi/snp.c View File

@@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
24 24
 #include <ipxe/efi/efi_driver.h>
25 25
 #include <ipxe/efi/efi_snp.h>
26 26
 #include "snpnet.h"
27
+#include "nii.h"
27 28
 
28 29
 /** @file
29 30
  *
@@ -63,6 +64,38 @@ static int snp_supported ( EFI_HANDLE device ) {
63 64
 	return 0;
64 65
 }
65 66
 
67
+/**
68
+ * Check to see if driver supports a device
69
+ *
70
+ * @v device		EFI device handle
71
+ * @ret rc		Return status code
72
+ */
73
+static int nii_supported ( EFI_HANDLE device ) {
74
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
75
+	EFI_STATUS efirc;
76
+
77
+	/* Check that this is not a device we are providing ourselves */
78
+	if ( find_snpdev ( device ) != NULL ) {
79
+		DBGCP ( device, "NII %p %s is provided by this binary\n",
80
+			device, efi_handle_name ( device ) );
81
+		return -ENOTTY;
82
+	}
83
+
84
+	/* Test for presence of NII protocol */
85
+	if ( ( efirc = bs->OpenProtocol ( device,
86
+					  &efi_nii31_protocol_guid,
87
+					  NULL, efi_image_handle, device,
88
+					  EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
89
+		DBGCP ( device, "NII %p %s is not an NII device\n",
90
+			device, efi_handle_name ( device ) );
91
+		return -EEFI ( efirc );
92
+	}
93
+	DBGC ( device, "NII %p %s is an NII device\n",
94
+	       device, efi_handle_name ( device ) );
95
+
96
+	return 0;
97
+}
98
+
66 99
 /** EFI SNP driver */
67 100
 struct efi_driver snp_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
68 101
 	.name = "SNP",
@@ -70,3 +103,11 @@ struct efi_driver snp_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
70 103
 	.start = snpnet_start,
71 104
 	.stop = snpnet_stop,
72 105
 };
106
+
107
+/** EFI NII driver */
108
+struct efi_driver nii_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
109
+	.name = "NII",
110
+	.supported = nii_supported,
111
+	.start = nii_start,
112
+	.stop = nii_stop,
113
+};

+ 133
- 63
src/drivers/net/efi/snponly.c View File

@@ -19,78 +19,164 @@
19 19
 
20 20
 FILE_LICENCE ( GPL2_OR_LATER );
21 21
 
22
+#include <string.h>
22 23
 #include <errno.h>
23 24
 #include <ipxe/init.h>
24 25
 #include <ipxe/efi/efi.h>
25 26
 #include <ipxe/efi/efi_driver.h>
27
+#include <ipxe/efi/efi_utils.h>
26 28
 #include <ipxe/efi/Protocol/SimpleNetwork.h>
29
+#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
27 30
 #include "snpnet.h"
31
+#include "nii.h"
28 32
 
29 33
 /** @file
30 34
  *
31
- * SNP chainloading-device-only driver
35
+ * EFI chainloaded-device-only driver
32 36
  *
33 37
  */
34 38
 
39
+/** A chainloaded protocol */
40
+struct chained_protocol {
41
+	/** Protocol GUID */
42
+	EFI_GUID *protocol;
43
+	/**
44
+	 * Protocol instance installed on the loaded image's device handle
45
+	 *
46
+	 * We match against the protocol instance (rather than simply
47
+	 * matching against the device handle itself) because some
48
+	 * systems load us via a child of the underlying device, with
49
+	 * a duplicate protocol installed on the child handle.
50
+	 */
51
+	void *interface;
52
+};
53
+
54
+/** Chainloaded SNP protocol */
55
+static struct chained_protocol chained_snp = {
56
+	.protocol = &efi_simple_network_protocol_guid,
57
+};
58
+
59
+/** Chainloaded NII protocol */
60
+static struct chained_protocol chained_nii = {
61
+	.protocol = &efi_nii31_protocol_guid,
62
+};
63
+
35 64
 /**
36
- * SNP protocol instance installed on the loaded image's device handle
65
+ * Locate chainloaded protocol instance
37 66
  *
38
- * We match against the SNP protocol instance (rather than simply
39
- * matching against the device handle itself) because some systems
40
- * load us via a child of the SNP device, with a duplicate SNP
41
- * protocol installed on the child handle.
67
+ * @v chained		Chainloaded protocol
68
+ * @ret rc		Return status code
42 69
  */
43
-static EFI_SIMPLE_NETWORK_PROTOCOL *snponly;
70
+static int chained_locate ( struct chained_protocol *chained ) {
71
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
72
+	EFI_HANDLE device = efi_loaded_image->DeviceHandle;
73
+	EFI_HANDLE parent;
74
+	EFI_STATUS efirc;
75
+	int rc;
76
+
77
+	/* Locate handle supporting this protocol */
78
+	if ( ( rc = efi_locate_device ( device, chained->protocol,
79
+					&parent ) ) != 0 ) {
80
+		DBGC ( device, "CHAINED %p %s does not support %s: %s\n",
81
+		       device, efi_handle_name ( device ),
82
+		       efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );
83
+		goto err_locate_device;
84
+	}
85
+	DBGC ( device, "CHAINED %p %s found %s on ", device,
86
+	       efi_handle_name ( device ), efi_guid_ntoa ( chained->protocol ));
87
+	DBGC ( device, "%p %s\n", parent, efi_handle_name ( parent ) );
88
+
89
+	/* Get protocol instance */
90
+	if ( ( efirc = bs->OpenProtocol ( parent, chained->protocol,
91
+					  &chained->interface, efi_image_handle,
92
+					  device,
93
+					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
94
+		rc = -EEFI ( efirc );
95
+		DBGC ( device, "CHAINED %p %s could not open %s on ",
96
+		       device, efi_handle_name ( device ),
97
+		       efi_guid_ntoa ( chained->protocol ) );
98
+		DBGC ( device, "%p %s: %s\n",
99
+		       parent, efi_handle_name ( parent ), strerror ( rc ) );
100
+		goto err_open_protocol;
101
+	}
102
+
103
+ err_locate_device:
104
+	bs->CloseProtocol ( parent, chained->protocol, efi_image_handle,
105
+			    device );
106
+ err_open_protocol:
107
+	return rc;
108
+}
44 109
 
45 110
 /**
46 111
  * Check to see if driver supports a device
47 112
  *
48 113
  * @v device		EFI device handle
114
+ * @v chained		Chainloaded protocol
49 115
  * @ret rc		Return status code
50 116
  */
51
-static int snponly_supported ( EFI_HANDLE device ) {
117
+static int chained_supported ( EFI_HANDLE device,
118
+			       struct chained_protocol *chained ) {
52 119
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
53 120
 	EFI_STATUS efirc;
54
-	union {
55
-		EFI_SIMPLE_NETWORK_PROTOCOL *snp;
56
-		void *interface;
57
-	} snp;
121
+	void *interface;
58 122
 	int rc;
59 123
 
60
-	/* Get SNP protocol */
61
-	if ( ( efirc = bs->OpenProtocol ( device,
62
-					  &efi_simple_network_protocol_guid,
63
-					  &snp.interface, efi_image_handle,
64
-					  device,
124
+	/* Get protocol */
125
+	if ( ( efirc = bs->OpenProtocol ( device, chained->protocol, &interface,
126
+					  efi_image_handle, device,
65 127
 					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
66 128
 		rc = -EEFI ( efirc );
67
-		DBGCP ( device, "SNPONLY %p %s is not an SNP device\n",
68
-			device, efi_handle_name ( device ) );
69
-		goto err_not_snp;
129
+		DBGCP ( device, "CHAINED %p %s is not a %s device\n",
130
+			device, efi_handle_name ( device ),
131
+			efi_guid_ntoa ( chained->protocol ) );
132
+		goto err_open_protocol;
70 133
 	}
71 134
 
72 135
 	/* Test for a match against the chainloading device */
73
-	if ( snp.snp != snponly ) {
74
-		DBGC ( device, "SNPONLY %p %s SNP %p is not the "
75
-		       "chainloading SNP\n", device,
76
-		       efi_handle_name ( device ), snp.snp );
136
+	if ( interface != chained->interface ) {
137
+		DBGC ( device, "CHAINED %p %s %p is not the chainloaded "
138
+		       "%s\n", device, efi_handle_name ( device ),
139
+		       interface, efi_guid_ntoa ( chained->protocol ) );
77 140
 		rc = -ENOTTY;
78
-		goto err_not_snponly;
141
+		goto err_no_match;
79 142
 	}
80 143
 
81 144
 	/* Success */
82 145
 	rc = 0;
83
-	DBGC ( device, "SNPONLY %p %s SNP %p is the chainloading SNP\n",
84
-	       device, efi_handle_name ( device ), snp.snp );
146
+	DBGC ( device, "CHAINED %p %s %p is the chainloaded %s\n",
147
+	       device, efi_handle_name ( device ), interface,
148
+	       efi_guid_ntoa ( chained->protocol ) );
85 149
 
86
- err_not_snponly:
87
-	bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
88
-			    efi_image_handle, device );
89
- err_not_snp:
150
+ err_no_match:
151
+	bs->CloseProtocol ( device, chained->protocol, efi_image_handle,
152
+			    device );
153
+ err_open_protocol:
90 154
 	return rc;
91 155
 }
92 156
 
93
-/** EFI chainloading-device-only driver */
157
+/**
158
+ * Check to see if driver supports a device
159
+ *
160
+ * @v device		EFI device handle
161
+ * @ret rc		Return status code
162
+ */
163
+static int snponly_supported ( EFI_HANDLE device ) {
164
+
165
+	return chained_supported ( device, &chained_snp );
166
+}
167
+
168
+/**
169
+ * Check to see if driver supports a device
170
+ *
171
+ * @v device		EFI device handle
172
+ * @ret rc		Return status code
173
+ */
174
+static int niionly_supported ( EFI_HANDLE device ) {
175
+
176
+	return chained_supported ( device, &chained_nii );
177
+}
178
+
179
+/** EFI SNP chainloading-device-only driver */
94 180
 struct efi_driver snponly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
95 181
 	.name = "SNPONLY",
96 182
 	.supported = snponly_supported,
@@ -98,41 +184,25 @@ struct efi_driver snponly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
98 184
 	.stop = snpnet_stop,
99 185
 };
100 186
 
187
+/** EFI NII chainloading-device-only driver */
188
+struct efi_driver niionly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
189
+	.name = "NIIONLY",
190
+	.supported = niionly_supported,
191
+	.start = nii_start,
192
+	.stop = nii_stop,
193
+};
194
+
101 195
 /**
102
- * Initialise EFI chainloading-device-only driver
196
+ * Initialise EFI chainloaded-device-only driver
103 197
  *
104 198
  */
105
-static void snponly_init ( void ) {
106
-	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
107
-	EFI_HANDLE device = efi_loaded_image->DeviceHandle;
108
-	union {
109
-		EFI_SIMPLE_NETWORK_PROTOCOL *snp;
110
-		void *interface;
111
-	} snp;
112
-	EFI_STATUS efirc;
199
+static void chained_init ( void ) {
113 200
 
114
-	/* Look for SNP protocol on the loaded image's device handle */
115
-	if ( ( efirc = bs->OpenProtocol ( device,
116
-					  &efi_simple_network_protocol_guid,
117
-					  &snp.interface, efi_image_handle,
118
-					  device,
119
-					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
120
-		DBGC ( device, "SNPONLY %p %s is not an SNP device\n",
121
-		       device, efi_handle_name ( device ) );
122
-		goto err_open_protocol;
123
-	}
124
-
125
-	/* Record SNP protocol instance */
126
-	snponly = snp.snp;
127
-	DBGC ( device, "SNPONLY %p %s found chainloading SNP %p\n",
128
-	       device, efi_handle_name ( device ), snponly );
129
-
130
- err_open_protocol:
131
-	bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
132
-			    efi_image_handle, device );
201
+	chained_locate ( &chained_snp );
202
+	chained_locate ( &chained_nii );
133 203
 }
134 204
 
135
-/** EFI chainloading-device-only initialisation function */
136
-struct init_fn snponly_init_fn __init_fn ( INIT_LATE ) = {
137
-	.initialise = snponly_init,
205
+/** EFI chainloaded-device-only initialisation function */
206
+struct init_fn chained_init_fn __init_fn ( INIT_LATE ) = {
207
+	.initialise = chained_init,
138 208
 };

Loading…
Cancel
Save