Browse Source

[efi] Add basic implementation of EFI SIMPLE_NETWORK_PROTOCOL

This implementation is tested and working, but not currently tied in
to the EFI build.
tags/v0.9.6
Michael Brown 15 years ago
parent
commit
c99b16c974

+ 166
- 0
src/include/gpxe/efi/Protocol/DriverBinding.h View File

@@ -0,0 +1,166 @@
1
+/** @file
2
+  UEFI DriverBinding Protocol is defined in UEFI specification.
3
+
4
+  This protocol is produced by every driver that follows the UEFI Driver Model,
5
+  and it is the central component that allows drivers and controllers to be managed.
6
+
7
+  Copyright (c) 2006 - 2008, Intel Corporation
8
+  All rights reserved. This program and the accompanying materials
9
+  are licensed and made available under the terms and conditions of the BSD License
10
+  which accompanies this distribution.  The full text of the license may be found at
11
+  http://opensource.org/licenses/bsd-license.php
12
+
13
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
+
16
+**/
17
+
18
+#ifndef __EFI_DRIVER_BINDING_H__
19
+#define __EFI_DRIVER_BINDING_H__
20
+
21
+#include <gpxe/efi/PiDxe.h>
22
+#include <gpxe/efi/Protocol/DevicePath.h>
23
+///
24
+/// Global ID for the ControllerHandle Driver Protocol
25
+///
26
+#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
27
+  { \
28
+    0x18a031ab, 0xb443, 0x4d1a, {0xa5, 0xc0, 0xc, 0x9, 0x26, 0x1e, 0x9f, 0x71 } \
29
+  }
30
+
31
+typedef struct _EFI_DRIVER_BINDING_PROTOCOL  EFI_DRIVER_BINDING_PROTOCOL;
32
+
33
+/**
34
+  Test to see if this driver supports ControllerHandle.
35
+
36
+  @param  This                Protocol instance pointer.
37
+  @param  ControllerHandle    Handle of device to test
38
+  @param  RemainingDevicePath Optional parameter use to pick a specific child
39
+                              device to start.
40
+
41
+  @retval EFI_SUCCESS         This driver supports this device
42
+  @retval EFI_ALREADY_STARTED This driver is already running on this device
43
+  @retval other               This driver does not support this device
44
+
45
+**/
46
+typedef
47
+EFI_STATUS
48
+(EFIAPI *EFI_DRIVER_BINDING_SUPPORTED)(
49
+  IN EFI_DRIVER_BINDING_PROTOCOL            *This,
50
+  IN EFI_HANDLE                             ControllerHandle,
51
+  IN EFI_DEVICE_PATH_PROTOCOL               *RemainingDevicePath OPTIONAL
52
+  );
53
+
54
+/**
55
+  Start this driver on ControllerHandle.
56
+
57
+  @param  This                 Protocol instance pointer.
58
+  @param  ControllerHandle     Handle of device to bind driver to
59
+  @param  RemainingDevicePath  Optional parameter use to pick a specific child
60
+                               device to start.
61
+
62
+  @retval EFI_SUCCESS          This driver is added to ControllerHandle
63
+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
64
+  @retval other                This driver does not support this device
65
+
66
+**/
67
+typedef
68
+EFI_STATUS
69
+(EFIAPI *EFI_DRIVER_BINDING_START)(
70
+  IN EFI_DRIVER_BINDING_PROTOCOL            *This,
71
+  IN EFI_HANDLE                             ControllerHandle,
72
+  IN EFI_DEVICE_PATH_PROTOCOL               *RemainingDevicePath OPTIONAL
73
+  );
74
+
75
+/**
76
+  Stop this driver on ControllerHandle.
77
+
78
+  @param  This              Protocol instance pointer.
79
+  @param  ControllerHandle  Handle of device to stop driver on
80
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
81
+                            children is zero stop the entire bus driver.
82
+  @param  ChildHandleBuffer List of Child Handles to Stop.
83
+
84
+  @retval EFI_SUCCESS       This driver is removed ControllerHandle
85
+  @retval other             This driver was not removed from this device
86
+
87
+**/
88
+typedef
89
+EFI_STATUS
90
+(EFIAPI *EFI_DRIVER_BINDING_STOP)(
91
+  IN EFI_DRIVER_BINDING_PROTOCOL            *This,
92
+  IN  EFI_HANDLE                            ControllerHandle,
93
+  IN  UINTN                                 NumberOfChildren,
94
+  IN  EFI_HANDLE                            *ChildHandleBuffer OPTIONAL
95
+  );
96
+
97
+//
98
+// Interface structure for the ControllerHandle Driver Protocol
99
+//
100
+/**
101
+  @par Protocol Description:
102
+  This protocol provides the services required to determine if a driver supports a given controller.
103
+  If a controller is supported, then it also provides routines to start and stop the controller.
104
+
105
+  @param Supported
106
+  Tests to see if this driver supports a given controller. This service
107
+  is called by the EFI boot service ConnectController(). In
108
+  order to make drivers as small as possible, there are a few calling
109
+  restrictions for this service. ConnectController() must
110
+  follow these calling restrictions. If any other agent wishes to call
111
+  Supported() it must also follow these calling restrictions.
112
+
113
+
114
+  @param Start
115
+  Starts a controller using this driver. This service is called by the
116
+  EFI boot service ConnectController(). In order to make
117
+  drivers as small as possible, there are a few calling restrictions for
118
+  this service. ConnectController() must follow these
119
+  calling restrictions. If any other agent wishes to call Start() it
120
+  must also follow these calling restrictions.
121
+
122
+  @param Stop
123
+  Stops a controller using this driver. This service is called by the
124
+  EFI boot service DisconnectController(). In order to
125
+  make drivers as small as possible, there are a few calling
126
+  restrictions for this service. DisconnectController()
127
+  must follow these calling restrictions. If any other agent wishes
128
+  to call Stop() it must also follow these calling restrictions.
129
+
130
+  @param Version
131
+  The version number of the UEFI driver that produced the
132
+  EFI_DRIVER_BINDING_PROTOCOL. This field is used by
133
+  the EFI boot service ConnectController() to determine
134
+  the order that driver's Supported() service will be used when
135
+  a controller needs to be started. EFI Driver Binding Protocol
136
+  instances with higher Version values will be used before ones
137
+  with lower Version values. The Version values of 0x0-
138
+  0x0f and 0xfffffff0-0xffffffff are reserved for
139
+  platform/OEM specific drivers. The Version values of 0x10-
140
+  0xffffffef are reserved for IHV-developed drivers.
141
+
142
+  @param ImageHandle
143
+  The image handle of the UEFI driver that produced this instance
144
+  of the EFI_DRIVER_BINDING_PROTOCOL.
145
+
146
+  @param DriverBindingHandle
147
+  The handle on which this instance of the
148
+  EFI_DRIVER_BINDING_PROTOCOL is installed. In most
149
+  cases, this is the same handle as ImageHandle. However, for
150
+  UEFI drivers that produce more than one instance of the
151
+  EFI_DRIVER_BINDING_PROTOCOL, this value may not be
152
+  the same as ImageHandle.
153
+
154
+**/
155
+struct _EFI_DRIVER_BINDING_PROTOCOL {
156
+  EFI_DRIVER_BINDING_SUPPORTED  Supported;
157
+  EFI_DRIVER_BINDING_START      Start;
158
+  EFI_DRIVER_BINDING_STOP       Stop;
159
+  UINT32                        Version;
160
+  EFI_HANDLE                    ImageHandle;
161
+  EFI_HANDLE                    DriverBindingHandle;
162
+};
163
+
164
+extern EFI_GUID gEfiDriverBindingProtocolGuid;
165
+
166
+#endif

+ 577
- 0
src/include/gpxe/efi/Protocol/PciIo.h View File

@@ -0,0 +1,577 @@
1
+/** @file
2
+  EFI PCI I/O Protocol provides the basic Memory, I/O, PCI configuration,
3
+  and DMA interfaces that a driver uses to access its PCI controller.
4
+
5
+  Copyright (c) 2006 - 2008, Intel Corporation
6
+  All rights reserved. This program and the accompanying materials
7
+  are licensed and made available under the terms and conditions of the BSD License
8
+  which accompanies this distribution.  The full text of the license may be found at
9
+  http://opensource.org/licenses/bsd-license.php
10
+
11
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
+
14
+**/
15
+
16
+#ifndef __PCI_IO_H__
17
+#define __PCI_IO_H__
18
+
19
+///
20
+/// Global ID for the PCI I/O Protocol
21
+///
22
+#define EFI_PCI_IO_PROTOCOL_GUID \
23
+  { \
24
+    0x4cf5b200, 0x68b8, 0x4ca5, {0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x2, 0x9a } \
25
+  }
26
+
27
+typedef struct _EFI_PCI_IO_PROTOCOL  EFI_PCI_IO_PROTOCOL;
28
+
29
+///
30
+/// Prototypes for the PCI I/O Protocol
31
+///
32
+typedef enum {
33
+  EfiPciIoWidthUint8      = 0,
34
+  EfiPciIoWidthUint16,
35
+  EfiPciIoWidthUint32,
36
+  EfiPciIoWidthUint64,
37
+  EfiPciIoWidthFifoUint8,
38
+  EfiPciIoWidthFifoUint16,
39
+  EfiPciIoWidthFifoUint32,
40
+  EfiPciIoWidthFifoUint64,
41
+  EfiPciIoWidthFillUint8,
42
+  EfiPciIoWidthFillUint16,
43
+  EfiPciIoWidthFillUint32,
44
+  EfiPciIoWidthFillUint64,
45
+  EfiPciIoWidthMaximum
46
+} EFI_PCI_IO_PROTOCOL_WIDTH;
47
+
48
+//
49
+// Complete PCI address generater
50
+//
51
+#define EFI_PCI_IO_PASS_THROUGH_BAR               0xff    // Special BAR that passes a memory or I/O cycle through unchanged
52
+#define EFI_PCI_IO_ATTRIBUTE_MASK                 0x077f  // All the following I/O and Memory cycles
53
+#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO   0x0001  // I/O cycles 0x0000-0x00FF (10 bit decode)
54
+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO               0x0002  // I/O cycles 0x0100-0x03FF or greater (10 bit decode)
55
+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO       0x0004  // I/O cycles 0x3C6, 0x3C8, 0x3C9 (10 bit decode)
56
+#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY           0x0008  // MEM cycles 0xA0000-0xBFFFF (24 bit decode)
57
+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO               0x0010  // I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (10 bit decode)
58
+#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO       0x0020  // I/O cycles 0x1F0-0x1F7, 0x3F6, 0x3F7 (10 bit decode)
59
+#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO     0x0040  // I/O cycles 0x170-0x177, 0x376, 0x377 (10 bit decode)
60
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080  // Map a memory range so write are combined
61
+#define EFI_PCI_IO_ATTRIBUTE_IO                   0x0100  // Enable the I/O decode bit in the PCI Config Header
62
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY               0x0200  // Enable the Memory decode bit in the PCI Config Header
63
+#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER           0x0400  // Enable the DMA bit in the PCI Config Header
64
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED        0x0800  // Map a memory range so all r/w accesses are cached
65
+#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE       0x1000  // Disable a memory range
66
+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE      0x2000  // Clear for an add-in PCI Device
67
+#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         0x4000  // Clear for a physical PCI Option ROM accessed through ROM BAR
68
+#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE   0x8000  // Clear for PCI controllers that can not genrate a DAC
69
+#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16            0x10000 // I/O cycles 0x0100-0x03FF or greater (16 bit decode)
70
+#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16    0x20000 // I/O cycles 0x3C6, 0x3C8, 0x3C9 (16 bit decode)
71
+#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16            0x30000 // I/O cycles 0x3B0-0x3BB and 0x3C0-0x3DF (16 bit decode)
72
+
73
+#define EFI_PCI_DEVICE_ENABLE                     (EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER)
74
+#define EFI_VGA_DEVICE_ENABLE                     (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_IO)
75
+
76
+///
77
+/// *******************************************************
78
+/// EFI_PCI_IO_PROTOCOL_OPERATION
79
+/// *******************************************************
80
+///
81
+typedef enum {
82
+  EfiPciIoOperationBusMasterRead,
83
+  EfiPciIoOperationBusMasterWrite,
84
+  EfiPciIoOperationBusMasterCommonBuffer,
85
+  EfiPciIoOperationMaximum
86
+} EFI_PCI_IO_PROTOCOL_OPERATION;
87
+
88
+///
89
+/// *******************************************************
90
+/// EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION
91
+/// *******************************************************
92
+///
93
+typedef enum {
94
+  EfiPciIoAttributeOperationGet,
95
+  EfiPciIoAttributeOperationSet,
96
+  EfiPciIoAttributeOperationEnable,
97
+  EfiPciIoAttributeOperationDisable,
98
+  EfiPciIoAttributeOperationSupported,
99
+  EfiPciIoAttributeOperationMaximum
100
+} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;
101
+
102
+/**
103
+  Reads from the memory space of a PCI controller. Returns when either the polling exit criteria is
104
+  satisfied or after a defined duration.
105
+
106
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
107
+  @param  Width                 Signifies the width of the memory or I/O operations.
108
+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the
109
+                                base address for the memory operation to perform.
110
+  @param  Offset                The offset within the selected BAR to start the memory operation.
111
+  @param  Mask                  Mask used for the polling criteria.
112
+  @param  Value                 The comparison value used for the polling exit criteria.
113
+  @param  Delay                 The number of 100 ns units to poll.
114
+  @param  Result                Pointer to the last value read from the memory location.
115
+
116
+  @retval EFI_SUCCESS           The last data returned from the access matched the poll exit criteria.
117
+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.
118
+  @retval EFI_UNSUPPORTED       Offset is not valid for the BarIndex of this PCI controller.
119
+  @retval EFI_TIMEOUT           Delay expired before a match occurred.
120
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
121
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
122
+
123
+**/
124
+typedef
125
+EFI_STATUS
126
+(EFIAPI *EFI_PCI_IO_PROTOCOL_POLL_IO_MEM)(
127
+  IN EFI_PCI_IO_PROTOCOL           *This,
128
+  IN  EFI_PCI_IO_PROTOCOL_WIDTH    Width,
129
+  IN  UINT8                        BarIndex,
130
+  IN  UINT64                       Offset,
131
+  IN  UINT64                       Mask,
132
+  IN  UINT64                       Value,
133
+  IN  UINT64                       Delay,
134
+  OUT UINT64                       *Result
135
+  );
136
+
137
+/**
138
+  Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space.
139
+
140
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
141
+  @param  Width                 Signifies the width of the memory or I/O operations.
142
+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the
143
+                                base address for the memory or I/O operation to perform.
144
+  @param  Offset                The offset within the selected BAR to start the memory or I/O operation.
145
+  @param  Count                 The number of memory or I/O operations to perform.
146
+  @param  Buffer                For read operations, the destination buffer to store the results. For write
147
+                                operations, the source buffer to write data from.
148
+
149
+  @retval EFI_SUCCESS           The data was read from or written to the PCI controller.
150
+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.
151
+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not
152
+                                valid for the PCI BAR specified by BarIndex.
153
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
154
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
155
+
156
+**/
157
+typedef
158
+EFI_STATUS
159
+(EFIAPI *EFI_PCI_IO_PROTOCOL_IO_MEM)(
160
+  IN EFI_PCI_IO_PROTOCOL              *This,
161
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,
162
+  IN     UINT8                        BarIndex,
163
+  IN     UINT64                       Offset,
164
+  IN     UINTN                        Count,
165
+  IN OUT VOID                         *Buffer
166
+  );
167
+
168
+typedef struct {
169
+  EFI_PCI_IO_PROTOCOL_IO_MEM  Read;
170
+  EFI_PCI_IO_PROTOCOL_IO_MEM  Write;
171
+} EFI_PCI_IO_PROTOCOL_ACCESS;
172
+
173
+/**
174
+  Enable a PCI driver to access PCI controller registers in PCI configuration space.
175
+
176
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
177
+  @param  Width                 Signifies the width of the memory operations.
178
+  @param  Offset                The offset within the PCI configuration space for the PCI controller.
179
+  @param  Count                 The number of PCI configuration operations to perform.
180
+  @param  Buffer                For read operations, the destination buffer to store the results. For write
181
+                                operations, the source buffer to write data from.
182
+
183
+
184
+  @retval EFI_SUCCESS           The data was read from or written to the PCI controller.
185
+  @retval EFI_UNSUPPORTED       The address range specified by Offset, Width, and Count is not
186
+                                valid for the PCI configuration header of the PCI controller.
187
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
188
+  @retval EFI_INVALID_PARAMETER Buffer is NULL or Width is invalid.
189
+
190
+**/
191
+typedef
192
+EFI_STATUS
193
+(EFIAPI *EFI_PCI_IO_PROTOCOL_CONFIG)(
194
+  IN EFI_PCI_IO_PROTOCOL              *This,
195
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,
196
+  IN     UINT32                       Offset,
197
+  IN     UINTN                        Count,
198
+  IN OUT VOID                         *Buffer
199
+  );
200
+
201
+typedef struct {
202
+  EFI_PCI_IO_PROTOCOL_CONFIG  Read;
203
+  EFI_PCI_IO_PROTOCOL_CONFIG  Write;
204
+} EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS;
205
+
206
+/**
207
+  Enables a PCI driver to copy one region of PCI memory space to another region of PCI
208
+  memory space.
209
+
210
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
211
+  @param  Width                 Signifies the width of the memory operations.
212
+  @param  DestBarIndex          The BAR index in the standard PCI Configuration header to use as the
213
+                                base address for the memory operation to perform.
214
+  @param  DestOffset            The destination offset within the BAR specified by DestBarIndex to
215
+                                start the memory writes for the copy operation.
216
+  @param  SrcBarIndex           The BAR index in the standard PCI Configuration header to use as the
217
+                                base address for the memory operation to perform.
218
+  @param  SrcOffset             The source offset within the BAR specified by SrcBarIndex to start
219
+                                the memory reads for the copy operation.
220
+  @param  Count                 The number of memory operations to perform. Bytes moved is Width
221
+                                size * Count, starting at DestOffset and SrcOffset.
222
+
223
+  @retval EFI_SUCCESS           The data was copied from one memory region to another memory region.
224
+  @retval EFI_UNSUPPORTED       DestBarIndex not valid for this PCI controller.
225
+  @retval EFI_UNSUPPORTED       SrcBarIndex not valid for this PCI controller.
226
+  @retval EFI_UNSUPPORTED       The address range specified by DestOffset, Width, and Count
227
+                                is not valid for the PCI BAR specified by DestBarIndex.
228
+  @retval EFI_UNSUPPORTED       The address range specified by SrcOffset, Width, and Count is
229
+                                not valid for the PCI BAR specified by SrcBarIndex.
230
+  @retval EFI_INVALID_PARAMETER Width is invalid.
231
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
232
+
233
+**/
234
+typedef
235
+EFI_STATUS
236
+(EFIAPI *EFI_PCI_IO_PROTOCOL_COPY_MEM)(
237
+  IN EFI_PCI_IO_PROTOCOL              *This,
238
+  IN     EFI_PCI_IO_PROTOCOL_WIDTH    Width,
239
+  IN     UINT8                        DestBarIndex,
240
+  IN     UINT64                       DestOffset,
241
+  IN     UINT8                        SrcBarIndex,
242
+  IN     UINT64                       SrcOffset,
243
+  IN     UINTN                        Count
244
+  );
245
+
246
+/**
247
+  Provides the PCI controller-Cspecific addresses needed to access system memory.
248
+
249
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
250
+  @param  Operation             Indicates if the bus master is going to read or write to system memory.
251
+  @param  HostAddress           The system memory address to map to the PCI controller.
252
+  @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes
253
+                                that were mapped.
254
+  @param  DeviceAddress         The resulting map address for the bus master PCI controller to use to
255
+                                access the hosts HostAddress.
256
+  @param  Mapping               A resulting value to pass to Unmap().
257
+
258
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.
259
+  @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.
260
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
261
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
262
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.
263
+
264
+**/
265
+typedef
266
+EFI_STATUS
267
+(EFIAPI *EFI_PCI_IO_PROTOCOL_MAP)(
268
+  IN EFI_PCI_IO_PROTOCOL                *This,
269
+  IN     EFI_PCI_IO_PROTOCOL_OPERATION  Operation,
270
+  IN     VOID                           *HostAddress,
271
+  IN OUT UINTN                          *NumberOfBytes,
272
+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,
273
+  OUT    VOID                           **Mapping
274
+  );
275
+
276
+/**
277
+  Completes the Map() operation and releases any corresponding resources.
278
+
279
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
280
+  @param  Mapping               The mapping value returned from Map().
281
+
282
+  @retval EFI_SUCCESS           The range was unmapped.
283
+  @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.
284
+
285
+**/
286
+typedef
287
+EFI_STATUS
288
+(EFIAPI *EFI_PCI_IO_PROTOCOL_UNMAP)(
289
+  IN EFI_PCI_IO_PROTOCOL           *This,
290
+  IN  VOID                         *Mapping
291
+  );
292
+
293
+/**
294
+  Allocates pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer
295
+  mapping.
296
+
297
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
298
+  @param  Type                  This parameter is not used and must be ignored.
299
+  @param  MemoryType            The type of memory to allocate, EfiBootServicesData or
300
+                                EfiRuntimeServicesData.
301
+  @param  Pages                 The number of pages to allocate.
302
+  @param  HostAddress           A pointer to store the base system memory address of the
303
+                                allocated range.
304
+  @param  Attributes            The requested bit mask of attributes for the allocated range.
305
+
306
+  @retval EFI_SUCCESS           The requested memory pages were allocated.
307
+  @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are
308
+                                MEMORY_WRITE_COMBINE and MEMORY_CACHED.
309
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
310
+  @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.
311
+
312
+**/
313
+typedef
314
+EFI_STATUS
315
+(EFIAPI *EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER)(
316
+  IN EFI_PCI_IO_PROTOCOL           *This,
317
+  IN  EFI_ALLOCATE_TYPE            Type,
318
+  IN  EFI_MEMORY_TYPE              MemoryType,
319
+  IN  UINTN                        Pages,
320
+  OUT VOID                         **HostAddress,
321
+  IN  UINT64                       Attributes
322
+  );
323
+
324
+/**
325
+  Frees memory that was allocated with AllocateBuffer().
326
+
327
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
328
+  @param  Pages                 The number of pages to free.
329
+  @param  HostAddress           The base system memory address of the allocated range.
330
+
331
+  @retval EFI_SUCCESS           The requested memory pages were freed.
332
+  @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
333
+                                was not allocated with AllocateBuffer().
334
+
335
+**/
336
+typedef
337
+EFI_STATUS
338
+(EFIAPI *EFI_PCI_IO_PROTOCOL_FREE_BUFFER)(
339
+  IN EFI_PCI_IO_PROTOCOL           *This,
340
+  IN  UINTN                        Pages,
341
+  IN  VOID                         *HostAddress
342
+  );
343
+
344
+/**
345
+  Flushes all PCI posted write transactions from a PCI host bridge to system memory.
346
+
347
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
348
+
349
+  @retval EFI_SUCCESS           The PCI posted write transactions were flushed from the PCI host
350
+                                bridge to system memory.
351
+  @retval EFI_DEVICE_ERROR      The PCI posted write transactions were not flushed from the PCI
352
+                                host bridge due to a hardware error.
353
+
354
+**/
355
+typedef
356
+EFI_STATUS
357
+(EFIAPI *EFI_PCI_IO_PROTOCOL_FLUSH)(
358
+  IN EFI_PCI_IO_PROTOCOL  *This
359
+  );
360
+
361
+/**
362
+  Retrieves this PCI controller's current PCI bus number, device number, and function number.
363
+
364
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
365
+  @param  SegmentNumber         The PCI controller's current PCI segment number.
366
+  @param  BusNumber             The PCI controller's current PCI bus number.
367
+  @param  DeviceNumber          The PCI controller's current PCI device number.
368
+  @param  FunctionNumber        The PCI controller's current PCI function number.
369
+
370
+  @retval EFI_SUCCESS           The PCI controller location was returned.
371
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
372
+
373
+**/
374
+typedef
375
+EFI_STATUS
376
+(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_LOCATION)(
377
+  IN EFI_PCI_IO_PROTOCOL          *This,
378
+  OUT UINTN                       *SegmentNumber,
379
+  OUT UINTN                       *BusNumber,
380
+  OUT UINTN                       *DeviceNumber,
381
+  OUT UINTN                       *FunctionNumber
382
+  );
383
+
384
+/**
385
+  Performs an operation on the attributes that this PCI controller supports. The operations include
386
+  getting the set of supported attributes, retrieving the current attributes, setting the current
387
+  attributes, enabling attributes, and disabling attributes.
388
+
389
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
390
+  @param  Operation             The operation to perform on the attributes for this PCI controller.
391
+  @param  Attributes            The mask of attributes that are used for Set, Enable, and Disable
392
+                                operations.
393
+  @param  Result                A pointer to the result mask of attributes that are returned for the Get
394
+                                and Supported operations.
395
+
396
+  @retval EFI_SUCCESS           The operation on the PCI controller's attributes was completed.
397
+  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
398
+  @retval EFI_UNSUPPORTED       one or more of the bits set in
399
+                                Attributes are not supported by this PCI controller or one of
400
+                                its parent bridges when Operation is Set, Enable or Disable.
401
+
402
+**/
403
+typedef
404
+EFI_STATUS
405
+(EFIAPI *EFI_PCI_IO_PROTOCOL_ATTRIBUTES)(
406
+  IN EFI_PCI_IO_PROTOCOL                       *This,
407
+  IN  EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION  Operation,
408
+  IN  UINT64                                   Attributes,
409
+  OUT UINT64                                   *Result OPTIONAL
410
+  );
411
+
412
+/**
413
+  Gets the attributes that this PCI controller supports setting on a BAR using
414
+  SetBarAttributes(), and retrieves the list of resource descriptors for a BAR.
415
+
416
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
417
+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the
418
+                                base address for resource range. The legal range for this field is 0..5.
419
+  @param  Supports              A pointer to the mask of attributes that this PCI controller supports
420
+                                setting for this BAR with SetBarAttributes().
421
+  @param  Resources             A pointer to the ACPI 2.0 resource descriptors that describe the current
422
+                                configuration of this BAR of the PCI controller.
423
+
424
+  @retval EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI
425
+                                controller supports are returned in Supports. If Resources
426
+                                is not NULL, then the ACPI 2.0 resource descriptors that the PCI
427
+                                controller is currently using are returned in Resources.
428
+  @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
429
+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.
430
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to allocate
431
+                                Resources.
432
+
433
+**/
434
+typedef
435
+EFI_STATUS
436
+(EFIAPI *EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES)(
437
+  IN EFI_PCI_IO_PROTOCOL             *This,
438
+  IN  UINT8                          BarIndex,
439
+  OUT UINT64                         *Supports, OPTIONAL
440
+  OUT VOID                           **Resources OPTIONAL
441
+  );
442
+
443
+/**
444
+  Sets the attributes for a range of a BAR on a PCI controller.
445
+
446
+  @param  This                  A pointer to the EFI_PCI_IO_PROTOCOL instance.
447
+  @param  Attributes            The mask of attributes to set for the resource range specified by
448
+                                BarIndex, Offset, and Length.
449
+  @param  BarIndex              The BAR index of the standard PCI Configuration header to use as the
450
+                                base address for resource range. The legal range for this field is 0..5.
451
+  @param  Offset                A pointer to the BAR relative base address of the resource range to be
452
+                                modified by the attributes specified by Attributes.
453
+  @param  Length                A pointer to the length of the resource range to be modified by the
454
+                                attributes specified by Attributes.
455
+
456
+  @retval EFI_SUCCESS           The set of attributes specified by Attributes for the resource
457
+                                range specified by BarIndex, Offset, and Length were
458
+                                set on the PCI controller, and the actual resource range is returned
459
+                                in Offset and Length.
460
+  @retval EFI_INVALID_PARAMETER Offset or Length is NULL.
461
+  @retval EFI_UNSUPPORTED       BarIndex not valid for this PCI controller.
462
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to set the attributes on the
463
+                                resource range specified by BarIndex, Offset, and
464
+                                Length.
465
+
466
+**/
467
+typedef
468
+EFI_STATUS
469
+(EFIAPI *EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES)(
470
+  IN EFI_PCI_IO_PROTOCOL              *This,
471
+  IN     UINT64                       Attributes,
472
+  IN     UINT8                        BarIndex,
473
+  IN OUT UINT64                       *Offset,
474
+  IN OUT UINT64                       *Length
475
+  );
476
+
477
+/**
478
+  @par Protocol Description:
479
+  The EFI_PCI_IO_PROTOCOL provides the basic Memory, I/O, PCI configuration,
480
+  and DMA interfaces that are used to abstract accesses to PCI controllers.
481
+  There is one EFI_PCI_IO_PROTOCOL instance for each PCI controller on a PCI bus.
482
+  A device driver that wishes to manage a PCI controller in a system will have to
483
+  retrieve the EFI_PCI_IO_PROTOCOL instance that is associated with the PCI controller.
484
+
485
+  @param PollMem
486
+  Polls an address in PCI memory space until an exit condition is met, or a timeout occurs.
487
+
488
+  @param PollIo
489
+  Polls an address in PCI I/O space until an exit condition is met, or a timeout occurs.
490
+
491
+  @param Mem.Read
492
+  Allows BAR relative reads to PCI memory space.
493
+
494
+  @param Mem.Write
495
+  Allows BAR relative writes to PCI memory space.
496
+
497
+  @param Io.Read
498
+  Allows BAR relative reads to PCI I/O space.
499
+
500
+  @param Io.Write
501
+  Allows BAR relative writes to PCI I/O space.
502
+
503
+  @param Pci.Read
504
+  Allows PCI controller relative reads to PCI configuration space.
505
+
506
+  @param Pci.Write
507
+  Allows PCI controller relative writes to PCI configuration space.
508
+
509
+  @param CopyMem
510
+  Allows one region of PCI memory space to be copied to another region of PCI memory space.
511
+
512
+  @param Map
513
+  Provides the PCI controller's specific address needed to access system memory for DMA.
514
+
515
+  @param Unmap
516
+  Releases any resources allocated by Map().
517
+
518
+  @param AllocateBuffer
519
+  Allocates pages that are suitable for a common buffer mapping.
520
+
521
+  @param FreeBuffer
522
+  Frees pages that were allocated with AllocateBuffer().
523
+
524
+  @param Flush
525
+  Flushes all PCI posted write transactions to system memory.
526
+
527
+  @param GetLocation
528
+  Retrieves this PCI controller's current PCI bus number, device number, and function number.
529
+
530
+  @param Attributes
531
+  Performs an operation on the attributes that this PCI controller supports.
532
+  The operations include getting the set of supported attributes, retrieving
533
+  the current attributes, setting the current
534
+  attributes, enabling attributes, and disabling attributes.
535
+
536
+  @param GetBarAttributes
537
+  Gets the attributes that this PCI controller supports setting on a BAR using
538
+  SetBarAttributes(), and retrieves the list of resource descriptors for a BAR.
539
+
540
+  @param SetBarAttributes
541
+  Sets the attributes for a range of a BAR on a PCI controller.
542
+
543
+  @param RomSize
544
+  The size, in bytes, of the ROM image.
545
+
546
+  @param RomImage
547
+  A pointer to the in memory copy of the ROM image. The PCI Bus Driver is responsible
548
+  for allocating memory for the ROM image, and copying the contents of the ROM to memory.
549
+  The contents of this buffer are either from the PCI option ROM that can be accessed
550
+  through the ROM BAR of the PCI controller, or it is from a platform-specific location.
551
+  The Attributes() function can be used to determine from which of these two sources
552
+  the RomImage buffer was initialized.
553
+
554
+**/
555
+struct _EFI_PCI_IO_PROTOCOL {
556
+  EFI_PCI_IO_PROTOCOL_POLL_IO_MEM         PollMem;
557
+  EFI_PCI_IO_PROTOCOL_POLL_IO_MEM         PollIo;
558
+  EFI_PCI_IO_PROTOCOL_ACCESS              Mem;
559
+  EFI_PCI_IO_PROTOCOL_ACCESS              Io;
560
+  EFI_PCI_IO_PROTOCOL_CONFIG_ACCESS       Pci;
561
+  EFI_PCI_IO_PROTOCOL_COPY_MEM            CopyMem;
562
+  EFI_PCI_IO_PROTOCOL_MAP                 Map;
563
+  EFI_PCI_IO_PROTOCOL_UNMAP               Unmap;
564
+  EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER     AllocateBuffer;
565
+  EFI_PCI_IO_PROTOCOL_FREE_BUFFER         FreeBuffer;
566
+  EFI_PCI_IO_PROTOCOL_FLUSH               Flush;
567
+  EFI_PCI_IO_PROTOCOL_GET_LOCATION        GetLocation;
568
+  EFI_PCI_IO_PROTOCOL_ATTRIBUTES          Attributes;
569
+  EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES  GetBarAttributes;
570
+  EFI_PCI_IO_PROTOCOL_SET_BAR_ATTRIBUTES  SetBarAttributes;
571
+  UINT64                                  RomSize;
572
+  VOID                                    *RomImage;
573
+};
574
+
575
+extern EFI_GUID gEfiPciIoProtocolGuid;
576
+
577
+#endif

+ 645
- 0
src/include/gpxe/efi/Protocol/SimpleNetwork.h View File

@@ -0,0 +1,645 @@
1
+/** @file
2
+  Simple Network protocol as defined in the UEFI 2.0 specification.
3
+
4
+  Basic network device abstraction.
5
+
6
+  Rx    - Received
7
+  Tx    - Transmit
8
+  MCast - MultiCast
9
+  ...
10
+
11
+  Copyright (c) 2006 - 2008, Intel Corporation
12
+  All rights reserved. This program and the accompanying materials
13
+  are licensed and made available under the terms and conditions of the BSD License
14
+  which accompanies this distribution.  The full text of the license may be found at
15
+  http://opensource.org/licenses/bsd-license.php
16
+
17
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19
+
20
+**/
21
+
22
+#ifndef __SIMPLE_NETWORK_H__
23
+#define __SIMPLE_NETWORK_H__
24
+
25
+#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \
26
+  { \
27
+    0xA19832B9, 0xAC25, 0x11D3, {0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D } \
28
+  }
29
+
30
+typedef struct _EFI_SIMPLE_NETWORK_PROTOCOL  EFI_SIMPLE_NETWORK_PROTOCOL;
31
+
32
+
33
+///
34
+/// Protocol defined in EFI1.1.
35
+///
36
+typedef EFI_SIMPLE_NETWORK_PROTOCOL   EFI_SIMPLE_NETWORK;
37
+
38
+///
39
+/// Simple Network Protocol data structures
40
+///
41
+typedef struct {
42
+  ///
43
+  /// Total number of frames received.  Includes frames with errors and
44
+  /// dropped frames.
45
+  ///
46
+  UINT64  RxTotalFrames;
47
+
48
+  ///
49
+  /// Number of valid frames received and copied into receive buffers.
50
+  ///
51
+  UINT64  RxGoodFrames;
52
+
53
+  ///
54
+  /// Number of frames below the minimum length for the media.
55
+  /// This would be <64 for ethernet.
56
+  ///
57
+  UINT64  RxUndersizeFrames;
58
+
59
+  ///
60
+  /// Number of frames longer than the maxminum length for the
61
+  /// media.  This would be >1500 for ethernet.
62
+  ///
63
+  UINT64  RxOversizeFrames;
64
+
65
+  ///
66
+  /// Valid frames that were dropped because receive buffers were full.
67
+  ///
68
+  UINT64  RxDroppedFrames;
69
+
70
+  ///
71
+  /// Number of valid unicast frames received and not dropped.
72
+  ///
73
+  UINT64  RxUnicastFrames;
74
+
75
+  ///
76
+  /// Number of valid broadcast frames received and not dropped.
77
+  ///
78
+  UINT64  RxBroadcastFrames;
79
+
80
+  ///
81
+  /// Number of valid mutlicast frames received and not dropped.
82
+  ///
83
+  UINT64  RxMulticastFrames;
84
+
85
+  ///
86
+  /// Number of frames w/ CRC or alignment errors.
87
+  ///
88
+  UINT64  RxCrcErrorFrames;
89
+
90
+  ///
91
+  /// Total number of bytes received.  Includes frames with errors
92
+  /// and dropped frames.
93
+  //
94
+  UINT64  RxTotalBytes;
95
+
96
+  ///
97
+  /// Transmit statistics.
98
+  ///
99
+  UINT64  TxTotalFrames;
100
+  UINT64  TxGoodFrames;
101
+  UINT64  TxUndersizeFrames;
102
+  UINT64  TxOversizeFrames;
103
+  UINT64  TxDroppedFrames;
104
+  UINT64  TxUnicastFrames;
105
+  UINT64  TxBroadcastFrames;
106
+  UINT64  TxMulticastFrames;
107
+  UINT64  TxCrcErrorFrames;
108
+  UINT64  TxTotalBytes;
109
+
110
+  ///
111
+  /// Number of collisions detection on this subnet.
112
+  ///
113
+  UINT64  Collisions;
114
+
115
+  ///
116
+  /// Number of frames destined for unsupported protocol.
117
+  ///
118
+  UINT64  UnsupportedProtocol;
119
+
120
+} EFI_NETWORK_STATISTICS;
121
+
122
+typedef enum {
123
+  EfiSimpleNetworkStopped,
124
+  EfiSimpleNetworkStarted,
125
+  EfiSimpleNetworkInitialized,
126
+  EfiSimpleNetworkMaxState
127
+} EFI_SIMPLE_NETWORK_STATE;
128
+
129
+#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST                0x01
130
+#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST              0x02
131
+#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST              0x04
132
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS            0x08
133
+#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST  0x10
134
+
135
+#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT              0x01
136
+#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT             0x02
137
+#define EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT              0x04
138
+#define EFI_SIMPLE_NETWORK_SOFTWARE_INTERRUPT             0x08
139
+
140
+#define MAX_MCAST_FILTER_CNT                              16
141
+typedef struct {
142
+  UINT32          State;
143
+  UINT32          HwAddressSize;
144
+  UINT32          MediaHeaderSize;
145
+  UINT32          MaxPacketSize;
146
+  UINT32          NvRamSize;
147
+  UINT32          NvRamAccessSize;
148
+  UINT32          ReceiveFilterMask;
149
+  UINT32          ReceiveFilterSetting;
150
+  UINT32          MaxMCastFilterCount;
151
+  UINT32          MCastFilterCount;
152
+  EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT];
153
+  EFI_MAC_ADDRESS CurrentAddress;
154
+  EFI_MAC_ADDRESS BroadcastAddress;
155
+  EFI_MAC_ADDRESS PermanentAddress;
156
+  UINT8           IfType;
157
+  BOOLEAN         MacAddressChangeable;
158
+  BOOLEAN         MultipleTxSupported;
159
+  BOOLEAN         MediaPresentSupported;
160
+  BOOLEAN         MediaPresent;
161
+} EFI_SIMPLE_NETWORK_MODE;
162
+
163
+//
164
+// Protocol Member Functions
165
+//
166
+/**
167
+  Changes the state of a network interface from "stopped" to "started".
168
+
169
+  @param  This Protocol instance pointer.
170
+
171
+  @retval EFI_SUCCESS           The network interface was started.
172
+  @retval EFI_ALREADY_STARTED   The network interface is already in the started state.
173
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
174
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
175
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
176
+
177
+**/
178
+typedef
179
+EFI_STATUS
180
+(EFIAPI *EFI_SIMPLE_NETWORK_START)(
181
+  IN EFI_SIMPLE_NETWORK_PROTOCOL  *This
182
+  );
183
+
184
+/**
185
+  Changes the state of a network interface from "started" to "stopped".
186
+
187
+  @param  This Protocol instance pointer.
188
+
189
+  @retval EFI_SUCCESS           The network interface was stopped.
190
+  @retval EFI_ALREADY_STARTED   The network interface is already in the stopped state.
191
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
192
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
193
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
194
+
195
+**/
196
+typedef
197
+EFI_STATUS
198
+(EFIAPI *EFI_SIMPLE_NETWORK_STOP)(
199
+  IN EFI_SIMPLE_NETWORK_PROTOCOL  *This
200
+  );
201
+
202
+/**
203
+  Resets a network adapter and allocates the transmit and receive buffers
204
+  required by the network interface; optionally, also requests allocation
205
+  of additional transmit and receive buffers.
206
+
207
+  @param  This              Protocol instance pointer.
208
+  @param  ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
209
+                            that the driver should allocate for the network interface.
210
+                            Some network interfaces will not be able to use the extra
211
+                            buffer, and the caller will not know if it is actually
212
+                            being used.
213
+  @param  ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
214
+                            that the driver should allocate for the network interface.
215
+                            Some network interfaces will not be able to use the extra
216
+                            buffer, and the caller will not know if it is actually
217
+                            being used.
218
+
219
+  @retval EFI_SUCCESS           The network interface was initialized.
220
+  @retval EFI_NOT_STARTED       The network interface has not been started
221
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and
222
+                                receive buffers.   .
223
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
224
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
225
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
226
+
227
+**/
228
+typedef
229
+EFI_STATUS
230
+(EFIAPI *EFI_SIMPLE_NETWORK_INITIALIZE)(
231
+  IN EFI_SIMPLE_NETWORK_PROTOCOL                    *This,
232
+  IN UINTN                                          ExtraRxBufferSize  OPTIONAL,
233
+  IN UINTN                                          ExtraTxBufferSize  OPTIONAL
234
+  );
235
+
236
+/**
237
+  Resets a network adapter and re-initializes it with the parameters that were
238
+  provided in the previous call to Initialize().
239
+
240
+  @param  This                 Protocol instance pointer.
241
+  @param  ExtendedVerification Indicates that the driver may perform a more
242
+                               exhaustive verification operation of the device
243
+                               during reset.
244
+
245
+  @retval EFI_SUCCESS           The network interface was reset.
246
+  @retval EFI_NOT_STARTED       The network interface has not been started
247
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
248
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
249
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
250
+
251
+**/
252
+typedef
253
+EFI_STATUS
254
+(EFIAPI *EFI_SIMPLE_NETWORK_RESET)(
255
+  IN EFI_SIMPLE_NETWORK_PROTOCOL   *This,
256
+  IN BOOLEAN                       ExtendedVerification
257
+  );
258
+
259
+/**
260
+  Resets a network adapter and leaves it in a state that is safe for
261
+  another driver to initialize.
262
+
263
+  @param  This Protocol instance pointer.
264
+
265
+  @retval EFI_SUCCESS           The network interface was shutdown.
266
+  @retval EFI_NOT_STARTED       The network interface has not been started
267
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
268
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
269
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
270
+
271
+**/
272
+typedef
273
+EFI_STATUS
274
+(EFIAPI *EFI_SIMPLE_NETWORK_SHUTDOWN)(
275
+  IN EFI_SIMPLE_NETWORK_PROTOCOL  *This
276
+  );
277
+
278
+/**
279
+  Manages the multicast receive filters of a network interface.
280
+
281
+  @param  This             Protocol instance pointer.
282
+  @param  Enable           A bit mask of receive filters to enable on the network interface.
283
+  @param  Disable          A bit mask of receive filters to disable on the network interface.
284
+  @param  ResetMCastFilter Set to TRUE to reset the contents of the multicast receive
285
+                           filters on the network interface to their default values.
286
+  @param  McastFilterCnt   Number of multicast HW MAC addresses in the new
287
+                           MCastFilter list. This value must be less than or equal to
288
+                           the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This
289
+                           field is optional if ResetMCastFilter is TRUE.
290
+  @param  MCastFilter      A pointer to a list of new multicast receive filter HW MAC
291
+                           addresses. This list will replace any existing multicast
292
+                           HW MAC address list. This field is optional if
293
+                           ResetMCastFilter is TRUE.
294
+
295
+  @retval EFI_SUCCESS           The multicast receive filter list was updated.
296
+  @retval EFI_NOT_STARTED       The network interface has not been started
297
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
298
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
299
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
300
+
301
+**/
302
+typedef
303
+EFI_STATUS
304
+(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)(
305
+  IN EFI_SIMPLE_NETWORK_PROTOCOL                             *This,
306
+  IN UINT32                                                  Enable,
307
+  IN UINT32                                                  Disable,
308
+  IN BOOLEAN                                                 ResetMCastFilter,
309
+  IN UINTN                                                   MCastFilterCnt     OPTIONAL,
310
+  IN EFI_MAC_ADDRESS                                         *MCastFilter OPTIONAL
311
+  );
312
+
313
+/**
314
+  Modifies or resets the current station address, if supported.
315
+
316
+  @param  This  Protocol instance pointer.
317
+  @param  Reset Flag used to reset the station address to the network interfaces
318
+                permanent address.
319
+  @param  New   New station address to be used for the network interface.
320
+
321
+  @retval EFI_SUCCESS           The network interfaces station address was updated.
322
+  @retval EFI_NOT_STARTED       The network interface has not been started
323
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
324
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
325
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
326
+
327
+**/
328
+typedef
329
+EFI_STATUS
330
+(EFIAPI *EFI_SIMPLE_NETWORK_STATION_ADDRESS)(
331
+  IN EFI_SIMPLE_NETWORK_PROTOCOL            *This,
332
+  IN BOOLEAN                                Reset,
333
+  IN EFI_MAC_ADDRESS                        *New OPTIONAL
334
+  );
335
+
336
+/**
337
+  Resets or collects the statistics on a network interface.
338
+
339
+  @param  This            Protocol instance pointer.
340
+  @param  Reset           Set to TRUE to reset the statistics for the network interface.
341
+  @param  StatisticsSize  On input the size, in bytes, of StatisticsTable. On
342
+                          output the size, in bytes, of the resulting table of
343
+                          statistics.
344
+  @param  StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
345
+                          contains the statistics.
346
+
347
+  @retval EFI_SUCCESS           The statistics were collected from the network interface.
348
+  @retval EFI_NOT_STARTED       The network interface has not been started.
349
+  @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
350
+                                size needed to hold the statistics is returned in
351
+                                StatisticsSize.
352
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
353
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
354
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
355
+
356
+**/
357
+typedef
358
+EFI_STATUS
359
+(EFIAPI *EFI_SIMPLE_NETWORK_STATISTICS)(
360
+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,
361
+  IN BOOLEAN                              Reset,
362
+  IN OUT UINTN                            *StatisticsSize   OPTIONAL,
363
+  OUT EFI_NETWORK_STATISTICS              *StatisticsTable  OPTIONAL
364
+  );
365
+
366
+/**
367
+  Converts a multicast IP address to a multicast HW MAC address.
368
+
369
+  @param  This Protocol instance pointer.
370
+  @param  IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
371
+               to FALSE if the multicast IP address is IPv4 [RFC 791].
372
+  @param  IP   The multicast IP address that is to be converted to a multicast
373
+               HW MAC address.
374
+  @param  MAC  The multicast HW MAC address that is to be generated from IP.
375
+
376
+  @retval EFI_SUCCESS           The multicast IP address was mapped to the multicast
377
+                                HW MAC address.
378
+  @retval EFI_NOT_STARTED       The network interface has not been started.
379
+  @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
380
+                                size needed to hold the statistics is returned in
381
+                                StatisticsSize.
382
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
383
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
384
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
385
+
386
+**/
387
+typedef
388
+EFI_STATUS
389
+(EFIAPI *EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)(
390
+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,
391
+  IN BOOLEAN                              IPv6,
392
+  IN EFI_IP_ADDRESS                       *IP,
393
+  OUT EFI_MAC_ADDRESS                     *MAC
394
+  );
395
+
396
+/**
397
+  Performs read and write operations on the NVRAM device attached to a
398
+  network interface.
399
+
400
+  @param  This       Protocol instance pointer.
401
+  @param  ReadWrite  TRUE for read operations, FALSE for write operations.
402
+  @param  Offset     Byte offset in the NVRAM device at which to start the read or
403
+                     write operation. This must be a multiple of NvRamAccessSize and
404
+                     less than NvRamSize.
405
+  @param  BufferSize The number of bytes to read or write from the NVRAM device.
406
+                     This must also be a multiple of NvramAccessSize.
407
+  @param  Buffer     A pointer to the data buffer.
408
+
409
+  @retval EFI_SUCCESS           The NVRAM access was performed.
410
+  @retval EFI_NOT_STARTED       The network interface has not been started.
411
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
412
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
413
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
414
+
415
+**/
416
+typedef
417
+EFI_STATUS
418
+(EFIAPI *EFI_SIMPLE_NETWORK_NVDATA)(
419
+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,
420
+  IN BOOLEAN                              ReadWrite,
421
+  IN UINTN                                Offset,
422
+  IN UINTN                                BufferSize,
423
+  IN OUT VOID                             *Buffer
424
+  );
425
+
426
+/**
427
+  Reads the current interrupt status and recycled transmit buffer status from
428
+  a network interface.
429
+
430
+  @param  This            Protocol instance pointer.
431
+  @param  InterruptStatus A pointer to the bit mask of the currently active interrupts
432
+                          If this is NULL, the interrupt status will not be read from
433
+                          the device. If this is not NULL, the interrupt status will
434
+                          be read from the device. When the  interrupt status is read,
435
+                          it will also be cleared. Clearing the transmit  interrupt
436
+                          does not empty the recycled transmit buffer array.
437
+  @param  TxBuf           Recycled transmit buffer address. The network interface will
438
+                          not transmit if its internal recycled transmit buffer array
439
+                          is full. Reading the transmit buffer does not clear the
440
+                          transmit interrupt. If this is NULL, then the transmit buffer
441
+                          status will not be read. If there are no transmit buffers to
442
+                          recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
443
+
444
+  @retval EFI_SUCCESS           The status of the network interface was retrieved.
445
+  @retval EFI_NOT_STARTED       The network interface has not been started.
446
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
447
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
448
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
449
+
450
+**/
451
+typedef
452
+EFI_STATUS
453
+(EFIAPI *EFI_SIMPLE_NETWORK_GET_STATUS)(
454
+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,
455
+  OUT UINT32                              *InterruptStatus OPTIONAL,
456
+  OUT VOID                                **TxBuf OPTIONAL
457
+  );
458
+
459
+/**
460
+  Places a packet in the transmit queue of a network interface.
461
+
462
+  @param  This       Protocol instance pointer.
463
+  @param  HeaderSize The size, in bytes, of the media header to be filled in by
464
+                     the Transmit() function. If HeaderSize is non-zero, then it
465
+                     must be equal to This->Mode->MediaHeaderSize and the DestAddr
466
+                     and Protocol parameters must not be NULL.
467
+  @param  BufferSize The size, in bytes, of the entire packet (media header and
468
+                     data) to be transmitted through the network interface.
469
+  @param  Buffer     A pointer to the packet (media header followed by data) to be
470
+                     transmitted. This parameter cannot be NULL. If HeaderSize is zero,
471
+                     then the media header in Buffer must already be filled in by the
472
+                     caller. If HeaderSize is non-zero, then the media header will be
473
+                     filled in by the Transmit() function.
474
+  @param  SrcAddr    The source HW MAC address. If HeaderSize is zero, then this parameter
475
+                     is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
476
+                     This->Mode->CurrentAddress is used for the source HW MAC address.
477
+  @param  DsetAddr   The destination HW MAC address. If HeaderSize is zero, then this
478
+                     parameter is ignored.
479
+  @param  Protocol   The type of header to build. If HeaderSize is zero, then this
480
+                     parameter is ignored. See RFC 1700, section "Ether Types", for
481
+                     examples.
482
+
483
+  @retval EFI_SUCCESS           The packet was placed on the transmit queue.
484
+  @retval EFI_NOT_STARTED       The network interface has not been started.
485
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
486
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
487
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
488
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
489
+  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.
490
+
491
+**/
492
+typedef
493
+EFI_STATUS
494
+(EFIAPI *EFI_SIMPLE_NETWORK_TRANSMIT)(
495
+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,
496
+  IN UINTN                                HeaderSize,
497
+  IN UINTN                                BufferSize,
498
+  IN VOID                                 *Buffer,
499
+  IN EFI_MAC_ADDRESS                      *SrcAddr  OPTIONAL,
500
+  IN EFI_MAC_ADDRESS                      *DestAddr OPTIONAL,
501
+  IN UINT16                               *Protocol OPTIONAL
502
+  );
503
+
504
+/**
505
+  Receives a packet from a network interface.
506
+
507
+  @param  This       Protocol instance pointer.
508
+  @param  HeaderSize The size, in bytes, of the media header received on the network
509
+                     interface. If this parameter is NULL, then the media header size
510
+                     will not be returned.
511
+  @param  BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
512
+                     bytes, of the packet that was received on the network interface.
513
+  @param  Buffer     A pointer to the data buffer to receive both the media header and
514
+                     the data.
515
+  @param  SrcAddr    The source HW MAC address. If this parameter is NULL, the
516
+                     HW MAC source address will not be extracted from the media
517
+                     header.
518
+  @param  DsetAddr   The destination HW MAC address. If this parameter is NULL,
519
+                     the HW MAC destination address will not be extracted from the
520
+                     media header.
521
+  @param  Protocol   The media header type. If this parameter is NULL, then the
522
+                     protocol will not be extracted from the media header. See
523
+                     RFC 1700 section "Ether Types" for examples.
524
+
525
+  @retval  EFI_SUCCESS           The received data was stored in Buffer, and BufferSize has
526
+                                 been updated to the number of bytes received.
527
+  @retval  EFI_NOT_STARTED       The network interface has not been started.
528
+  @retval  EFI_NOT_READY         The network interface is too busy to accept this transmit
529
+                                 request.
530
+  @retval  EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
531
+  @retval  EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
532
+  @retval  EFI_DEVICE_ERROR      The command could not be sent to the network interface.
533
+  @retval  EFI_UNSUPPORTED       This function is not supported by the network interface.
534
+
535
+**/
536
+typedef
537
+EFI_STATUS
538
+(EFIAPI *EFI_SIMPLE_NETWORK_RECEIVE)(
539
+  IN EFI_SIMPLE_NETWORK_PROTOCOL          *This,
540
+  OUT UINTN                               *HeaderSize OPTIONAL,
541
+  IN OUT UINTN                            *BufferSize,
542
+  OUT VOID                                *Buffer,
543
+  OUT EFI_MAC_ADDRESS                     *SrcAddr    OPTIONAL,
544
+  OUT EFI_MAC_ADDRESS                     *DestAddr   OPTIONAL,
545
+  OUT UINT16                              *Protocol   OPTIONAL
546
+  );
547
+
548
+#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION  0x00010000
549
+
550
+//
551
+// Revision defined in EFI1.1
552
+//
553
+#define EFI_SIMPLE_NETWORK_INTERFACE_REVISION   EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
554
+
555
+/**
556
+  @par Protocol Description:
557
+  The EFI_SIMPLE_NETWORK_PROTOCOL protocol is used to initialize access
558
+  to a network adapter. Once the network adapter initializes,
559
+  the EFI_SIMPLE_NETWORK_PROTOCOL protocol provides services that
560
+  allow packets to be transmitted and received.
561
+
562
+  @param Revision
563
+  Revision of the EFI_SIMPLE_NETWORK_PROTOCOL. All future revisions must
564
+  be backwards compatible. If a future version is not backwards compatible
565
+  it is not the same GUID.
566
+
567
+  @param Start
568
+  Prepares the network interface for further command operations.
569
+  No other EFI_SIMPLE_NETWORK_PROTOCOL interface functions will operate
570
+  until this call is made.
571
+
572
+  @param Stop
573
+  Stops further network interface command processing.
574
+  No other EFI_SIMPLE_NETWORK_PROTOCOL interface functions will operate
575
+  after this call is made until another Start() call is made.
576
+
577
+  @param Initialize
578
+  Resets the network adapter and allocates the transmit and receive buffers.
579
+
580
+  @param Reset
581
+  Resets the network adapter and reinitializes it with the parameters
582
+  provided in the previous call to Initialize().
583
+
584
+  @param Shutdown
585
+  Resets the network adapter and leaves it in a state safe for another driver
586
+  to initialize. The memory buffers assigned in the Initialize() call are released.
587
+  After this call, only the Initialize() or Stop() calls may be used.
588
+
589
+  @param ReceiveFilters
590
+  Enables and disables the receive filters for the network interface and,
591
+  if supported, manages the filtered multicast
592
+  HW MAC (Hardware Media Access Control) address list.
593
+
594
+  @param StationAddress
595
+  Modifies or resets the current station address, if supported.
596
+
597
+  @param Statistics
598
+  Collects statistics from the network interface and allows the statistics to be reset.
599
+
600
+  @param MCastIpToMac
601
+  Maps a multicast IP address to a multicast HW MAC address.
602
+
603
+  @param NvData
604
+  Reads and writes the contents of the NVRAM devices attached to the network interface.
605
+
606
+  @param GetStatus
607
+  Reads the current interrupt status and the list of recycled transmit
608
+  buffers from the network interface.
609
+
610
+  @param Transmit
611
+  Places a packet in the transmit queue.
612
+
613
+  @param Receive
614
+  Retrieves a packet from the receive queue, along with the status
615
+  flags that describe the packet type.
616
+
617
+  @param WaitForPacket
618
+  Event used with WaitForEvent() to wait for a packet to be received.
619
+
620
+  @param Mode
621
+  Pointer to the EFI_SIMPLE_NETWORK_MODE data for the device.
622
+
623
+**/
624
+struct _EFI_SIMPLE_NETWORK_PROTOCOL {
625
+  UINT64                              Revision;
626
+  EFI_SIMPLE_NETWORK_START            Start;
627
+  EFI_SIMPLE_NETWORK_STOP             Stop;
628
+  EFI_SIMPLE_NETWORK_INITIALIZE       Initialize;
629
+  EFI_SIMPLE_NETWORK_RESET            Reset;
630
+  EFI_SIMPLE_NETWORK_SHUTDOWN         Shutdown;
631
+  EFI_SIMPLE_NETWORK_RECEIVE_FILTERS  ReceiveFilters;
632
+  EFI_SIMPLE_NETWORK_STATION_ADDRESS  StationAddress;
633
+  EFI_SIMPLE_NETWORK_STATISTICS       Statistics;
634
+  EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC  MCastIpToMac;
635
+  EFI_SIMPLE_NETWORK_NVDATA           NvData;
636
+  EFI_SIMPLE_NETWORK_GET_STATUS       GetStatus;
637
+  EFI_SIMPLE_NETWORK_TRANSMIT         Transmit;
638
+  EFI_SIMPLE_NETWORK_RECEIVE          Receive;
639
+  EFI_EVENT                           WaitForPacket;
640
+  EFI_SIMPLE_NETWORK_MODE             *Mode;
641
+};
642
+
643
+extern EFI_GUID gEfiSimpleNetworkProtocolGuid;
644
+
645
+#endif

+ 1
- 0
src/include/gpxe/errfile.h View File

@@ -158,6 +158,7 @@
158 158
 #define ERRFILE_ifmgmt		      ( ERRFILE_OTHER | 0x000e0000 )
159 159
 #define ERRFILE_iscsiboot	      ( ERRFILE_OTHER | 0x000f0000 )
160 160
 #define ERRFILE_efi_pci		      ( ERRFILE_OTHER | 0x00100000 )
161
+#define ERRFILE_efi_snp		      ( ERRFILE_OTHER | 0x00110000 )
161 162
 
162 163
 /** @} */
163 164
 

+ 978
- 0
src/interface/efi/efi_snp.c View File

@@ -0,0 +1,978 @@
1
+/*
2
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdlib.h>
20
+#include <string.h>
21
+#include <errno.h>
22
+#include <assert.h>
23
+#include <byteswap.h>
24
+#include <gpxe/netdevice.h>
25
+#include <gpxe/iobuf.h>
26
+#include <gpxe/in.h>
27
+#include <gpxe/pci.h>
28
+#include <gpxe/efi/efi.h>
29
+#include <gpxe/efi/Protocol/DriverBinding.h>
30
+#include <gpxe/efi/Protocol/PciIo.h>
31
+#include <gpxe/efi/Protocol/SimpleNetwork.h>
32
+
33
+/** @file
34
+ *
35
+ * gPXE EFI SNP interface
36
+ *
37
+ */
38
+
39
+/** An SNP device */
40
+struct efi_snp_device {
41
+	/** The underlying gPXE network device */
42
+	struct net_device *netdev;
43
+	/** The SNP structure itself */
44
+	EFI_SIMPLE_NETWORK_PROTOCOL snp;
45
+	/** The SNP "mode" (parameters) */
46
+	EFI_SIMPLE_NETWORK_MODE mode;
47
+	/** Outstanding TX packet count (via "interrupt status")
48
+	 *
49
+	 * Used in order to generate TX completions.
50
+	 */
51
+	unsigned int tx_count_interrupts;
52
+	/** Outstanding TX packet count (via "recycled tx buffers")
53
+	 *
54
+	 * Used in order to generate TX completions.
55
+	 */
56
+	unsigned int tx_count_txbufs;
57
+	/** Outstanding RX packet count (via "interrupt status") */
58
+	unsigned int rx_count_interrupts;
59
+	/** Outstanding RX packet count (via WaitForPacket event) */
60
+	unsigned int rx_count_events;
61
+};
62
+
63
+/** EFI simple network protocol GUID */
64
+static EFI_GUID efi_simple_network_protocol_guid
65
+	= EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
66
+
67
+/** EFI driver binding protocol GUID */
68
+static EFI_GUID efi_driver_binding_protocol_guid
69
+	= EFI_DRIVER_BINDING_PROTOCOL_GUID;
70
+
71
+/** EFI PCI I/O protocol GUID */
72
+static EFI_GUID efi_pci_io_protocol_guid
73
+	= EFI_PCI_IO_PROTOCOL_GUID;
74
+
75
+/**
76
+ * Set EFI SNP mode based on gPXE net device parameters
77
+ *
78
+ * @v snp		SNP interface
79
+ */
80
+static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
81
+	struct net_device *netdev = snpdev->netdev;
82
+	EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
83
+	unsigned int ll_addr_len = netdev->ll_protocol->ll_addr_len;
84
+
85
+	mode->HwAddressSize = ll_addr_len;
86
+	mode->MediaHeaderSize = netdev->ll_protocol->ll_header_len;
87
+	mode->MaxPacketSize = netdev->max_pkt_len;
88
+	mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
89
+				    EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
90
+				    EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST );
91
+	assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
92
+	memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
93
+	memcpy ( &mode->BroadcastAddress, netdev->ll_protocol->ll_broadcast,
94
+		 ll_addr_len );
95
+	memcpy ( &mode->PermanentAddress, netdev->ll_addr, ll_addr_len );
96
+	mode->IfType = ntohs ( netdev->ll_protocol->ll_proto );
97
+	mode->MacAddressChangeable = TRUE;
98
+	mode->MediaPresentSupported = TRUE;
99
+	mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
100
+}
101
+
102
+/**
103
+ * Poll net device and count received packets
104
+ *
105
+ * @v snpdev		SNP device
106
+ */
107
+static void efi_snp_poll ( struct efi_snp_device *snpdev ) {
108
+	struct io_buffer *iobuf;
109
+	unsigned int before = 0;
110
+	unsigned int after = 0;
111
+	unsigned int arrived;
112
+
113
+	/* We have to report packet arrivals, and this is the easiest
114
+	 * way to fake it.
115
+	 */
116
+	list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list )
117
+		before++;
118
+	netdev_poll ( snpdev->netdev );
119
+	list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list )
120
+		after++;
121
+	arrived = ( after - before );
122
+
123
+	snpdev->rx_count_interrupts += arrived;
124
+	snpdev->rx_count_events += arrived;
125
+}
126
+
127
+/**
128
+ * Change SNP state from "stopped" to "started"
129
+ *
130
+ * @v snp		SNP interface
131
+ * @ret efirc		EFI status code
132
+ */
133
+static EFI_STATUS EFIAPI
134
+efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
135
+	struct efi_snp_device *snpdev =
136
+		container_of ( snp, struct efi_snp_device, snp );
137
+
138
+	DBGC2 ( snpdev, "SNPDEV %p START\n", snpdev );
139
+
140
+	snpdev->mode.State = EfiSimpleNetworkStarted;
141
+	return 0;
142
+}
143
+
144
+/**
145
+ * Change SNP state from "started" to "stopped"
146
+ *
147
+ * @v snp		SNP interface
148
+ * @ret efirc		EFI status code
149
+ */
150
+static EFI_STATUS EFIAPI
151
+efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
152
+	struct efi_snp_device *snpdev =
153
+		container_of ( snp, struct efi_snp_device, snp );
154
+
155
+	DBGC2 ( snpdev, "SNPDEV %p STOP\n", snpdev );
156
+
157
+	snpdev->mode.State = EfiSimpleNetworkStopped;
158
+	return 0;
159
+}
160
+
161
+/**
162
+ * Open the network device
163
+ *
164
+ * @v snp		SNP interface
165
+ * @v extra_rx_bufsize	Extra RX buffer size, in bytes
166
+ * @v extra_tx_bufsize	Extra TX buffer size, in bytes
167
+ * @ret efirc		EFI status code
168
+ */
169
+static EFI_STATUS EFIAPI
170
+efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
171
+		     UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
172
+	struct efi_snp_device *snpdev =
173
+		container_of ( snp, struct efi_snp_device, snp );
174
+	int rc;
175
+
176
+	DBGC2 ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
177
+		snpdev, extra_rx_bufsize, extra_tx_bufsize );
178
+
179
+	if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
180
+		DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
181
+		       snpdev, snpdev->netdev->name, strerror ( rc ) );
182
+		return RC_TO_EFIRC ( rc );
183
+	}
184
+
185
+	snpdev->mode.State = EfiSimpleNetworkInitialized;
186
+	return 0;
187
+}
188
+
189
+/**
190
+ * Reset the network device
191
+ *
192
+ * @v snp		SNP interface
193
+ * @v ext_verify	Extended verification required
194
+ * @ret efirc		EFI status code
195
+ */
196
+static EFI_STATUS EFIAPI
197
+efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
198
+	struct efi_snp_device *snpdev =
199
+		container_of ( snp, struct efi_snp_device, snp );
200
+	int rc;
201
+
202
+	DBGC2 ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
203
+		snpdev, ( ext_verify ? "with" : "without" ) );
204
+
205
+	netdev_close ( snpdev->netdev );
206
+	snpdev->mode.State = EfiSimpleNetworkStarted;
207
+
208
+	if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
209
+		DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
210
+		       snpdev, snpdev->netdev->name, strerror ( rc ) );
211
+		return RC_TO_EFIRC ( rc );
212
+	}
213
+
214
+	snpdev->mode.State = EfiSimpleNetworkInitialized;
215
+	return 0;
216
+}
217
+
218
+/**
219
+ * Shut down the network device
220
+ *
221
+ * @v snp		SNP interface
222
+ * @ret efirc		EFI status code
223
+ */
224
+static EFI_STATUS EFIAPI
225
+efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
226
+	struct efi_snp_device *snpdev =
227
+		container_of ( snp, struct efi_snp_device, snp );
228
+
229
+	DBGC2 ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
230
+
231
+	netdev_close ( snpdev->netdev );
232
+	snpdev->mode.State = EfiSimpleNetworkStarted;
233
+	return 0;
234
+}
235
+
236
+/**
237
+ * Manage receive filters
238
+ *
239
+ * @v snp		SNP interface
240
+ * @v enable		Receive filters to enable
241
+ * @v disable		Receive filters to disable
242
+ * @v mcast_reset	Reset multicast filters
243
+ * @v mcast_count	Number of multicast filters
244
+ * @v mcast		Multicast filters
245
+ * @ret efirc		EFI status code
246
+ */
247
+static EFI_STATUS EFIAPI
248
+efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
249
+			  UINT32 disable, BOOLEAN mcast_reset,
250
+			  UINTN mcast_count, EFI_MAC_ADDRESS *mcast ) {
251
+	struct efi_snp_device *snpdev =
252
+		container_of ( snp, struct efi_snp_device, snp );
253
+	unsigned int i;
254
+
255
+	DBGC2 ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08lx&~%08lx%s %ld mcast\n",
256
+		snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
257
+		mcast_count );
258
+	for ( i = 0 ; i < mcast_count ; i++ ) {
259
+		DBGC2_HDA ( snpdev, i, &mcast[i],
260
+			    snpdev->netdev->ll_protocol->ll_addr_len );
261
+	}
262
+
263
+	/* Lie through our teeth, otherwise MNP refuses to accept us */
264
+	return 0;
265
+}
266
+
267
+/**
268
+ * Set station address
269
+ *
270
+ * @v snp		SNP interface
271
+ * @v reset		Reset to permanent address
272
+ * @v new		New station address
273
+ * @ret efirc		EFI status code
274
+ */
275
+static EFI_STATUS EFIAPI
276
+efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
277
+			  EFI_MAC_ADDRESS *new ) {
278
+	struct efi_snp_device *snpdev =
279
+		container_of ( snp, struct efi_snp_device, snp );
280
+	struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
281
+
282
+	DBGC2 ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
283
+		( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
284
+
285
+	/* Set the MAC address */
286
+	if ( reset )
287
+		new = &snpdev->mode.PermanentAddress;
288
+	memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
289
+
290
+	/* MAC address changes take effect only on netdev_open() */
291
+	if ( snpdev->netdev->state & NETDEV_OPEN ) {
292
+		DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
293
+		       "devive open\n", snpdev );
294
+	}
295
+
296
+	return 0;
297
+}
298
+
299
+/**
300
+ * Get (or reset) statistics
301
+ *
302
+ * @v snp		SNP interface
303
+ * @v reset		Reset statistics
304
+ * @v stats_len		Size of statistics table
305
+ * @v stats		Statistics table
306
+ * @ret efirc		EFI status code
307
+ */
308
+static EFI_STATUS EFIAPI
309
+efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
310
+		     UINTN *stats_len, EFI_NETWORK_STATISTICS *stats ) {
311
+	struct efi_snp_device *snpdev =
312
+		container_of ( snp, struct efi_snp_device, snp );
313
+	EFI_NETWORK_STATISTICS stats_buf;
314
+
315
+	DBGC2 ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
316
+		( reset ? " reset" : "" ) );
317
+
318
+	/* Gather statistics */
319
+	memset ( &stats_buf, 0, sizeof ( stats_buf ) );
320
+	stats_buf.TxGoodFrames = snpdev->netdev->stats.tx_ok;
321
+	stats_buf.TxDroppedFrames = snpdev->netdev->stats.tx_err;
322
+	stats_buf.TxTotalFrames = ( snpdev->netdev->stats.tx_ok +
323
+				    snpdev->netdev->stats.tx_err );
324
+	stats_buf.RxGoodFrames = snpdev->netdev->stats.rx_ok;
325
+	stats_buf.RxDroppedFrames = snpdev->netdev->stats.rx_err;
326
+	stats_buf.RxTotalFrames = ( snpdev->netdev->stats.rx_ok +
327
+				    snpdev->netdev->stats.rx_err );
328
+	if ( *stats_len > sizeof ( stats_buf ) )
329
+		*stats_len = sizeof ( stats_buf );
330
+	if ( stats )
331
+		memcpy ( stats, &stats_buf, *stats_len );
332
+
333
+	/* Reset statistics if requested to do so */
334
+	if ( reset ) {
335
+		memset ( &snpdev->netdev->stats, 0,
336
+			 sizeof ( snpdev->netdev->stats ) );
337
+	}
338
+
339
+	return 0;
340
+}
341
+
342
+/**
343
+ * Convert multicast IP address to MAC address
344
+ *
345
+ * @v snp		SNP interface
346
+ * @v ipv6		Address is IPv6
347
+ * @v ip		IP address
348
+ * @v mac		MAC address
349
+ * @ret efirc		EFI status code
350
+ */
351
+static EFI_STATUS EFIAPI
352
+efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6,
353
+			  EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac ) {
354
+	struct efi_snp_device *snpdev =
355
+		container_of ( snp, struct efi_snp_device, snp );
356
+	struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
357
+	const char *ip_str;
358
+	int rc;
359
+
360
+	ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
361
+		   inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
362
+	DBGC2 ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
363
+
364
+	/* Try to hash the address */
365
+	if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
366
+					   ip, mac ) ) != 0 ) {
367
+		DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
368
+		       snpdev, ip_str, strerror ( rc ) );
369
+		return RC_TO_EFIRC ( rc );
370
+	}
371
+
372
+	return 0;
373
+}
374
+
375
+/**
376
+ * Read or write non-volatile storage
377
+ *
378
+ * @v snp		SNP interface
379
+ * @v read		Operation is a read
380
+ * @v offset		Starting offset within NVRAM
381
+ * @v len		Length of data buffer
382
+ * @v data		Data buffer
383
+ * @ret efirc		EFI status code
384
+ */
385
+static EFI_STATUS EFIAPI
386
+efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
387
+		 UINTN offset, UINTN len, VOID *data ) {
388
+	struct efi_snp_device *snpdev =
389
+		container_of ( snp, struct efi_snp_device, snp );
390
+
391
+	DBGC2 ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
392
+		( read ? "read" : "write" ), offset, len );
393
+	if ( ! read )
394
+		DBGC2_HDA ( snpdev, offset, data, len );
395
+
396
+	return EFI_UNSUPPORTED;
397
+}
398
+
399
+/**
400
+ * Read interrupt status and TX recycled buffer status
401
+ *
402
+ * @v snp		SNP interface
403
+ * @v interrupts	Interrupt status, or NULL
404
+ * @v txbufs		Recycled transmit buffer address, or NULL
405
+ * @ret efirc		EFI status code
406
+ */
407
+static EFI_STATUS EFIAPI
408
+efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
409
+		     UINT32 *interrupts, VOID **txbufs ) {
410
+	struct efi_snp_device *snpdev =
411
+		container_of ( snp, struct efi_snp_device, snp );
412
+
413
+	DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
414
+
415
+	/* Poll the network device */
416
+	efi_snp_poll ( snpdev );
417
+
418
+	/* Interrupt status.  In practice, this seems to be used only
419
+	 * to detect TX completions.
420
+	 */
421
+	if ( interrupts ) {
422
+		*interrupts = 0;
423
+		/* Report TX completions once queue is empty; this
424
+		 * avoids having to add hooks in the net device layer.
425
+		 */
426
+		if ( snpdev->tx_count_interrupts &&
427
+		     list_empty ( &snpdev->netdev->tx_queue ) ) {
428
+			*interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
429
+			snpdev->tx_count_interrupts--;
430
+		}
431
+		/* Report RX */
432
+		if ( snpdev->rx_count_interrupts ) {
433
+			*interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
434
+			snpdev->rx_count_interrupts--;
435
+		}
436
+		DBGC2 ( snpdev, " INTS:%02lx", *interrupts );
437
+	}
438
+
439
+	/* TX completions.  It would be possible to design a more
440
+	 * idiotic scheme for this, but it would be a challenge.
441
+	 * According to the UEFI header file, txbufs will be filled in
442
+	 * with a list of "recycled transmit buffers" (i.e. completed
443
+	 * TX buffers).  Observant readers may care to note that
444
+	 * *txbufs is a void pointer.  Precisely how a list of
445
+	 * completed transmit buffers is meant to be represented as an
446
+	 * array of voids is left as an exercise for the reader.
447
+	 *
448
+	 * The only users of this interface (MnpDxe/MnpIo.c and
449
+	 * PxeBcDxe/Bc.c within the EFI dev kit) both just poll until
450
+	 * seeing a non-NULL result return in txbufs.  This is valid
451
+	 * provided that they do not ever attempt to transmit more
452
+	 * than one packet concurrently (and that TX never times out).
453
+	 */
454
+	if ( txbufs ) {
455
+		if ( snpdev->tx_count_txbufs &&
456
+		     list_empty ( &snpdev->netdev->tx_queue ) ) {
457
+			*txbufs = "Which idiot designed this API?";
458
+			snpdev->tx_count_txbufs--;
459
+		} else {
460
+			*txbufs = NULL;
461
+		}
462
+		DBGC2 ( snpdev, " TX:%s", ( *txbufs ? "some" : "none" ) );
463
+	}
464
+
465
+	DBGC2 ( snpdev, "\n" );
466
+	return 0;
467
+}
468
+
469
+/**
470
+ * Start packet transmission
471
+ *
472
+ * @v snp		SNP interface
473
+ * @v ll_header_len	Link-layer header length, if to be filled in
474
+ * @v len		Length of data buffer
475
+ * @v data		Data buffer
476
+ * @v ll_src		Link-layer source address, if specified
477
+ * @v ll_dest		Link-layer destination address, if specified
478
+ * @v net_proto		Network-layer protocol (in host order)
479
+ * @ret efirc		EFI status code
480
+ */
481
+static EFI_STATUS EFIAPI
482
+efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
483
+		   UINTN ll_header_len, UINTN len, VOID *data,
484
+		   EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
485
+		   UINT16 *net_proto ) {
486
+	struct efi_snp_device *snpdev =
487
+		container_of ( snp, struct efi_snp_device, snp );
488
+	struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
489
+	struct io_buffer *iobuf;
490
+	int rc;
491
+	EFI_STATUS efirc;
492
+
493
+	DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data, len );
494
+	if ( ll_header_len ) {
495
+		if ( ll_src ) {
496
+			DBGC2 ( snpdev, " src %s",
497
+				ll_protocol->ntoa ( ll_src ) );
498
+		}
499
+		if ( ll_dest ) {
500
+			DBGC2 ( snpdev, " dest %s",
501
+				ll_protocol->ntoa ( ll_dest ) );
502
+		}
503
+		if ( net_proto ) {
504
+			DBGC2 ( snpdev, " proto %04x", *net_proto );
505
+		}
506
+	}
507
+	DBGC2 ( snpdev, "\n" );
508
+
509
+	/* Sanity checks */
510
+	if ( ll_header_len ) {
511
+		if ( ll_header_len != ll_protocol->ll_header_len ) {
512
+			DBGC ( snpdev, "SNPDEV %p TX invalid header length "
513
+			       "%ld\n", snpdev, ll_header_len );
514
+			efirc = EFI_INVALID_PARAMETER;
515
+			goto err_sanity;
516
+		}
517
+		if ( len < ll_header_len ) {
518
+			DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
519
+			       snpdev, len );
520
+			efirc = EFI_BUFFER_TOO_SMALL;
521
+			goto err_sanity;
522
+		}
523
+		if ( ! ll_dest ) {
524
+			DBGC ( snpdev, "SNPDEV %p TX missing destination "
525
+			       "address\n", snpdev );
526
+			efirc = EFI_INVALID_PARAMETER;
527
+			goto err_sanity;
528
+		}
529
+		if ( ! net_proto ) {
530
+			DBGC ( snpdev, "SNPDEV %p TX missing network "
531
+			       "protocol\n", snpdev );
532
+			efirc = EFI_INVALID_PARAMETER;
533
+			goto err_sanity;
534
+		}
535
+		if ( ! ll_src )
536
+			ll_src = &snpdev->mode.CurrentAddress;
537
+	}
538
+
539
+	/* Allocate buffer */
540
+	iobuf = alloc_iob ( len );
541
+	if ( ! iobuf ) {
542
+		DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
543
+		       "buffer\n", snpdev, len );
544
+		efirc = EFI_DEVICE_ERROR;
545
+		goto err_alloc_iob;
546
+	}
547
+	memcpy ( iob_put ( iobuf, len ), data, len );
548
+
549
+	/* Create link-layer header, if specified */
550
+	if ( ll_header_len ) {
551
+		iob_pull ( iobuf, ll_header_len );
552
+		if ( ( rc = ll_protocol->push ( iobuf, ll_dest, ll_src,
553
+						htons ( *net_proto ) )) != 0 ){
554
+			DBGC ( snpdev, "SNPDEV %p TX could not construct "
555
+			       "header: %s\n", snpdev, strerror ( rc ) );
556
+			efirc = RC_TO_EFIRC ( rc );
557
+			goto err_ll_push;
558
+		}
559
+	}
560
+
561
+	/* Transmit packet */
562
+	if ( ( rc = netdev_tx ( snpdev->netdev, iobuf ) ) != 0 ) {
563
+		DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
564
+		       snpdev, strerror ( rc ) );
565
+		iobuf = NULL;
566
+		efirc = RC_TO_EFIRC ( rc );
567
+		goto err_tx;
568
+	}
569
+
570
+	/* Record transmission as outstanding */
571
+	snpdev->tx_count_interrupts++;
572
+	snpdev->tx_count_txbufs++;
573
+
574
+	return 0;
575
+
576
+ err_tx:
577
+ err_ll_push:
578
+	free_iob ( iobuf );
579
+ err_alloc_iob:
580
+ err_sanity:
581
+	return efirc;
582
+}
583
+
584
+/**
585
+ * Receive packet
586
+ *
587
+ * @v snp		SNP interface
588
+ * @v ll_header_len	Link-layer header length, if to be filled in
589
+ * @v len		Length of data buffer
590
+ * @v data		Data buffer
591
+ * @v ll_src		Link-layer source address, if specified
592
+ * @v ll_dest		Link-layer destination address, if specified
593
+ * @v net_proto		Network-layer protocol (in host order)
594
+ * @ret efirc		EFI status code
595
+ */
596
+static EFI_STATUS EFIAPI
597
+efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
598
+		  UINTN *ll_header_len, UINTN *len, VOID *data,
599
+		  EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
600
+		  UINT16 *net_proto ) {
601
+	struct efi_snp_device *snpdev =
602
+		container_of ( snp, struct efi_snp_device, snp );
603
+	struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
604
+	struct io_buffer *iobuf;
605
+	const void *iob_ll_dest;
606
+	const void *iob_ll_src;
607
+	uint16_t iob_net_proto;
608
+	int rc;
609
+	EFI_STATUS efirc;
610
+
611
+	DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data, *len );
612
+
613
+	/* Poll the network device */
614
+	efi_snp_poll ( snpdev );
615
+
616
+	/* Dequeue a packet, if one is available */
617
+	iobuf = netdev_rx_dequeue ( snpdev->netdev );
618
+	if ( ! iobuf ) {
619
+		DBGC2 ( snpdev, "\n" );
620
+		efirc = EFI_NOT_READY;
621
+		goto out_no_packet;
622
+	}
623
+	DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
624
+
625
+	/* Return packet to caller */
626
+	memcpy ( data, iobuf->data, iob_len ( iobuf ) );
627
+	*len = iob_len ( iobuf );
628
+
629
+	/* Attempt to decode link-layer header */
630
+	if ( ( rc = ll_protocol->pull ( iobuf, &iob_ll_dest, &iob_ll_src,
631
+					&iob_net_proto ) ) != 0 ) {
632
+		DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
633
+		       snpdev, strerror ( rc ) );
634
+		efirc = RC_TO_EFIRC ( rc );
635
+		goto out_bad_ll_header;
636
+	}
637
+
638
+	/* Return link-layer header parameters to caller, if required */
639
+	if ( ll_header_len )
640
+		*ll_header_len = ll_protocol->ll_header_len;
641
+	if ( ll_src )
642
+		memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
643
+	if ( ll_dest )
644
+		memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
645
+	if ( net_proto )
646
+		*net_proto = ntohs ( iob_net_proto );
647
+
648
+	efirc = 0;
649
+
650
+ out_bad_ll_header:
651
+	free_iob ( iobuf );
652
+out_no_packet:
653
+	return efirc;
654
+}
655
+
656
+/**
657
+ * Poll event
658
+ *
659
+ * @v event		Event
660
+ * @v context		Event context
661
+ */
662
+static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event,
663
+					     VOID *context ) {
664
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
665
+	struct efi_snp_device *snpdev = context;
666
+
667
+	DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
668
+
669
+	/* Do nothing unless the net device is open */
670
+	if ( ! ( snpdev->netdev->state & NETDEV_OPEN ) )
671
+		return;
672
+
673
+	/* Poll the network device */
674
+	efi_snp_poll ( snpdev );
675
+
676
+	/* Fire event if packets have been received */
677
+	if ( snpdev->rx_count_events != 0 ) {
678
+		DBGC2 ( snpdev, "SNPDEV %p firing WaitForPacket event\n",
679
+			snpdev );
680
+		bs->SignalEvent ( event );
681
+		snpdev->rx_count_events--;
682
+	}
683
+}
684
+
685
+/** SNP interface */
686
+static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
687
+	.Revision	= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
688
+	.Start		= efi_snp_start,
689
+	.Stop		= efi_snp_stop,
690
+	.Initialize	= efi_snp_initialize,
691
+	.Reset		= efi_snp_reset,
692
+	.Shutdown	= efi_snp_shutdown,
693
+	.ReceiveFilters	= efi_snp_receive_filters,
694
+	.StationAddress	= efi_snp_station_address,
695
+	.Statistics	= efi_snp_statistics,
696
+	.MCastIpToMac	= efi_snp_mcast_ip_to_mac,
697
+	.NvData		= efi_snp_nvdata,
698
+	.GetStatus	= efi_snp_get_status,
699
+	.Transmit	= efi_snp_transmit,
700
+	.Receive	= efi_snp_receive,
701
+};
702
+
703
+/**
704
+ * Locate net device corresponding to EFI device
705
+ *
706
+ * @v driver		EFI driver
707
+ * @v device		EFI device
708
+ * @ret netdev		Net device, or NULL if not found
709
+ */
710
+static struct net_device *
711
+efi_snp_netdev ( EFI_DRIVER_BINDING_PROTOCOL *driver, EFI_HANDLE device ) {
712
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
713
+	union {
714
+		EFI_PCI_IO_PROTOCOL *pci;
715
+		void *interface;
716
+	} u;
717
+	UINTN pci_segment, pci_bus, pci_dev, pci_fn;
718
+	unsigned int pci_busdevfn;
719
+	struct net_device *netdev = NULL;
720
+	EFI_STATUS efirc;
721
+
722
+	/* See if device is a PCI device */
723
+	if ( ( efirc = bs->OpenProtocol ( device,
724
+					  &efi_pci_io_protocol_guid,
725
+					  &u.interface,
726
+					  driver->DriverBindingHandle,
727
+					  device,
728
+					  EFI_OPEN_PROTOCOL_BY_DRIVER )) !=0 ){
729
+		DBGCP ( driver, "SNPDRV %p device %p is not a PCI device\n",
730
+			driver, device );
731
+		goto out_no_pci_io;
732
+	}
733
+
734
+	/* Get PCI bus:dev.fn address */
735
+	if ( ( efirc = u.pci->GetLocation ( u.pci, &pci_segment, &pci_bus,
736
+					    &pci_dev, &pci_fn ) ) != 0 ) {
737
+		DBGC ( driver, "SNPDRV %p device %p could not get PCI "
738
+		       "location: %lx\n", driver, device, efirc );
739
+		goto out_no_pci_location;
740
+	}
741
+	DBGCP ( driver, "SNPDRV %p device %p is PCI %04lx:%02lx:%02lx.%lx\n",
742
+		driver, device, pci_segment, pci_bus, pci_dev, pci_fn );
743
+
744
+	/* Look up corresponding network device */
745
+	pci_busdevfn = PCI_BUSDEVFN ( pci_bus, PCI_DEVFN ( pci_dev, pci_fn ) );
746
+	if ( ( netdev = find_netdev_by_location ( BUS_TYPE_PCI,
747
+						  pci_busdevfn ) ) == NULL ) {
748
+		DBGCP ( driver, "SNPDRV %p device %p is not a gPXE network "
749
+			"device\n", driver, device );
750
+		goto out_no_netdev;
751
+	}
752
+	DBGC ( driver, "SNPDRV %p device %p is %s\n",
753
+	       driver, device, netdev->name );
754
+
755
+ out_no_netdev:
756
+ out_no_pci_location:
757
+	bs->CloseProtocol ( device, &efi_pci_io_protocol_guid,
758
+			    driver->DriverBindingHandle, device );
759
+ out_no_pci_io:
760
+	return netdev;
761
+}
762
+
763
+/**
764
+ * Locate SNP corresponding to EFI device
765
+ *
766
+ * @v driver		EFI driver
767
+ * @v device		EFI device
768
+ * @ret snp		EFI SNP, or NULL if not found
769
+ */
770
+static struct efi_snp_device *
771
+efi_snp_snpdev ( EFI_DRIVER_BINDING_PROTOCOL *driver, EFI_HANDLE device ) {
772
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
773
+	union {
774
+		EFI_SIMPLE_NETWORK_PROTOCOL *snp;
775
+		void *interface;
776
+	} u;
777
+	struct efi_snp_device *snpdev;
778
+	EFI_STATUS efirc;
779
+
780
+	if ( ( efirc = bs->OpenProtocol ( device,
781
+					  &efi_simple_network_protocol_guid,
782
+					  &u.interface,
783
+					  driver->DriverBindingHandle,
784
+					  device,
785
+					  EFI_OPEN_PROTOCOL_GET_PROTOCOL))!=0){
786
+		DBGC ( driver, "SNPDRV %p device %p could not locate SNP: "
787
+		       "%lx\n", driver, device, efirc );
788
+		return NULL;
789
+	}
790
+
791
+	snpdev =  container_of ( u.snp, struct efi_snp_device, snp );
792
+	DBGCP ( driver, "SNPDRV %p device %p is SNPDEV %p\n",
793
+		driver, device, snpdev );
794
+	return snpdev;
795
+}
796
+
797
+/**
798
+ * Check to see if driver supports a device
799
+ *
800
+ * @v driver		EFI driver
801
+ * @v device		EFI device
802
+ * @v child		Path to child device, if any
803
+ * @ret efirc		EFI status code
804
+ */
805
+static EFI_STATUS EFIAPI
806
+efi_snp_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver,
807
+			   EFI_HANDLE device,
808
+			   EFI_DEVICE_PATH_PROTOCOL *child ) {
809
+	struct net_device *netdev;
810
+
811
+	DBGCP ( driver, "SNPDRV %p DRIVER_SUPPORTED %p (%p)\n",
812
+		driver, device, child );
813
+
814
+	netdev = efi_snp_netdev ( driver, device );
815
+	return ( netdev ? 0 : EFI_UNSUPPORTED );
816
+}
817
+
818
+/**
819
+ * Attach driver to device
820
+ *
821
+ * @v driver		EFI driver
822
+ * @v device		EFI device
823
+ * @v child		Path to child device, if any
824
+ * @ret efirc		EFI status code
825
+ */
826
+static EFI_STATUS EFIAPI
827
+efi_snp_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver,
828
+		       EFI_HANDLE device,
829
+		       EFI_DEVICE_PATH_PROTOCOL *child ) {
830
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
831
+	struct efi_snp_device *snpdev;
832
+	struct net_device *netdev;
833
+	EFI_STATUS efirc;
834
+
835
+	DBGCP ( driver, "SNPDRV %p DRIVER_START %p (%p)\n",
836
+		driver, device, child );
837
+
838
+	/* Allocate the SNP device */
839
+	snpdev = zalloc ( sizeof ( *snpdev ) );
840
+	if ( ! snpdev ) {
841
+		efirc = EFI_OUT_OF_RESOURCES;
842
+		goto err_alloc_snp;
843
+	}
844
+
845
+	/* Identify the net device */
846
+	netdev = efi_snp_netdev ( driver, device );
847
+	if ( ! netdev ) {
848
+		DBGC ( snpdev, "SNPDEV %p cannot find netdev for device %p\n",
849
+		       snpdev, device );
850
+		efirc = EFI_UNSUPPORTED;
851
+		goto err_no_netdev;
852
+	}
853
+	snpdev->netdev = netdev_get ( netdev );
854
+
855
+	/* Sanity check */
856
+	if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
857
+		DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
858
+		       "length %zd for %s\n", snpdev,
859
+		       netdev->ll_protocol->ll_addr_len, netdev->name );
860
+		efirc = EFI_INVALID_PARAMETER;
861
+		goto err_ll_addr_len;
862
+	}
863
+
864
+	/* Populate the SNP structure */
865
+	memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
866
+	snpdev->snp.Mode = &snpdev->mode;
867
+	if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
868
+					 efi_snp_wait_for_packet, snpdev,
869
+					 &snpdev->snp.WaitForPacket ) ) != 0 ){
870
+		DBGC ( snpdev, "SNPDEV %p could not create event: %lx\n",
871
+		       snpdev, efirc );
872
+		goto err_create_event;
873
+	}
874
+
875
+	/* Populate the SNP mode structure */
876
+	snpdev->mode.State = EfiSimpleNetworkStopped;
877
+	efi_snp_set_mode ( snpdev );
878
+
879
+	/* Install the SNP */
880
+	if ( ( efirc = bs->InstallProtocolInterface ( &device,
881
+				&efi_simple_network_protocol_guid,
882
+				EFI_NATIVE_INTERFACE, &snpdev->snp ) ) != 0 ) {
883
+		DBGC ( snpdev, "SNPDEV %p could not install protocol: %lx\n",
884
+		       snpdev, efirc );
885
+		goto err_install_protocol_interface;
886
+	}
887
+
888
+	DBGC ( snpdev, "SNPDEV %p installed for %s on device %p\n",
889
+	       snpdev, netdev->name, device );
890
+	return 0;
891
+
892
+	bs->UninstallProtocolInterface ( device,
893
+					 &efi_simple_network_protocol_guid,
894
+					 &snpdev->snp );
895
+ err_install_protocol_interface:
896
+	bs->CloseEvent ( snpdev->snp.WaitForPacket );
897
+ err_create_event:
898
+ err_ll_addr_len:
899
+	netdev_put ( netdev );
900
+ err_no_netdev:
901
+	free ( snpdev );
902
+ err_alloc_snp:
903
+	return efirc;
904
+}
905
+
906
+/**
907
+ * Detach driver from device
908
+ *
909
+ * @v driver		EFI driver
910
+ * @v device		EFI device
911
+ * @v num_children	Number of child devices
912
+ * @v children		List of child devices
913
+ * @ret efirc		EFI status code
914
+ */
915
+static EFI_STATUS EFIAPI
916
+efi_snp_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver,
917
+		      EFI_HANDLE device,
918
+		      UINTN num_children,
919
+		      EFI_HANDLE *children ) {
920
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
921
+	struct efi_snp_device *snpdev;
922
+
923
+	DBGCP ( driver, "SNPDRV %p DRIVER_STOP %p (%ld %p)\n",
924
+		driver, device, num_children, children );
925
+
926
+	/* Locate SNP device */
927
+	snpdev = efi_snp_snpdev ( driver, device );
928
+	if ( ! snpdev ) {
929
+		DBGC ( driver, "SNPDRV %p device %p could not find SNPDEV\n",
930
+		       driver, device );
931
+		return EFI_DEVICE_ERROR;
932
+	}
933
+
934
+	/* Uninstall the SNP */
935
+	bs->UninstallProtocolInterface ( device,
936
+					 &efi_simple_network_protocol_guid,
937
+					 &snpdev->snp );
938
+	bs->CloseEvent ( snpdev->snp.WaitForPacket );
939
+	netdev_put ( snpdev->netdev );
940
+	free ( snpdev );
941
+	return 0;
942
+}
943
+
944
+/** EFI SNP driver binding */
945
+static EFI_DRIVER_BINDING_PROTOCOL efi_snp_binding = {
946
+	efi_snp_driver_supported,
947
+	efi_snp_driver_start,
948
+	efi_snp_driver_stop,
949
+	0x10,
950
+	NULL,
951
+	NULL
952
+};
953
+
954
+/**
955
+ * Install EFI SNP driver
956
+ *
957
+ * @ret rc		Return status code
958
+ */
959
+int efi_snp_install ( void ) {
960
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
961
+	EFI_DRIVER_BINDING_PROTOCOL *driver = &efi_snp_binding;
962
+	EFI_STATUS efirc;
963
+
964
+	driver->ImageHandle = efi_image_handle;
965
+	if ( ( efirc = bs->InstallProtocolInterface (
966
+					&driver->DriverBindingHandle,
967
+					&efi_driver_binding_protocol_guid,
968
+					EFI_NATIVE_INTERFACE,
969
+					driver ) ) != 0 ) {
970
+		DBGC ( driver, "SNPDRV %p could not install driver binding: "
971
+		       "%lx\n", driver, efirc );
972
+		return EFIRC_TO_RC ( efirc );
973
+	}
974
+
975
+	DBGC ( driver, "SNPDRV %p driver binding installed as %p\n",
976
+	       driver, driver->DriverBindingHandle );
977
+	return 0;
978
+}

Loading…
Cancel
Save