iPXE
efi_snp.c File Reference
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/netdevice.h>
#include <ipxe/vlan.h>
#include <ipxe/iobuf.h>
#include <ipxe/in.h>
#include <ipxe/version.h>
#include <ipxe/console.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/efi_watchdog.h>
#include <ipxe/efi/efi_null.h>
#include <ipxe/efi/efi_snp.h>
#include <usr/autoboot.h>
#include <config/general.h>

Go to the source code of this file.

Data Structures

union  PXE_CPB_ANY
 Union type for command parameter blocks. More...
union  PXE_DB_ANY
 Union type for data blocks. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 FILE_SECBOOT (PERMITTED)
static LIST_HEAD (efi_snp_devices)
 List of SNP devices.
static void efi_snp_set_state (struct efi_snp_device *snpdev)
 Set EFI SNP mode state.
static void efi_snp_set_mode (struct efi_snp_device *snpdev)
 Set EFI SNP mode based on iPXE net device parameters.
static void efi_snp_flush (struct efi_snp_device *snpdev)
 Flush transmit ring and receive queue.
static void efi_snp_poll (struct efi_snp_device *snpdev)
 Poll net device and count received packets.
static EFI_STATUS EFIAPI efi_snp_start (EFI_SIMPLE_NETWORK_PROTOCOL *snp)
 Change SNP state from "stopped" to "started".
static EFI_STATUS EFIAPI efi_snp_stop (EFI_SIMPLE_NETWORK_PROTOCOL *snp)
 Change SNP state from "started" to "stopped".
static EFI_STATUS EFIAPI efi_snp_initialize (EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINTN extra_rx_bufsize, UINTN extra_tx_bufsize)
 Open the network device.
static EFI_STATUS EFIAPI efi_snp_reset (EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify)
 Reset the network device.
static EFI_STATUS EFIAPI efi_snp_shutdown (EFI_SIMPLE_NETWORK_PROTOCOL *snp)
 Shut down the network device.
static EFI_STATUS EFIAPI efi_snp_receive_filters (EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable, UINT32 disable, BOOLEAN mcast_reset, UINTN mcast_count, EFI_MAC_ADDRESS *mcast)
 Manage receive filters.
static EFI_STATUS EFIAPI efi_snp_station_address (EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset, EFI_MAC_ADDRESS *new)
 Set station address.
static EFI_STATUS EFIAPI efi_snp_statistics (EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset, UINTN *stats_len, EFI_NETWORK_STATISTICS *stats)
 Get (or reset) statistics.
static EFI_STATUS EFIAPI efi_snp_mcast_ip_to_mac (EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6, EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac)
 Convert multicast IP address to MAC address.
static EFI_STATUS EFIAPI efi_snp_nvdata (EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read, UINTN offset, UINTN len, VOID *data)
 Read or write non-volatile storage.
static EFI_STATUS EFIAPI efi_snp_get_status (EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 *interrupts, VOID **txbuf)
 Read interrupt status and TX recycled buffer status.
static EFI_STATUS EFIAPI efi_snp_transmit (EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINTN ll_header_len, UINTN len, VOID *data, EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest, UINT16 *net_proto)
 Start packet transmission.
static EFI_STATUS EFIAPI efi_snp_receive (EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINTN *ll_header_len, UINTN *len, VOID *data, EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest, UINT16 *net_proto)
 Receive packet.
static VOID EFIAPI efi_snp_wait_for_packet (EFI_EVENT event __unused, VOID *context)
 Poll event.
static uint8_t efi_undi_checksum (void *data, size_t len)
 Calculate UNDI byte checksum.
static unsigned int efi_undi_ifnum (struct efi_snp_device *snpdev)
 Get UNDI SNP device interface number.
static struct efi_snp_deviceefi_undi_snpdev (unsigned int ifnum)
 Identify UNDI SNP device.
static PXE_STATCODE efi_undi_statcode (EFI_STATUS efirc)
 Convert EFI status code to UNDI status code.
static EFI_STATUS efi_undi_get_state (struct efi_snp_device *snpdev, PXE_CDB *cdb)
 Get state.
static EFI_STATUS efi_undi_start (struct efi_snp_device *snpdev)
 Start.
static EFI_STATUS efi_undi_stop (struct efi_snp_device *snpdev)
 Stop.
static EFI_STATUS efi_undi_get_init_info (struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_DB_GET_INIT_INFO *db)
 Get initialisation information.
static EFI_STATUS efi_undi_initialize (struct efi_snp_device *snpdev, PXE_CDB *cdb)
 Initialise.
static EFI_STATUS efi_undi_reset (struct efi_snp_device *snpdev)
 Reset.
static EFI_STATUS efi_undi_shutdown (struct efi_snp_device *snpdev)
 Shutdown.
static EFI_STATUS efi_undi_receive_filters (struct efi_snp_device *snpdev, PXE_CDB *cdb)
 Get/set receive filters.
static EFI_STATUS efi_undi_station_address (struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_CPB_STATION_ADDRESS *cpb, PXE_DB_STATION_ADDRESS *db)
 Get/set station address.
static EFI_STATUS efi_undi_get_status (struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_DB_GET_STATUS *db)
 Get interrupt status.
static EFI_STATUS efi_undi_fill_header (struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_CPB_ANY *cpb)
 Fill header.
static EFI_STATUS efi_undi_transmit (struct efi_snp_device *snpdev, PXE_CPB_TRANSMIT *cpb)
 Transmit.
static EFI_STATUS efi_undi_receive (struct efi_snp_device *snpdev, PXE_CPB_RECEIVE *cpb, PXE_DB_RECEIVE *db)
 Receive.
static EFIAPI VOID efi_undi_issue (UINT64 cdb_phys)
 UNDI entry point.
static EFI_STATUS EFIAPI efi_vlan_set (EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 tag, UINT8 priority)
 Create or modify VLAN device.
static EFI_STATUS EFIAPI efi_vlan_find (EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 *filter, UINT16 *count, EFI_VLAN_FIND_DATA **entries)
 Find VLAN device(s)
static EFI_STATUS EFIAPI efi_vlan_remove (EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 tag)
 Remove VLAN device.
static EFI_STATUS EFIAPI efi_snp_get_driver_name (EFI_COMPONENT_NAME2_PROTOCOL *name2, CHAR8 *language __unused, CHAR16 **driver_name)
 Look up driver name.
static EFI_STATUS EFIAPI efi_snp_get_controller_name (EFI_COMPONENT_NAME2_PROTOCOL *name2, EFI_HANDLE device __unused, EFI_HANDLE child __unused, CHAR8 *language __unused, CHAR16 **controller_name)
 Look up controller name.
static EFI_STATUS EFIAPI efi_snp_load_file (EFI_LOAD_FILE_PROTOCOL *load_file, EFI_DEVICE_PATH_PROTOCOL *path __unused, BOOLEAN booting, UINTN *len __unused, VOID *data __unused)
 Load file.
static struct efi_snp_deviceefi_snp_demux (struct net_device *netdev)
 Locate SNP device corresponding to network device.
static int efi_snp_probe (struct net_device *netdev, void *priv __unused)
 Create SNP device.
static void efi_snp_notify (struct net_device *netdev, void *priv __unused)
 Handle SNP device or link state change.
static void efi_snp_remove (struct net_device *netdev, void *priv __unused)
 Destroy SNP device.
struct efi_snp_devicefind_snpdev (EFI_HANDLE handle)
 Find SNP device by EFI device handle.
struct efi_snp_devicelast_opened_snpdev (void)
 Get most recently opened SNP device.
void efi_snp_add_claim (int delta)
 Add to SNP claimed/released count.

Variables

static int efi_snp_claimed
 Network devices are currently claimed for use by iPXE.
static struct efi_saved_tpl efi_snp_saved_tpl
 TPL prior to network devices being claimed.
static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp
 SNP interface.
static PXE_SW_UNDI efi_snp_undi
 UNDI interface.
static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii
 Network Identification Interface (NII)
static EFI_VLAN_CONFIG_PROTOCOL efi_vlan
 VLAN configuration protocol.
static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol
 Load file protocol.
struct net_driver efi_snp_driver __net_driver
 SNP driver.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ LIST_HEAD()

LIST_HEAD ( efi_snp_devices )
static

List of SNP devices.

◆ efi_snp_set_state()

void efi_snp_set_state ( struct efi_snp_device * snpdev)
static

Set EFI SNP mode state.

Parameters
snpSNP interface

Definition at line 92 of file efi_snp.c.

92 {
93 struct net_device *netdev = snpdev->netdev;
95
96 /* Calculate state */
97 if ( ! snpdev->started ) {
98 /* Start() method not called; report as Stopped */
100 } else if ( ! netdev_is_open ( netdev ) ) {
101 /* Network device not opened; report as Started */
103 } else if ( efi_snp_claimed ) {
104 /* Network device opened but claimed for use by iPXE; report
105 * as Started to inhibit receive polling.
106 */
108 } else {
109 /* Network device opened and available for use via SNP; report
110 * as Initialized.
111 */
113 }
114}
@ EfiSimpleNetworkInitialized
@ EfiSimpleNetworkStarted
@ EfiSimpleNetworkStopped
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition efi_snp.c:49
uint16_t mode
Acceleration mode.
Definition ena.h:15
static struct net_device * netdev
Definition gdbudp.c:53
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662
int started
Started flag.
Definition efi_snp.h:43
struct net_device * netdev
The underlying iPXE network device.
Definition efi_snp.h:33
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition efi_snp.h:41
A network device.
Definition netdevice.h:353

References efi_snp_claimed, EfiSimpleNetworkInitialized, EfiSimpleNetworkStarted, EfiSimpleNetworkStopped, efi_snp_device::mode, mode, efi_snp_device::netdev, netdev, netdev_is_open(), and efi_snp_device::started.

Referenced by efi_snp_add_claim(), efi_snp_initialize(), efi_snp_notify(), efi_snp_reset(), efi_snp_shutdown(), efi_snp_start(), and efi_snp_stop().

◆ efi_snp_set_mode()

void efi_snp_set_mode ( struct efi_snp_device * snpdev)
static

Set EFI SNP mode based on iPXE net device parameters.

Parameters
snpSNP interface

Definition at line 121 of file efi_snp.c.

121 {
122 struct net_device *netdev = snpdev->netdev;
124 struct ll_protocol *ll_protocol = netdev->ll_protocol;
125 unsigned int ll_addr_len = ll_protocol->ll_addr_len;
126
127 mode->HwAddressSize = ll_addr_len;
128 mode->MediaHeaderSize = ll_protocol->ll_header_len;
129 mode->MaxPacketSize = netdev->mtu;
130 mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
133 assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
134 memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
135 memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
136 ll_protocol->init_addr ( netdev->hw_addr, &mode->PermanentAddress );
137 mode->IfType = ntohs ( ll_protocol->ll_proto );
138 mode->MacAddressChangeable = TRUE;
139 mode->MediaPresentSupported = TRUE;
140 mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
141}
#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define ntohs(value)
Definition byteswap.h:137
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition netdevice.h:640
A link-layer protocol.
Definition netdevice.h:115
void(* init_addr)(const void *hw_addr, void *ll_addr)
Initialise link-layer address.
Definition netdevice.h:151
uint8_t ll_addr_len
Link-layer address length.
Definition netdevice.h:199
uint8_t ll_header_len
Link-layer header length.
Definition netdevice.h:201
uint16_t ll_proto
Link-layer protocol.
Definition netdevice.h:195
#define TRUE
Definition tlan.h:46
#define FALSE
Definition tlan.h:45

References assert, EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST, EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST, EFI_SIMPLE_NETWORK_RECEIVE_UNICAST, FALSE, ll_protocol::init_addr, ll_protocol::ll_addr_len, ll_protocol::ll_header_len, ll_protocol::ll_proto, memcpy(), efi_snp_device::mode, mode, efi_snp_device::netdev, netdev, netdev_link_ok(), ntohs, and TRUE.

Referenced by efi_snp_probe().

◆ efi_snp_flush()

void efi_snp_flush ( struct efi_snp_device * snpdev)
static

Flush transmit ring and receive queue.

Parameters
snpdevSNP device

Definition at line 148 of file efi_snp.c.

148 {
149 struct io_buffer *iobuf;
150 struct io_buffer *tmp;
151
152 /* Reset transmit completion ring */
153 snpdev->tx_prod = 0;
154 snpdev->tx_cons = 0;
155
156 /* Discard any queued receive buffers */
157 list_for_each_entry_safe ( iobuf, tmp, &snpdev->rx, list ) {
158 list_del ( &iobuf->list );
159 free_iob ( iobuf );
160 }
161}
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
struct list_head rx
Receive queue.
Definition efi_snp.h:53
unsigned int tx_prod
Transmit completion ring producer counter.
Definition efi_snp.h:49
unsigned int tx_cons
Transmit completion ring consumer counter.
Definition efi_snp.h:51
A persistent I/O buffer.
Definition iobuf.h:38
struct list_head list
List of which this buffer is a member.
Definition iobuf.h:45

References free_iob(), io_buffer::list, list_del, list_for_each_entry_safe, efi_snp_device::rx, tmp, efi_snp_device::tx_cons, and efi_snp_device::tx_prod.

Referenced by efi_snp_reset(), and efi_snp_shutdown().

◆ efi_snp_poll()

void efi_snp_poll ( struct efi_snp_device * snpdev)
static

Poll net device and count received packets.

Parameters
snpdevSNP device

Definition at line 168 of file efi_snp.c.

168 {
169 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
170 struct io_buffer *iobuf;
171
172 /* Poll network device */
173 netdev_poll ( snpdev->netdev );
174
175 /* Retrieve any received packets */
176 while ( ( iobuf = netdev_rx_dequeue ( snpdev->netdev ) ) ) {
177 list_add_tail ( &iobuf->list, &snpdev->rx );
179 bs->SignalEvent ( snpdev->snp.WaitForPacket );
180 }
181}
#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
EFI_SYSTEM_TABLE * efi_systab
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
struct io_buffer * netdev_rx_dequeue(struct net_device *netdev)
Remove packet from device's receive queue.
Definition netdevice.c:638
void netdev_poll(struct net_device *netdev)
Poll for completed and received packets on network device.
Definition netdevice.c:613
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_SIGNAL_EVENT SignalEvent
Definition UefiSpec.h:1958
EFI_EVENT WaitForPacket
Event used with WaitForEvent() to wait for a packet to be received.
unsigned int interrupts
Pending interrupt status.
Definition efi_snp.h:45
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition efi_snp.h:39

References EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT, efi_systab, efi_snp_device::interrupts, io_buffer::list, list_add_tail, efi_snp_device::netdev, netdev_poll(), netdev_rx_dequeue(), efi_snp_device::rx, EFI_BOOT_SERVICES::SignalEvent, efi_snp_device::snp, and _EFI_SIMPLE_NETWORK_PROTOCOL::WaitForPacket.

Referenced by efi_snp_get_status(), efi_snp_receive(), and efi_snp_wait_for_packet().

◆ efi_snp_start()

EFI_STATUS EFIAPI efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL * snp)
static

Change SNP state from "stopped" to "started".

Parameters
snpSNP interface
Return values
efircEFI status code

Definition at line 190 of file efi_snp.c.

190 {
191 struct efi_snp_device *snpdev =
192 container_of ( snp, struct efi_snp_device, snp );
193
194 DBGC ( snpdev, "SNPDEV %p START\n", snpdev );
195
196 /* Allow start even if net device is currently claimed by iPXE */
197 if ( efi_snp_claimed ) {
198 DBGC ( snpdev, "SNPDEV %p allowing start while claimed\n",
199 snpdev );
200 }
201
202 snpdev->started = 1;
203 efi_snp_set_state ( snpdev );
204 return 0;
205}
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition efi_snp.c:92
#define DBGC(...)
Definition compiler.h:505
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An SNP device.
Definition efi_snp.h:29

References container_of, DBGC, efi_snp_claimed, efi_snp_set_state(), efi_snp_device::snp, and efi_snp_device::started.

Referenced by efi_undi_start().

◆ efi_snp_stop()

EFI_STATUS EFIAPI efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL * snp)
static

Change SNP state from "started" to "stopped".

Parameters
snpSNP interface
Return values
efircEFI status code

Definition at line 214 of file efi_snp.c.

214 {
215 struct efi_snp_device *snpdev =
216 container_of ( snp, struct efi_snp_device, snp );
217
218 DBGC ( snpdev, "SNPDEV %p STOP\n", snpdev );
219
220 /* Fail if net device is currently claimed for use by iPXE */
221 if ( efi_snp_claimed )
222 return EFI_NOT_READY;
223
224 snpdev->started = 0;
225 efi_snp_set_state ( snpdev );
226
227 return 0;
228}
#define EFI_NOT_READY
Enumeration of EFI_STATUS.

References container_of, DBGC, EFI_NOT_READY, efi_snp_claimed, efi_snp_set_state(), efi_snp_device::snp, and efi_snp_device::started.

Referenced by efi_undi_stop().

◆ efi_snp_initialize()

EFI_STATUS EFIAPI efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
UINTN extra_rx_bufsize,
UINTN extra_tx_bufsize )
static

Open the network device.

Parameters
snpSNP interface
extra_rx_bufsizeExtra RX buffer size, in bytes
extra_tx_bufsizeExtra TX buffer size, in bytes
Return values
efircEFI status code

Definition at line 239 of file efi_snp.c.

240 {
241 struct efi_snp_device *snpdev =
242 container_of ( snp, struct efi_snp_device, snp );
243 struct efi_saved_tpl tpl;
244 int rc;
245
246 DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
247 snpdev, ( ( unsigned long ) extra_rx_bufsize ),
248 ( ( unsigned long ) extra_tx_bufsize ) );
249
250 /* Do nothing if net device is currently claimed for use by
251 * iPXE. Do not return an error, because this will cause
252 * MnpDxe et al to fail to install the relevant child handles
253 * and to leave behind a partially initialised device handle
254 * that can cause a later system crash.
255 */
256 if ( efi_snp_claimed ) {
257 DBGC ( snpdev, "SNPDEV %p ignoring initialization while "
258 "claimed\n", snpdev );
259 return 0;
260 }
261
262 /* Raise TPL */
263 efi_raise_tpl ( &tpl );
264
265 /* Open network device */
266 if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
267 DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
268 snpdev, snpdev->netdev->name, strerror ( rc ) );
269 goto err_open;
270 }
271 efi_snp_set_state ( snpdev );
272
273 err_open:
274 efi_restore_tpl ( &tpl );
275 return EFIRC ( rc );
276}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition efi_init.c:383
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition efi_init.c:399
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition efi.h:167
int netdev_open(struct net_device *netdev)
Open network device.
Definition netdevice.c:862
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
An EFI saved task priority level.
Definition efi.h:80
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition netdevice.h:363

References container_of, DBGC, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_set_state(), EFIRC, net_device::name, efi_snp_device::netdev, netdev_open(), rc, efi_snp_device::snp, and strerror().

Referenced by efi_undi_initialize().

◆ efi_snp_reset()

EFI_STATUS EFIAPI efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
BOOLEAN ext_verify )
static

Reset the network device.

Parameters
snpSNP interface
ext_verifyExtended verification required
Return values
efircEFI status code

Definition at line 286 of file efi_snp.c.

286 {
287 struct efi_snp_device *snpdev =
288 container_of ( snp, struct efi_snp_device, snp );
289 struct efi_saved_tpl tpl;
290 int rc;
291
292 DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
293 snpdev, ( ext_verify ? "with" : "without" ) );
294
295 /* Fail if net device is currently claimed for use by iPXE */
296 if ( efi_snp_claimed ) {
297 rc = -EAGAIN;
298 goto err_claimed;
299 }
300
301 /* Raise TPL */
302 efi_raise_tpl ( &tpl );
303
304 /* Close network device */
305 netdev_close ( snpdev->netdev );
306 efi_snp_set_state ( snpdev );
307 efi_snp_flush ( snpdev );
308
309 /* Reopen network device */
310 if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
311 DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
312 snpdev, snpdev->netdev->name, strerror ( rc ) );
313 goto err_open;
314 }
315 efi_snp_set_state ( snpdev );
316
317 err_open:
318 efi_restore_tpl ( &tpl );
319 err_claimed:
320 return EFIRC ( rc );
321}
static void efi_snp_flush(struct efi_snp_device *snpdev)
Flush transmit ring and receive queue.
Definition efi_snp.c:148
#define EAGAIN
Resource temporarily unavailable.
Definition errno.h:319
void netdev_close(struct net_device *netdev)
Close network device.
Definition netdevice.c:896

References container_of, DBGC, EAGAIN, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_flush(), efi_snp_set_state(), EFIRC, net_device::name, efi_snp_device::netdev, netdev_close(), netdev_open(), rc, efi_snp_device::snp, and strerror().

Referenced by efi_undi_reset().

◆ efi_snp_shutdown()

EFI_STATUS EFIAPI efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL * snp)
static

Shut down the network device.

Parameters
snpSNP interface
Return values
efircEFI status code

Definition at line 330 of file efi_snp.c.

330 {
331 struct efi_snp_device *snpdev =
332 container_of ( snp, struct efi_snp_device, snp );
333 struct efi_saved_tpl tpl;
334
335 DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
336
337 /* Fail if net device is currently claimed for use by iPXE */
338 if ( efi_snp_claimed )
339 return EFI_NOT_READY;
340
341 /* Raise TPL */
342 efi_raise_tpl ( &tpl );
343
344 /* Close network device */
345 netdev_close ( snpdev->netdev );
346 efi_snp_set_state ( snpdev );
347 efi_snp_flush ( snpdev );
348
349 /* Restore TPL */
350 efi_restore_tpl ( &tpl );
351
352 return 0;
353}

References container_of, DBGC, EFI_NOT_READY, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_flush(), efi_snp_set_state(), efi_snp_device::netdev, netdev_close(), and efi_snp_device::snp.

Referenced by efi_undi_shutdown().

◆ efi_snp_receive_filters()

EFI_STATUS EFIAPI efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
UINT32 enable,
UINT32 disable,
BOOLEAN mcast_reset,
UINTN mcast_count,
EFI_MAC_ADDRESS * mcast )
static

Manage receive filters.

Parameters
snpSNP interface
enableReceive filters to enable
disableReceive filters to disable
mcast_resetReset multicast filters
mcast_countNumber of multicast filters
mcastMulticast filters
Return values
efircEFI status code

Definition at line 367 of file efi_snp.c.

369 {
370 struct efi_snp_device *snpdev =
371 container_of ( snp, struct efi_snp_device, snp );
372 unsigned int i;
373
374 DBGC ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
375 snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
376 ( ( unsigned long ) mcast_count ) );
377 for ( i = 0 ; i < mcast_count ; i++ ) {
378 DBGC2_HDA ( snpdev, i, &mcast[i],
379 snpdev->netdev->ll_protocol->ll_addr_len );
380 }
381
382 /* Lie through our teeth, otherwise MNP refuses to accept us.
383 *
384 * Return success even if the SNP device is currently claimed
385 * for use by iPXE, since otherwise Windows Deployment
386 * Services refuses to attempt to receive further packets via
387 * our EFI PXE Base Code protocol.
388 */
389 return 0;
390}
#define DBGC2_HDA(...)
Definition compiler.h:523
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition netdevice.h:373

References container_of, DBGC, DBGC2_HDA, ll_protocol::ll_addr_len, net_device::ll_protocol, efi_snp_device::netdev, and efi_snp_device::snp.

◆ efi_snp_station_address()

EFI_STATUS EFIAPI efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
BOOLEAN reset,
EFI_MAC_ADDRESS * new )
static

Set station address.

Parameters
snpSNP interface
resetReset to permanent address
newNew station address
Return values
efircEFI status code

Definition at line 401 of file efi_snp.c.

402 {
403 struct efi_snp_device *snpdev =
404 container_of ( snp, struct efi_snp_device, snp );
405 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
406
407 DBGC ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
408 ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
409
410 /* Fail if net device is currently claimed for use by iPXE */
411 if ( efi_snp_claimed )
412 return EFI_NOT_READY;
413
414 /* Set the MAC address */
415 if ( reset )
416 new = &snpdev->mode.PermanentAddress;
417 memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
418
419 /* MAC address changes take effect only on netdev_open() */
420 if ( netdev_is_open ( snpdev->netdev ) ) {
421 DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
422 "device open\n", snpdev );
423 }
424
425 return 0;
426}
EFI_MAC_ADDRESS PermanentAddress
The permanent HW MAC address for the network interface.
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition netdevice.h:164
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition netdevice.h:388

References container_of, DBGC, EFI_NOT_READY, efi_snp_claimed, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_protocol, memcpy(), efi_snp_device::mode, efi_snp_device::netdev, netdev_is_open(), ll_protocol::ntoa, EFI_SIMPLE_NETWORK_MODE::PermanentAddress, and efi_snp_device::snp.

Referenced by efi_undi_station_address().

◆ efi_snp_statistics()

EFI_STATUS EFIAPI efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
BOOLEAN reset,
UINTN * stats_len,
EFI_NETWORK_STATISTICS * stats )
static

Get (or reset) statistics.

Parameters
snpSNP interface
resetReset statistics
stats_lenSize of statistics table
statsStatistics table
Return values
efircEFI status code

Definition at line 438 of file efi_snp.c.

439 {
440 struct efi_snp_device *snpdev =
441 container_of ( snp, struct efi_snp_device, snp );
442 EFI_NETWORK_STATISTICS stats_buf;
443
444 DBGC ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
445 ( reset ? " reset" : "" ) );
446
447 /* Fail if net device is currently claimed for use by iPXE */
448 if ( efi_snp_claimed )
449 return EFI_NOT_READY;
450
451 /* Gather statistics */
452 memset ( &stats_buf, 0, sizeof ( stats_buf ) );
453 stats_buf.TxGoodFrames = snpdev->netdev->tx_stats.good;
454 stats_buf.TxDroppedFrames = snpdev->netdev->tx_stats.bad;
455 stats_buf.TxTotalFrames = ( snpdev->netdev->tx_stats.good +
456 snpdev->netdev->tx_stats.bad );
457 stats_buf.RxGoodFrames = snpdev->netdev->rx_stats.good;
458 stats_buf.RxDroppedFrames = snpdev->netdev->rx_stats.bad;
459 stats_buf.RxTotalFrames = ( snpdev->netdev->rx_stats.good +
460 snpdev->netdev->rx_stats.bad );
461 if ( *stats_len > sizeof ( stats_buf ) )
462 *stats_len = sizeof ( stats_buf );
463 if ( stats )
464 memcpy ( stats, &stats_buf, *stats_len );
465
466 /* Reset statistics if requested to do so */
467 if ( reset ) {
468 memset ( &snpdev->netdev->tx_stats, 0,
469 sizeof ( snpdev->netdev->tx_stats ) );
470 memset ( &snpdev->netdev->rx_stats, 0,
471 sizeof ( snpdev->netdev->rx_stats ) );
472 }
473
474 return 0;
475}
void * memset(void *dest, int character, size_t len) __nonnull
Simple Network Protocol data structures.
UINT64 RxTotalFrames
Total number of frames received.
UINT64 RxDroppedFrames
Valid frames that were dropped because receive buffers were full.
UINT64 TxTotalFrames
Transmit statistics.
UINT64 RxGoodFrames
Number of valid frames received and copied into receive buffers.
unsigned int good
Count of successful completions.
Definition netdevice.h:294
unsigned int bad
Count of error completions.
Definition netdevice.h:296
struct net_device_stats rx_stats
RX statistics.
Definition netdevice.h:426
struct net_device_stats tx_stats
TX statistics.
Definition netdevice.h:424

References net_device_stats::bad, container_of, DBGC, EFI_NOT_READY, efi_snp_claimed, net_device_stats::good, memcpy(), memset(), efi_snp_device::netdev, net_device::rx_stats, EFI_NETWORK_STATISTICS::RxDroppedFrames, EFI_NETWORK_STATISTICS::RxGoodFrames, EFI_NETWORK_STATISTICS::RxTotalFrames, efi_snp_device::snp, net_device::tx_stats, EFI_NETWORK_STATISTICS::TxDroppedFrames, EFI_NETWORK_STATISTICS::TxGoodFrames, and EFI_NETWORK_STATISTICS::TxTotalFrames.

◆ efi_snp_mcast_ip_to_mac()

EFI_STATUS EFIAPI efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
BOOLEAN ipv6,
EFI_IP_ADDRESS * ip,
EFI_MAC_ADDRESS * mac )
static

Convert multicast IP address to MAC address.

Parameters
snpSNP interface
ipv6Address is IPv6
ipIP address
macMAC address
Return values
efircEFI status code

Definition at line 487 of file efi_snp.c.

488 {
489 struct efi_snp_device *snpdev =
490 container_of ( snp, struct efi_snp_device, snp );
491 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
492 const char *ip_str;
493 int rc;
494
495 ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
496 inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
497 DBGC ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
498
499 /* Fail if net device is currently claimed for use by iPXE */
500 if ( efi_snp_claimed )
501 return EFI_NOT_READY;
502
503 /* Try to hash the address */
504 if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
505 ip, mac ) ) != 0 ) {
506 DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
507 snpdev, ip_str, strerror ( rc ) );
508 return EFIRC ( rc );
509 }
510
511 return 0;
512}
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
#define AF_INET
IPv4 Internet addresses.
Definition socket.h:64
#define AF_INET6
IPv6 Internet addresses.
Definition socket.h:65
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition ipv4.c:814
IP4_t ip
Destination IP address.
Definition pxe_api.h:1
IP address structure.
Definition in.h:42
int(* mc_hash)(unsigned int af, const void *net_addr, void *ll_addr)
Hash multicast address.
Definition netdevice.h:173

References AF_INET, AF_INET6, container_of, DBGC, EFI_NOT_READY, efi_snp_claimed, EFIRC, inet_ntoa(), ip, net_device::ll_protocol, mac, ll_protocol::mc_hash, efi_snp_device::netdev, rc, efi_snp_device::snp, and strerror().

◆ efi_snp_nvdata()

EFI_STATUS EFIAPI efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
BOOLEAN read,
UINTN offset,
UINTN len,
VOID * data )
static

Read or write non-volatile storage.

Parameters
snpSNP interface
readOperation is a read
offsetStarting offset within NVRAM
lenLength of data buffer
dataData buffer
Return values
efircEFI status code

Definition at line 525 of file efi_snp.c.

526 {
527 struct efi_snp_device *snpdev =
528 container_of ( snp, struct efi_snp_device, snp );
529
530 DBGC ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
531 ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
532 ( ( unsigned long ) len ) );
533 if ( ! read )
534 DBGC2_HDA ( snpdev, offset, data, len );
535
536 /* Fail if net device is currently claimed for use by iPXE */
537 if ( efi_snp_claimed )
538 return EFI_NOT_READY;
539
540 return EFI_UNSUPPORTED;
541}
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
struct option_descriptor read[1]
Definition nvo_cmd.c:116

References container_of, data, DBGC, DBGC2_HDA, EFI_NOT_READY, efi_snp_claimed, EFI_UNSUPPORTED, len, offset, read, efi_snp_device::snp, and VOID.

◆ efi_snp_get_status()

EFI_STATUS EFIAPI efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
UINT32 * interrupts,
VOID ** txbuf )
static

Read interrupt status and TX recycled buffer status.

Parameters
snpSNP interface
interruptsInterrupt status, or NULL
txbufRecycled transmit buffer address, or NULL
Return values
efircEFI status code

Definition at line 552 of file efi_snp.c.

553 {
554 struct efi_snp_device *snpdev =
555 container_of ( snp, struct efi_snp_device, snp );
556 struct efi_saved_tpl tpl;
557
558 DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
559
560 /* Fail if net device is currently claimed for use by iPXE */
561 if ( efi_snp_claimed ) {
562 DBGC2 ( snpdev, "\n" );
563 return EFI_NOT_READY;
564 }
565
566 /* Raise TPL */
567 efi_raise_tpl ( &tpl );
568
569 /* Poll the network device */
570 efi_snp_poll ( snpdev );
571
572 /* Interrupt status. In practice, this seems to be used only
573 * to detect TX completions.
574 */
575 if ( interrupts ) {
576 *interrupts = snpdev->interrupts;
577 DBGC2 ( snpdev, " INTS:%02x", *interrupts );
578 snpdev->interrupts = 0;
579 }
580
581 /* TX completions */
582 if ( txbuf ) {
583 if ( snpdev->tx_prod != snpdev->tx_cons ) {
584 *txbuf = snpdev->tx[snpdev->tx_cons++ % EFI_SNP_NUM_TX];
585 } else {
586 *txbuf = NULL;
587 }
588 DBGC2 ( snpdev, " TX:%p", *txbuf );
589 }
590
591 /* Restore TPL */
592 efi_restore_tpl ( &tpl );
593
594 DBGC2 ( snpdev, "\n" );
595 return 0;
596}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
static void efi_snp_poll(struct efi_snp_device *snpdev)
Poll net device and count received packets.
Definition efi_snp.c:168
#define EFI_SNP_NUM_TX
SNP transmit completion ring size.
Definition efi_snp.h:26
#define DBGC2(...)
Definition compiler.h:522
VOID * tx[EFI_SNP_NUM_TX]
Transmit completion ring.
Definition efi_snp.h:47

References container_of, DBGC2, EFI_NOT_READY, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, EFI_SNP_NUM_TX, efi_snp_poll(), efi_snp_device::interrupts, NULL, efi_snp_device::snp, efi_snp_device::tx, efi_snp_device::tx_cons, efi_snp_device::tx_prod, and VOID.

Referenced by efi_undi_get_status().

◆ efi_snp_transmit()

EFI_STATUS EFIAPI efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
UINTN ll_header_len,
UINTN len,
VOID * data,
EFI_MAC_ADDRESS * ll_src,
EFI_MAC_ADDRESS * ll_dest,
UINT16 * net_proto )
static

Start packet transmission.

Parameters
snpSNP interface
ll_header_lenLink-layer header length, if to be filled in
lenLength of data buffer
dataData buffer
ll_srcLink-layer source address, if specified
ll_destLink-layer destination address, if specified
net_protoNetwork-layer protocol (in host order)
Return values
efircEFI status code

Definition at line 611 of file efi_snp.c.

614 {
615 struct efi_snp_device *snpdev =
616 container_of ( snp, struct efi_snp_device, snp );
617 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
618 struct efi_saved_tpl tpl;
619 struct io_buffer *iobuf;
620 size_t payload_len;
621 unsigned int tx_fill;
622 int rc;
623
624 DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
625 ( ( unsigned long ) len ) );
626 if ( ll_header_len ) {
627 if ( ll_src ) {
628 DBGC2 ( snpdev, " src %s",
629 ll_protocol->ntoa ( ll_src ) );
630 }
631 if ( ll_dest ) {
632 DBGC2 ( snpdev, " dest %s",
633 ll_protocol->ntoa ( ll_dest ) );
634 }
635 if ( net_proto ) {
636 DBGC2 ( snpdev, " proto %04x", *net_proto );
637 }
638 }
639 DBGC2 ( snpdev, "\n" );
640
641 /* Fail if net device is currently claimed for use by iPXE */
642 if ( efi_snp_claimed ) {
643 rc = -EAGAIN;
644 goto err_claimed;
645 }
646
647 /* Raise TPL */
648 efi_raise_tpl ( &tpl );
649
650 /* Sanity checks */
651 if ( ll_header_len ) {
652 if ( ll_header_len != ll_protocol->ll_header_len ) {
653 DBGC ( snpdev, "SNPDEV %p TX invalid header length "
654 "%ld\n", snpdev,
655 ( ( unsigned long ) ll_header_len ) );
656 rc = -EINVAL;
657 goto err_sanity;
658 }
659 if ( len < ll_header_len ) {
660 DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
661 snpdev, ( ( unsigned long ) len ) );
662 rc = -EINVAL;
663 goto err_sanity;
664 }
665 if ( ! ll_dest ) {
666 DBGC ( snpdev, "SNPDEV %p TX missing destination "
667 "address\n", snpdev );
668 rc = -EINVAL;
669 goto err_sanity;
670 }
671 if ( ! net_proto ) {
672 DBGC ( snpdev, "SNPDEV %p TX missing network "
673 "protocol\n", snpdev );
674 rc = -EINVAL;
675 goto err_sanity;
676 }
677 if ( ! ll_src )
678 ll_src = &snpdev->mode.CurrentAddress;
679 }
680
681 /* Allocate buffer */
682 payload_len = ( len - ll_protocol->ll_header_len );
683 iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
684 payload_len : IOB_ZLEN ) );
685 if ( ! iobuf ) {
686 DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
687 "buffer\n", snpdev, ( ( unsigned long ) len ) );
688 rc = -ENOMEM;
689 goto err_alloc_iob;
690 }
691 iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
693 memcpy ( iob_put ( iobuf, len ), data, len );
694
695 /* Create link-layer header, if specified */
696 if ( ll_header_len ) {
698 if ( ( rc = ll_protocol->push ( snpdev->netdev,
699 iobuf, ll_dest, ll_src,
700 htons ( *net_proto ) )) != 0 ){
701 DBGC ( snpdev, "SNPDEV %p TX could not construct "
702 "header: %s\n", snpdev, strerror ( rc ) );
703 goto err_ll_push;
704 }
705 }
706
707 /* Transmit packet */
708 if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
709 DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
710 snpdev, strerror ( rc ) );
711 goto err_tx;
712 }
713
714 /* Record in transmit completion ring. If we run out of
715 * space, report the failure even though we have already
716 * transmitted the packet.
717 *
718 * This allows us to report completions only for packets for
719 * which we had reported successfully initiating transmission,
720 * while continuing to support clients that never poll for
721 * transmit completions.
722 */
723 tx_fill = ( snpdev->tx_prod - snpdev->tx_cons );
724 if ( tx_fill >= EFI_SNP_NUM_TX ) {
725 DBGC ( snpdev, "SNPDEV %p TX completion ring full\n", snpdev );
726 rc = -ENOBUFS;
727 goto err_ring_full;
728 }
729 snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
731
732 /* Restore TPL */
733 efi_restore_tpl ( &tpl );
734
735 return 0;
736
737 err_ring_full:
738 err_tx:
739 err_ll_push:
740 free_iob ( iobuf );
741 err_alloc_iob:
742 err_sanity:
743 efi_restore_tpl ( &tpl );
744 err_claimed:
745 return EFIRC ( rc );
746}
#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOBUFS
No buffer space available.
Definition errno.h:499
#define htons(value)
Definition byteswap.h:136
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define IOB_ZLEN
Minimum I/O buffer length and alignment.
Definition iobuf.h:29
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
#define iob_pull(iobuf, len)
Definition iobuf.h:107
int netdev_tx(struct net_device *netdev, struct io_buffer *iobuf)
Transmit raw packet via network device.
Definition netdevice.c:335
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition netdevice.h:46
EFI_MAC_ADDRESS CurrentAddress
The current HW MAC address for the network interface.
int(* push)(struct net_device *netdev, struct io_buffer *iobuf, const void *ll_dest, const void *ll_source, uint16_t net_proto)
Add link-layer header.
Definition netdevice.h:128

References alloc_iob(), container_of, EFI_SIMPLE_NETWORK_MODE::CurrentAddress, data, DBGC, DBGC2, EAGAIN, efi_raise_tpl(), efi_restore_tpl(), EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT, efi_snp_claimed, EFI_SNP_NUM_TX, EFIRC, EINVAL, ENOBUFS, ENOMEM, free_iob(), htons, efi_snp_device::interrupts, iob_disown, iob_pull, iob_put, iob_reserve, IOB_ZLEN, len, ll_protocol::ll_header_len, net_device::ll_protocol, MAX_LL_HEADER_LEN, memcpy(), efi_snp_device::mode, efi_snp_device::netdev, netdev_tx(), ll_protocol::ntoa, ll_protocol::push, rc, efi_snp_device::snp, strerror(), efi_snp_device::tx, efi_snp_device::tx_cons, efi_snp_device::tx_prod, and VOID.

Referenced by efi_undi_transmit().

◆ efi_snp_receive()

EFI_STATUS EFIAPI efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL * snp,
UINTN * ll_header_len,
UINTN * len,
VOID * data,
EFI_MAC_ADDRESS * ll_src,
EFI_MAC_ADDRESS * ll_dest,
UINT16 * net_proto )
static

Receive packet.

Parameters
snpSNP interface
ll_header_lenLink-layer header length, if to be filled in
lenLength of data buffer
dataData buffer
ll_srcLink-layer source address, if specified
ll_destLink-layer destination address, if specified
net_protoNetwork-layer protocol (in host order)
Return values
efircEFI status code

Definition at line 761 of file efi_snp.c.

764 {
765 struct efi_snp_device *snpdev =
766 container_of ( snp, struct efi_snp_device, snp );
767 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
768 struct efi_saved_tpl tpl;
769 struct io_buffer *iobuf;
770 const void *iob_ll_dest;
771 const void *iob_ll_src;
772 uint16_t iob_net_proto;
773 unsigned int iob_flags;
774 size_t copy_len;
775 int rc;
776
777 DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
778 ( ( unsigned long ) *len ) );
779
780 /* Fail if net device is currently claimed for use by iPXE */
781 if ( efi_snp_claimed ) {
782 rc = -EAGAIN;
783 goto err_claimed;
784 }
785
786 /* Raise TPL */
787 efi_raise_tpl ( &tpl );
788
789 /* Poll the network device */
790 efi_snp_poll ( snpdev );
791
792 /* Check for an available packet */
793 iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
794 if ( ! iobuf ) {
795 DBGC2 ( snpdev, "\n" );
796 rc = -EAGAIN;
797 goto out_no_packet;
798 }
799 DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
800
801 /* Dequeue packet */
802 list_del ( &iobuf->list );
803
804 /* Return packet to caller, truncating to buffer length */
805 copy_len = iob_len ( iobuf );
806 if ( copy_len > *len )
807 copy_len = *len;
808 memcpy ( data, iobuf->data, copy_len );
809 *len = iob_len ( iobuf );
810
811 /* Attempt to decode link-layer header */
812 if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
813 &iob_ll_src, &iob_net_proto,
814 &iob_flags ) ) != 0 ) {
815 DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
816 snpdev, strerror ( rc ) );
817 goto out_bad_ll_header;
818 }
819
820 /* Return link-layer header parameters to caller, if required */
821 if ( ll_header_len )
822 *ll_header_len = ll_protocol->ll_header_len;
823 if ( ll_src )
824 memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
825 if ( ll_dest )
826 memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
827 if ( net_proto )
828 *net_proto = ntohs ( iob_net_proto );
829
830 /* Check buffer length */
831 rc = ( ( copy_len == *len ) ? 0 : -ERANGE );
832
833 out_bad_ll_header:
834 free_iob ( iobuf );
835 out_no_packet:
836 efi_restore_tpl ( &tpl );
837 err_claimed:
838 return EFIRC ( rc );
839}
unsigned short uint16_t
Definition stdint.h:11
#define ERANGE
Result too large.
Definition errno.h:640
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition list.h:334
void * data
Start of data.
Definition iobuf.h:53
int(* pull)(struct net_device *netdev, struct io_buffer *iobuf, const void **ll_dest, const void **ll_source, uint16_t *net_proto, unsigned int *flags)
Remove link-layer header.
Definition netdevice.h:142

References container_of, data, io_buffer::data, DBGC, DBGC2, EAGAIN, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_poll(), EFIRC, ERANGE, free_iob(), iob_len(), len, io_buffer::list, list_del, list_first_entry, ll_protocol::ll_addr_len, ll_protocol::ll_header_len, net_device::ll_protocol, memcpy(), efi_snp_device::netdev, ntohs, ll_protocol::pull, rc, efi_snp_device::rx, efi_snp_device::snp, strerror(), and VOID.

Referenced by efi_undi_receive().

◆ efi_snp_wait_for_packet()

VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
VOID * context )
static

Poll event.

Parameters
eventEvent
contextEvent context

Definition at line 847 of file efi_snp.c.

848 {
849 struct efi_snp_device *snpdev = context;
850 struct efi_saved_tpl tpl;
851
852 DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
853
854 /* Do nothing unless the net device is open */
855 if ( ! netdev_is_open ( snpdev->netdev ) )
856 return;
857
858 /* Do nothing if net device is currently claimed for use by iPXE */
859 if ( efi_snp_claimed )
860 return;
861
862 /* Raise TPL */
863 efi_raise_tpl ( &tpl );
864
865 /* Poll the network device */
866 efi_snp_poll ( snpdev );
867
868 /* Restore TPL */
869 efi_restore_tpl ( &tpl );
870}
#define DBGCP(...)
Definition compiler.h:539

References __unused, DBGCP, EFI_EVENT, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_poll(), EFIAPI, efi_snp_device::netdev, netdev_is_open(), and VOID.

Referenced by efi_snp_probe().

◆ efi_undi_checksum()

uint8_t efi_undi_checksum ( void * data,
size_t len )
static

Calculate UNDI byte checksum.

Parameters
dataData
lenLength of data
Return values
sumChecksum

Definition at line 921 of file efi_snp.c.

921 {
922 uint8_t *bytes = data;
923 uint8_t sum = 0;
924
925 while ( len-- )
926 sum += *bytes++;
927 return sum;
928}
unsigned char uint8_t
Definition stdint.h:10
uint8_t bytes[64]
Definition ib_mad.h:5

References bytes, data, and len.

Referenced by efi_snp_probe().

◆ efi_undi_ifnum()

unsigned int efi_undi_ifnum ( struct efi_snp_device * snpdev)
static

Get UNDI SNP device interface number.

Parameters
snpdevSNP device
Return values
ifnumUNDI interface number

Definition at line 936 of file efi_snp.c.

936 {
937
938 /* iPXE network device scope IDs are one-based (leaving zero
939 * meaning "unspecified"). UNDI interface numbers are
940 * zero-based.
941 */
942 return ( snpdev->netdev->scope_id - 1 );
943}
unsigned int scope_id
Scope ID.
Definition netdevice.h:361

References efi_snp_device::netdev, and net_device::scope_id.

Referenced by efi_snp_probe(), and efi_undi_snpdev().

◆ efi_undi_snpdev()

struct efi_snp_device * efi_undi_snpdev ( unsigned int ifnum)
static

Identify UNDI SNP device.

Parameters
ifnumInterface number
Return values
snpdevSNP device, or NULL if not found

Definition at line 951 of file efi_snp.c.

951 {
952 struct efi_snp_device *snpdev;
953
954 list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
955 if ( efi_undi_ifnum ( snpdev ) == ifnum )
956 return snpdev;
957 }
958 return NULL;
959}
static unsigned int efi_undi_ifnum(struct efi_snp_device *snpdev)
Get UNDI SNP device interface number.
Definition efi_snp.c:936
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
struct list_head list
List of SNP devices.
Definition efi_snp.h:31

References efi_undi_ifnum(), efi_snp_device::list, list_for_each_entry, and NULL.

Referenced by efi_undi_issue().

◆ efi_undi_statcode()

PXE_STATCODE efi_undi_statcode ( EFI_STATUS efirc)
static

Convert EFI status code to UNDI status code.

Parameters
efircEFI status code
Return values
statcodeUNDI status code

Definition at line 967 of file efi_snp.c.

967 {
968
969 switch ( efirc ) {
975 default:
977 }
978}
#define EFI_INVALID_PARAMETER
Enumeration of EFI_STATUS.
#define EFI_PROTOCOL_ERROR
Enumeration of EFI_STATUS.
#define EFI_OUT_OF_RESOURCES
Enumeration of EFI_STATUS.
#define PXE_STATCODE_INVALID_CDB
Definition UefiPxe.h:607
#define PXE_STATCODE_DEVICE_FAILURE
Definition UefiPxe.h:616
#define PXE_STATCODE_NO_DATA
Definition UefiPxe.h:625
#define PXE_STATCODE_BUFFER_FULL
Definition UefiPxe.h:619
#define PXE_STATCODE_INVALID_PARAMETER
Definition UefiPxe.h:620
#define PXE_STATCODE_UNSUPPORTED
Definition UefiPxe.h:618

References EFI_INVALID_PARAMETER, EFI_NOT_READY, EFI_OUT_OF_RESOURCES, EFI_PROTOCOL_ERROR, EFI_UNSUPPORTED, PXE_STATCODE_BUFFER_FULL, PXE_STATCODE_DEVICE_FAILURE, PXE_STATCODE_INVALID_CDB, PXE_STATCODE_INVALID_PARAMETER, PXE_STATCODE_NO_DATA, and PXE_STATCODE_UNSUPPORTED.

Referenced by efi_undi_issue().

◆ efi_undi_get_state()

EFI_STATUS efi_undi_get_state ( struct efi_snp_device * snpdev,
PXE_CDB * cdb )
static

Get state.

Parameters
snpdevSNP device
cdbCommand description block
Return values
efircEFI status code

Definition at line 987 of file efi_snp.c.

988 {
990
991 DBGC ( snpdev, "UNDI %p GET STATE\n", snpdev );
992
993 /* Return current state */
994 if ( mode->State == EfiSimpleNetworkInitialized ) {
996 } else if ( mode->State == EfiSimpleNetworkStarted ) {
998 } else {
1000 }
1001
1002 return 0;
1003}
#define PXE_STATFLAGS_GET_STATE_STARTED
Definition UefiPxe.h:426
#define PXE_STATFLAGS_GET_STATE_STOPPED
Definition UefiPxe.h:427
#define PXE_STATFLAGS_GET_STATE_INITIALIZED
Definition UefiPxe.h:425
PXE_STATFLAGS StatFlags
Definition UefiPxe.h:884

References DBGC, EfiSimpleNetworkInitialized, EfiSimpleNetworkStarted, efi_snp_device::mode, mode, PXE_STATFLAGS_GET_STATE_INITIALIZED, PXE_STATFLAGS_GET_STATE_STARTED, PXE_STATFLAGS_GET_STATE_STOPPED, and s_pxe_cdb::StatFlags.

Referenced by efi_undi_issue().

◆ efi_undi_start()

EFI_STATUS efi_undi_start ( struct efi_snp_device * snpdev)
static

Start.

Parameters
snpdevSNP device
Return values
efircEFI status code

Definition at line 1011 of file efi_snp.c.

1011 {
1012 EFI_STATUS efirc;
1013
1014 DBGC ( snpdev, "UNDI %p START\n", snpdev );
1015
1016 /* Start SNP device */
1017 if ( ( efirc = efi_snp_start ( &snpdev->snp ) ) != 0 )
1018 return efirc;
1019
1020 return 0;
1021}
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
static EFI_STATUS EFIAPI efi_snp_start(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Change SNP state from "stopped" to "started".
Definition efi_snp.c:190

References DBGC, efi_snp_start(), and efi_snp_device::snp.

Referenced by efi_undi_issue().

◆ efi_undi_stop()

EFI_STATUS efi_undi_stop ( struct efi_snp_device * snpdev)
static

Stop.

Parameters
snpdevSNP device
Return values
efircEFI status code

Definition at line 1029 of file efi_snp.c.

1029 {
1030 EFI_STATUS efirc;
1031
1032 DBGC ( snpdev, "UNDI %p STOP\n", snpdev );
1033
1034 /* Stop SNP device */
1035 if ( ( efirc = efi_snp_stop ( &snpdev->snp ) ) != 0 )
1036 return efirc;
1037
1038 return 0;
1039}
static EFI_STATUS EFIAPI efi_snp_stop(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Change SNP state from "started" to "stopped".
Definition efi_snp.c:214

References DBGC, efi_snp_stop(), and efi_snp_device::snp.

Referenced by efi_undi_issue().

◆ efi_undi_get_init_info()

EFI_STATUS efi_undi_get_init_info ( struct efi_snp_device * snpdev,
PXE_CDB * cdb,
PXE_DB_GET_INIT_INFO * db )
static

Get initialisation information.

Parameters
snpdevSNP device
cdbCommand description block
dbData block
Return values
efircEFI status code

Definition at line 1049 of file efi_snp.c.

1051 {
1052 struct net_device *netdev = snpdev->netdev;
1053 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1054
1055 DBGC ( snpdev, "UNDI %p GET INIT INFO\n", snpdev );
1056
1057 /* Populate structure */
1058 memset ( db, 0, sizeof ( *db ) );
1059 db->FrameDataLen = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
1060 db->MediaHeaderLen = ll_protocol->ll_header_len;
1061 db->HWaddrLen = ll_protocol->ll_addr_len;
1062 db->IFtype = ntohs ( ll_protocol->ll_proto );
1065
1066 return 0;
1067}
#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
Definition UefiPxe.h:444
#define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
Definition UefiPxe.h:440
static struct dmfe_private * db
Definition dmfe.c:177

References db, DBGC, ll_protocol::ll_addr_len, ll_protocol::ll_header_len, ll_protocol::ll_proto, memset(), efi_snp_device::netdev, netdev, ntohs, PXE_STATFLAGS_CABLE_DETECT_SUPPORTED, PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED, and s_pxe_cdb::StatFlags.

Referenced by efi_undi_issue().

◆ efi_undi_initialize()

EFI_STATUS efi_undi_initialize ( struct efi_snp_device * snpdev,
PXE_CDB * cdb )
static

Initialise.

Parameters
snpdevSNP device
cdbCommand description block
efircEFI status code

Definition at line 1076 of file efi_snp.c.

1077 {
1078 struct net_device *netdev = snpdev->netdev;
1079 EFI_STATUS efirc;
1080
1081 DBGC ( snpdev, "UNDI %p INITIALIZE\n", snpdev );
1082
1083 /* Reset SNP device */
1084 if ( ( efirc = efi_snp_initialize ( &snpdev->snp, 0, 0 ) ) != 0 )
1085 return efirc;
1086
1087 /* Report link state */
1088 if ( ! netdev_link_ok ( netdev ) )
1090
1091 return 0;
1092}
#define PXE_STATFLAGS_INITIALIZED_NO_MEDIA
UNDI Initialize.
Definition UefiPxe.h:449
static EFI_STATUS EFIAPI efi_snp_initialize(EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINTN extra_rx_bufsize, UINTN extra_tx_bufsize)
Open the network device.
Definition efi_snp.c:239

References DBGC, efi_snp_initialize(), efi_snp_device::netdev, netdev, netdev_link_ok(), PXE_STATFLAGS_INITIALIZED_NO_MEDIA, efi_snp_device::snp, and s_pxe_cdb::StatFlags.

Referenced by efi_undi_issue().

◆ efi_undi_reset()

EFI_STATUS efi_undi_reset ( struct efi_snp_device * snpdev)
static

Reset.

Parameters
snpdevSNP device
efircEFI status code

Definition at line 1100 of file efi_snp.c.

1100 {
1101 EFI_STATUS efirc;
1102
1103 DBGC ( snpdev, "UNDI %p RESET\n", snpdev );
1104
1105 /* Reset SNP device */
1106 if ( ( efirc = efi_snp_reset ( &snpdev->snp, 0 ) ) != 0 )
1107 return efirc;
1108
1109 return 0;
1110}
static EFI_STATUS EFIAPI efi_snp_reset(EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify)
Reset the network device.
Definition efi_snp.c:286

References DBGC, efi_snp_reset(), and efi_snp_device::snp.

Referenced by efi_undi_issue().

◆ efi_undi_shutdown()

EFI_STATUS efi_undi_shutdown ( struct efi_snp_device * snpdev)
static

Shutdown.

Parameters
snpdevSNP device
efircEFI status code

Definition at line 1118 of file efi_snp.c.

1118 {
1119 EFI_STATUS efirc;
1120
1121 DBGC ( snpdev, "UNDI %p SHUTDOWN\n", snpdev );
1122
1123 /* Reset SNP device */
1124 if ( ( efirc = efi_snp_shutdown ( &snpdev->snp ) ) != 0 )
1125 return efirc;
1126
1127 return 0;
1128}
static EFI_STATUS EFIAPI efi_snp_shutdown(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Shut down the network device.
Definition efi_snp.c:330

References DBGC, efi_snp_shutdown(), and efi_snp_device::snp.

Referenced by efi_undi_issue().

◆ efi_undi_receive_filters()

EFI_STATUS efi_undi_receive_filters ( struct efi_snp_device * snpdev,
PXE_CDB * cdb )
static

Get/set receive filters.

Parameters
snpdevSNP device
cdbCommand description block
efircEFI status code

Definition at line 1137 of file efi_snp.c.

1138 {
1139
1140 DBGC ( snpdev, "UNDI %p RECEIVE FILTERS\n", snpdev );
1141
1142 /* Mark everything as supported */
1147
1148 return 0;
1149}
#define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST
If set, all multicast packets will be received.
Definition UefiPxe.h:507
#define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST
If set, broadcast packets will be received.
Definition UefiPxe.h:491
#define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST
UNDI Receive Filters.
Definition UefiPxe.h:486
#define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS
If set, all packets will be received.
Definition UefiPxe.h:502

References DBGC, PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST, PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST, PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS, PXE_STATFLAGS_RECEIVE_FILTER_UNICAST, and s_pxe_cdb::StatFlags.

Referenced by efi_undi_issue().

◆ efi_undi_station_address()

EFI_STATUS efi_undi_station_address ( struct efi_snp_device * snpdev,
PXE_CDB * cdb,
PXE_CPB_STATION_ADDRESS * cpb,
PXE_DB_STATION_ADDRESS * db )
static

Get/set station address.

Parameters
snpdevSNP device
cdbCommand description block
cpbCommand parameter block
efircEFI status code

Definition at line 1159 of file efi_snp.c.

1162 {
1163 struct net_device *netdev = snpdev->netdev;
1164 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1165 void *mac;
1166 int reset;
1167 EFI_STATUS efirc;
1168
1169 DBGC ( snpdev, "UNDI %p STATION ADDRESS\n", snpdev );
1170
1171 /* Update address if applicable */
1172 reset = ( cdb->OpFlags & PXE_OPFLAGS_STATION_ADDRESS_RESET );
1173 mac = ( cpb ? &cpb->StationAddr : NULL );
1174 if ( ( reset || mac ) &&
1175 ( ( efirc = efi_snp_station_address ( &snpdev->snp, reset,
1176 mac ) ) != 0 ) )
1177 return efirc;
1178
1179 /* Fill in current addresses, if applicable */
1180 if ( db ) {
1181 memset ( db, 0, sizeof ( *db ) );
1182 memcpy ( &db->StationAddr, netdev->ll_addr,
1184 memcpy ( &db->BroadcastAddr, netdev->ll_broadcast,
1186 memcpy ( &db->PermanentAddr, netdev->hw_addr,
1188 }
1189
1190 return 0;
1191}
#define PXE_OPFLAGS_STATION_ADDRESS_RESET
Definition UefiPxe.h:318
static EFI_STATUS EFIAPI efi_snp_station_address(EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset, EFI_MAC_ADDRESS *new)
Set station address.
Definition efi_snp.c:401
uint8_t hw_addr_len
Hardware address length.
Definition netdevice.h:197
PXE_OPFLAGS OpFlags
Definition UefiPxe.h:878
PXE_MAC_ADDR StationAddr
If supplied and supported, the current station MAC address will be changed.
Definition UefiPxe.h:1339

References db, DBGC, efi_snp_station_address(), ll_protocol::hw_addr_len, ll_protocol::ll_addr_len, mac, memcpy(), memset(), efi_snp_device::netdev, netdev, NULL, s_pxe_cdb::OpFlags, PXE_OPFLAGS_STATION_ADDRESS_RESET, efi_snp_device::snp, and s_pxe_cpb_station_address::StationAddr.

Referenced by efi_undi_issue().

◆ efi_undi_get_status()

EFI_STATUS efi_undi_get_status ( struct efi_snp_device * snpdev,
PXE_CDB * cdb,
PXE_DB_GET_STATUS * db )
static

Get interrupt status.

Parameters
snpdevSNP device
cdbCommand description block
dbData block
efircEFI status code

Definition at line 1201 of file efi_snp.c.

1202 {
1203 UINT32 interrupts;
1204 VOID *txbuf;
1205 struct io_buffer *rxbuf;
1206 EFI_STATUS efirc;
1207
1208 DBGC2 ( snpdev, "UNDI %p GET STATUS\n", snpdev );
1209
1210 /* Get status */
1211 if ( ( efirc = efi_snp_get_status ( &snpdev->snp, &interrupts,
1212 &txbuf ) ) != 0 )
1213 return efirc;
1214
1215 /* Report status */
1216 memset ( db, 0, sizeof ( *db ) );
1217 if ( interrupts & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT )
1219 if ( interrupts & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT )
1221 if ( txbuf ) {
1222 db->TxBuffer[0] = ( ( intptr_t ) txbuf );
1223 } else {
1225 /* The specification states clearly that UNDI drivers
1226 * should set TXBUF_QUEUE_EMPTY if all completed
1227 * buffer addresses are written into the returned data
1228 * block. However, SnpDxe chooses to interpret
1229 * TXBUF_QUEUE_EMPTY as a synonym for
1230 * NO_TXBUFS_WRITTEN, thereby rendering it entirely
1231 * pointless. Work around this UEFI stupidity, as per
1232 * usual.
1233 */
1234 if ( snpdev->tx_prod == snpdev->tx_cons )
1235 cdb->StatFlags |=
1237 }
1238 rxbuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
1239 if ( rxbuf )
1240 db->RxFrameLen = iob_len ( rxbuf );
1241 if ( ! netdev_link_ok ( snpdev->netdev ) )
1243
1244 return 0;
1245}
unsigned int UINT32
4-byte unsigned value.
#define VOID
Undeclared type.
Definition Base.h:272
#define PXE_STATFLAGS_GET_STATUS_TRANSMIT
If set, at least one transmit interrupt occurred.
Definition UefiPxe.h:550
#define PXE_STATFLAGS_GET_STATUS_RECEIVE
If set, at least one receive interrupt occurred.
Definition UefiPxe.h:545
#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA
This flag is set if there is no media detected.
Definition UefiPxe.h:577
#define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY
This flag is set if the transmitted buffer queue is empty.
Definition UefiPxe.h:566
#define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN
This flag is set if no transmitted buffer addresses were written into the DB.
Definition UefiPxe.h:572
unsigned long intptr_t
Definition stdint.h:21
static EFI_STATUS EFIAPI efi_snp_get_status(EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 *interrupts, VOID **txbuf)
Read interrupt status and TX recycled buffer status.
Definition efi_snp.c:552

References db, DBGC2, EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT, EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT, efi_snp_get_status(), iob_len(), io_buffer::list, list_first_entry, memset(), efi_snp_device::netdev, netdev_link_ok(), PXE_STATFLAGS_GET_STATUS_NO_MEDIA, PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN, PXE_STATFLAGS_GET_STATUS_RECEIVE, PXE_STATFLAGS_GET_STATUS_TRANSMIT, PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY, efi_snp_device::rx, efi_snp_device::snp, s_pxe_cdb::StatFlags, efi_snp_device::tx_cons, efi_snp_device::tx_prod, and VOID.

Referenced by efi_undi_issue().

◆ efi_undi_fill_header()

EFI_STATUS efi_undi_fill_header ( struct efi_snp_device * snpdev,
PXE_CDB * cdb,
PXE_CPB_ANY * cpb )
static

Fill header.

Parameters
snpdevSNP device
cdbCommand description block
cpbCommand parameter block
efircEFI status code

Definition at line 1255 of file efi_snp.c.

1256 {
1257 struct net_device *netdev = snpdev->netdev;
1258 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1259 PXE_CPB_FILL_HEADER *whole = &cpb->fill_header;
1261 VOID *data;
1262 void *dest;
1263 void *src;
1264 uint16_t proto;
1265 struct io_buffer iobuf;
1266 int rc;
1267
1268 /* SnpDxe will (pointlessly) use PXE_CPB_FILL_HEADER_FRAGMENTED
1269 * even though we choose to explicitly not claim support for
1270 * fragments via PXE_ROMID_IMP_FRAG_SUPPORTED.
1271 */
1273 data = ( ( void * ) ( intptr_t ) fragged->FragDesc[0].FragAddr);
1274 dest = &fragged->DestAddr;
1275 src = &fragged->SrcAddr;
1276 proto = fragged->Protocol;
1277 } else {
1278 data = ( ( void * ) ( intptr_t ) whole->MediaHeader );
1279 dest = &whole->DestAddr;
1280 src = &whole->SrcAddr;
1281 proto = whole->Protocol;
1282 }
1283
1284 /* Construct link-layer header */
1285 iob_populate ( &iobuf, data, 0, ll_protocol->ll_header_len );
1287 if ( ( rc = ll_protocol->push ( netdev, &iobuf, dest, src,
1288 proto ) ) != 0 )
1289 return EFIRC ( rc );
1290
1291 return 0;
1292}
struct s_pxe_cpb_fill_header PXE_CPB_FILL_HEADER
struct s_pxe_cpb_fill_header_fragmented PXE_CPB_FILL_HEADER_FRAGMENTED
#define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED
Definition UefiPxe.h:376
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
static const void * src
Definition string.h:48
static void iob_populate(struct io_buffer *iobuf, void *data, size_t len, size_t max_len)
Create a temporary I/O buffer.
Definition iobuf.h:195
PXE_UINT64 FragAddr
Address of this packet fragment.
Definition UefiPxe.h:1650
PXE_MEDIA_PROTOCOL Protocol
Protocol type.
Definition UefiPxe.h:1625
struct s_pxe_cpb_fill_header_fragmented::@146373153332152126301350117074014067050140014012 FragDesc[MAX_XMIT_FRAGMENTS]
Array of packet fragment descriptors.
PXE_MAC_ADDR SrcAddr
Source and destination MAC addresses.
Definition UefiPxe.h:1612
PXE_MAC_ADDR DestAddr
Definition UefiPxe.h:1577
PXE_UINT64 MediaHeader
Address of first byte of media header.
Definition UefiPxe.h:1583
PXE_UINT16 Protocol
Protocol type.
Definition UefiPxe.h:1595
PXE_MAC_ADDR SrcAddr
Source and destination MAC addresses.
Definition UefiPxe.h:1576
PXE_CPB_FILL_HEADER_FRAGMENTED fill_header_fragmented
Definition efi_snp.c:901
PXE_CPB_FILL_HEADER fill_header
Definition efi_snp.c:900

References data, dest, s_pxe_cpb_fill_header::DestAddr, s_pxe_cpb_fill_header_fragmented::DestAddr, EFIRC, PXE_CPB_ANY::fill_header, PXE_CPB_ANY::fill_header_fragmented, s_pxe_cpb_fill_header_fragmented::FragAddr, s_pxe_cpb_fill_header_fragmented::FragDesc, iob_populate(), iob_reserve, ll_protocol::ll_header_len, s_pxe_cpb_fill_header::MediaHeader, efi_snp_device::netdev, netdev, s_pxe_cdb::OpFlags, s_pxe_cpb_fill_header::Protocol, s_pxe_cpb_fill_header_fragmented::Protocol, ll_protocol::push, PXE_OPFLAGS_FILL_HEADER_FRAGMENTED, rc, src, s_pxe_cpb_fill_header::SrcAddr, s_pxe_cpb_fill_header_fragmented::SrcAddr, and VOID.

Referenced by efi_undi_issue().

◆ efi_undi_transmit()

EFI_STATUS efi_undi_transmit ( struct efi_snp_device * snpdev,
PXE_CPB_TRANSMIT * cpb )
static

Transmit.

Parameters
snpdevSNP device
cpbCommand parameter block
efircEFI status code

Definition at line 1301 of file efi_snp.c.

1302 {
1303 VOID *data = ( ( void * ) ( intptr_t ) cpb->FrameAddr );
1304 EFI_STATUS efirc;
1305
1306 DBGC2 ( snpdev, "UNDI %p TRANSMIT\n", snpdev );
1307
1308 /* Transmit packet */
1309 if ( ( efirc = efi_snp_transmit ( &snpdev->snp, 0, cpb->DataLen,
1310 data, NULL, NULL, NULL ) ) != 0 )
1311 return efirc;
1312
1313 return 0;
1314}
static EFI_STATUS EFIAPI efi_snp_transmit(EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINTN ll_header_len, UINTN len, VOID *data, EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest, UINT16 *net_proto)
Start packet transmission.
Definition efi_snp.c:611
PXE_UINT32 DataLen
Length of the data portion of the frame buffer in bytes.
Definition UefiPxe.h:1675
PXE_UINT64 FrameAddr
Address of first byte of frame buffer.
Definition UefiPxe.h:1669

References data, s_pxe_cpb_transmit::DataLen, DBGC2, efi_snp_transmit(), s_pxe_cpb_transmit::FrameAddr, NULL, efi_snp_device::snp, and VOID.

Referenced by efi_undi_issue().

◆ efi_undi_receive()

EFI_STATUS efi_undi_receive ( struct efi_snp_device * snpdev,
PXE_CPB_RECEIVE * cpb,
PXE_DB_RECEIVE * db )
static

Receive.

Parameters
snpdevSNP device
cpbCommand parameter block
efircEFI status code

Definition at line 1323 of file efi_snp.c.

1325 {
1326 struct net_device *netdev = snpdev->netdev;
1327 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1328 VOID *data = ( ( void * ) ( intptr_t ) cpb->BufferAddr );
1329 UINTN hdr_len;
1330 UINTN len = cpb->BufferLen;
1333 UINT16 proto;
1334 EFI_STATUS efirc;
1335
1336 DBGC2 ( snpdev, "UNDI %p RECEIVE\n", snpdev );
1337
1338 /* Receive packet */
1339 if ( ( efirc = efi_snp_receive ( &snpdev->snp, &hdr_len, &len, data,
1340 &src, &dest, &proto ) ) != 0 )
1341 return efirc;
1342
1343 /* Describe frame */
1344 memset ( db, 0, sizeof ( *db ) );
1345 memcpy ( &db->SrcAddr, &src, ll_protocol->ll_addr_len );
1346 memcpy ( &db->DestAddr, &dest, ll_protocol->ll_addr_len );
1347 db->FrameLen = len;
1348 db->Protocol = proto;
1349 db->MediaHeaderLen = ll_protocol->ll_header_len;
1351
1352 return 0;
1353}
unsigned short UINT16
2-byte unsigned value.
UINT64 UINTN
Unsigned value of native width.
#define PXE_FRAME_TYPE_PROMISCUOUS
Definition UefiPxe.h:667
static EFI_STATUS EFIAPI efi_snp_receive(EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINTN *ll_header_len, UINTN *len, VOID *data, EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest, UINT16 *net_proto)
Receive packet.
Definition efi_snp.c:761
32-byte buffer containing a network Media Access Control address.
PXE_UINT32 BufferLen
Length of receive buffer.
Definition UefiPxe.h:1738
PXE_UINT64 BufferAddr
Address of first byte of receive buffer.
Definition UefiPxe.h:1731

References s_pxe_cpb_receive::BufferAddr, s_pxe_cpb_receive::BufferLen, data, db, DBGC2, dest, efi_snp_receive(), len, ll_protocol::ll_addr_len, ll_protocol::ll_header_len, memcpy(), memset(), efi_snp_device::netdev, netdev, PXE_FRAME_TYPE_PROMISCUOUS, efi_snp_device::snp, src, and VOID.

Referenced by efi_undi_issue().

◆ efi_undi_issue()

EFIAPI VOID efi_undi_issue ( UINT64 cdb_phys)
static

UNDI entry point.

Definition at line 1356 of file efi_snp.c.

1356 {
1357 PXE_CDB *cdb = ( ( void * ) ( intptr_t ) cdb_phys );
1358 PXE_CPB_ANY *cpb = ( ( void * ) ( intptr_t ) cdb->CPBaddr );
1359 PXE_DB_ANY *db = ( ( void * ) ( intptr_t ) cdb->DBaddr );
1360 struct efi_snp_device *snpdev;
1361 EFI_STATUS efirc;
1362
1363 /* Identify device */
1364 snpdev = efi_undi_snpdev ( cdb->IFnum );
1365 if ( ! snpdev ) {
1366 DBGC ( cdb, "UNDI invalid interface number %d\n", cdb->IFnum );
1369 return;
1370 }
1371
1372 /* Fail if net device is currently claimed for use by iPXE */
1373 if ( efi_snp_claimed ) {
1376 return;
1377 }
1378
1379 /* Handle opcode */
1382 switch ( cdb->OpCode ) {
1383
1385 efirc = efi_undi_get_state ( snpdev, cdb );
1386 break;
1387
1388 case PXE_OPCODE_START:
1389 efirc = efi_undi_start ( snpdev );
1390 break;
1391
1392 case PXE_OPCODE_STOP:
1393 efirc = efi_undi_stop ( snpdev );
1394 break;
1395
1397 efirc = efi_undi_get_init_info ( snpdev, cdb,
1398 &db->get_init_info );
1399 break;
1400
1402 efirc = efi_undi_initialize ( snpdev, cdb );
1403 break;
1404
1405 case PXE_OPCODE_RESET:
1406 efirc = efi_undi_reset ( snpdev );
1407 break;
1408
1410 efirc = efi_undi_shutdown ( snpdev );
1411 break;
1412
1414 efirc = efi_undi_receive_filters ( snpdev, cdb );
1415 break;
1416
1418 efirc = efi_undi_station_address ( snpdev, cdb,
1419 &cpb->station_address,
1420 &db->station_address );
1421 break;
1422
1424 efirc = efi_undi_get_status ( snpdev, cdb, &db->get_status );
1425 break;
1426
1428 efirc = efi_undi_fill_header ( snpdev, cdb, cpb );
1429 break;
1430
1432 efirc = efi_undi_transmit ( snpdev, &cpb->transmit );
1433 break;
1434
1435 case PXE_OPCODE_RECEIVE:
1436 efirc = efi_undi_receive ( snpdev, &cpb->receive,
1437 &db->receive );
1438 break;
1439
1440 default:
1441 DBGC ( snpdev, "UNDI %p unsupported opcode %#04x\n",
1442 snpdev, cdb->OpCode );
1443 efirc = EFI_UNSUPPORTED;
1444 break;
1445 }
1446
1447 /* Convert EFI status code to UNDI status code */
1448 if ( efirc != 0 ) {
1451 cdb->StatCode = efi_undi_statcode ( efirc );
1452 }
1453}
#define PXE_OPCODE_TRANSMIT
Transmit packet(s).
Definition UefiPxe.h:168
#define PXE_STATFLAGS_COMMAND_FAILED
Definition UefiPxe.h:418
#define PXE_OPCODE_STOP
Change UNDI operational state from Started to Stopped.
Definition UefiPxe.h:98
#define PXE_OPCODE_GET_STATUS
Get & clear interrupt status.
Definition UefiPxe.h:158
#define PXE_OPCODE_GET_STATE
Return UNDI operational state.
Definition UefiPxe.h:88
struct s_pxe_cdb PXE_CDB
#define PXE_OPCODE_STATION_ADDRESS
Read & change station MAC address.
Definition UefiPxe.h:138
#define PXE_STATFLAGS_COMMAND_COMPLETE
Definition UefiPxe.h:417
#define PXE_STATCODE_BUSY
Definition UefiPxe.h:609
#define PXE_OPCODE_FILL_HEADER
Fill media header in packet for transmit.
Definition UefiPxe.h:163
#define PXE_OPCODE_RESET
Re-initialize the NIC H/W.
Definition UefiPxe.h:118
#define PXE_STATFLAGS_STATUS_MASK
Common StatFlags that can be returned by all commands.
Definition UefiPxe.h:416
#define PXE_OPCODE_RECEIVE
Receive packet.
Definition UefiPxe.h:173
#define PXE_OPCODE_INITIALIZE
Changed UNDI operational state from Started to Initialized.
Definition UefiPxe.h:113
#define PXE_OPCODE_RECEIVE_FILTERS
Read & change state of packet receive filters.
Definition UefiPxe.h:133
#define PXE_OPCODE_START
Change UNDI operational state from Stopped to Started.
Definition UefiPxe.h:93
#define PXE_OPCODE_GET_INIT_INFO
Get UNDI initialization information.
Definition UefiPxe.h:103
#define PXE_STATCODE_SUCCESS
Common StatCodes returned by all UNDI commands, UNDI protocol functions and BC protocol functions.
Definition UefiPxe.h:605
#define PXE_OPCODE_SHUTDOWN
Change the UNDI operational state from Initialized to Started.
Definition UefiPxe.h:123
static EFI_STATUS efi_undi_receive(struct efi_snp_device *snpdev, PXE_CPB_RECEIVE *cpb, PXE_DB_RECEIVE *db)
Receive.
Definition efi_snp.c:1323
static EFI_STATUS efi_undi_receive_filters(struct efi_snp_device *snpdev, PXE_CDB *cdb)
Get/set receive filters.
Definition efi_snp.c:1137
static struct efi_snp_device * efi_undi_snpdev(unsigned int ifnum)
Identify UNDI SNP device.
Definition efi_snp.c:951
static EFI_STATUS efi_undi_start(struct efi_snp_device *snpdev)
Start.
Definition efi_snp.c:1011
static EFI_STATUS efi_undi_get_init_info(struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_DB_GET_INIT_INFO *db)
Get initialisation information.
Definition efi_snp.c:1049
static EFI_STATUS efi_undi_reset(struct efi_snp_device *snpdev)
Reset.
Definition efi_snp.c:1100
static EFI_STATUS efi_undi_stop(struct efi_snp_device *snpdev)
Stop.
Definition efi_snp.c:1029
static PXE_STATCODE efi_undi_statcode(EFI_STATUS efirc)
Convert EFI status code to UNDI status code.
Definition efi_snp.c:967
static EFI_STATUS efi_undi_fill_header(struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_CPB_ANY *cpb)
Fill header.
Definition efi_snp.c:1255
static EFI_STATUS efi_undi_shutdown(struct efi_snp_device *snpdev)
Shutdown.
Definition efi_snp.c:1118
static EFI_STATUS efi_undi_initialize(struct efi_snp_device *snpdev, PXE_CDB *cdb)
Initialise.
Definition efi_snp.c:1076
static EFI_STATUS efi_undi_transmit(struct efi_snp_device *snpdev, PXE_CPB_TRANSMIT *cpb)
Transmit.
Definition efi_snp.c:1301
static EFI_STATUS efi_undi_get_status(struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_DB_GET_STATUS *db)
Get interrupt status.
Definition efi_snp.c:1201
static EFI_STATUS efi_undi_station_address(struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_CPB_STATION_ADDRESS *cpb, PXE_DB_STATION_ADDRESS *db)
Get/set station address.
Definition efi_snp.c:1159
static EFI_STATUS efi_undi_get_state(struct efi_snp_device *snpdev, PXE_CDB *cdb)
Get state.
Definition efi_snp.c:987
PXE_UINT64 CPBaddr
Definition UefiPxe.h:881
PXE_STATCODE StatCode
Definition UefiPxe.h:883
PXE_UINT16 IFnum
Definition UefiPxe.h:885
PXE_UINT64 DBaddr
Definition UefiPxe.h:882
PXE_OPCODE OpCode
Definition UefiPxe.h:877
Union type for command parameter blocks.
Definition efi_snp.c:898
PXE_CPB_STATION_ADDRESS station_address
Definition efi_snp.c:899
PXE_CPB_TRANSMIT transmit
Definition efi_snp.c:902
PXE_CPB_RECEIVE receive
Definition efi_snp.c:903
Union type for data blocks.
Definition efi_snp.c:907

References s_pxe_cdb::CPBaddr, db, s_pxe_cdb::DBaddr, DBGC, efi_snp_claimed, efi_undi_fill_header(), efi_undi_get_init_info(), efi_undi_get_state(), efi_undi_get_status(), efi_undi_initialize(), efi_undi_receive(), efi_undi_receive_filters(), efi_undi_reset(), efi_undi_shutdown(), efi_undi_snpdev(), efi_undi_start(), efi_undi_statcode(), efi_undi_station_address(), efi_undi_stop(), efi_undi_transmit(), EFI_UNSUPPORTED, EFIAPI, s_pxe_cdb::IFnum, s_pxe_cdb::OpCode, PXE_OPCODE_FILL_HEADER, PXE_OPCODE_GET_INIT_INFO, PXE_OPCODE_GET_STATE, PXE_OPCODE_GET_STATUS, PXE_OPCODE_INITIALIZE, PXE_OPCODE_RECEIVE, PXE_OPCODE_RECEIVE_FILTERS, PXE_OPCODE_RESET, PXE_OPCODE_SHUTDOWN, PXE_OPCODE_START, PXE_OPCODE_STATION_ADDRESS, PXE_OPCODE_STOP, PXE_OPCODE_TRANSMIT, PXE_STATCODE_BUSY, PXE_STATCODE_INVALID_CDB, PXE_STATCODE_SUCCESS, PXE_STATFLAGS_COMMAND_COMPLETE, PXE_STATFLAGS_COMMAND_FAILED, PXE_STATFLAGS_STATUS_MASK, PXE_CPB_ANY::receive, s_pxe_cdb::StatCode, s_pxe_cdb::StatFlags, PXE_CPB_ANY::station_address, PXE_CPB_ANY::transmit, and VOID.

Referenced by efi_snp_probe().

◆ efi_vlan_set()

EFI_STATUS EFIAPI efi_vlan_set ( EFI_VLAN_CONFIG_PROTOCOL * vcfg,
UINT16 tag,
UINT8 priority )
static

Create or modify VLAN device.

Parameters
vcfgVLAN configuration protocol
tagVLAN tag
priorityDefault VLAN priority
Return values
efircEFI status code

Definition at line 1507 of file efi_snp.c.

1508 {
1509 struct efi_snp_device *snpdev =
1510 container_of ( vcfg, struct efi_snp_device, vcfg );
1511 struct net_device *trunk = snpdev->netdev;
1512 struct efi_saved_tpl tpl;
1513 int rc;
1514
1515 /* Raise TPL */
1516 efi_raise_tpl ( &tpl );
1517
1518 /* Create or modify VLAN device */
1519 if ( ( rc = vlan_create ( trunk, tag, priority ) ) != 0 ) {
1520 DBGC ( snpdev, "SNPDEV %p could not create VLAN tag %d: %s\n",
1521 snpdev, tag, strerror ( rc ) );
1522 goto err_create;
1523 }
1524 DBGC ( snpdev, "SNPDEV %p created VLAN tag %d priority %d\n",
1525 snpdev, tag, priority );
1526
1527 err_create:
1528 efi_restore_tpl ( &tpl );
1529 return EFIRC ( rc );
1530}
uint64_t tag
Identity tag.
Definition edd.h:1
uint16_t priority
Priotity.
Definition stp.h:1
EFI_VLAN_CONFIG_PROTOCOL vcfg
VLAN configuration protocol.
Definition efi_snp.h:57
int vlan_create(struct net_device *trunk, unsigned int tag, unsigned int priority)
Create VLAN device.
Definition vlan.c:344

References container_of, DBGC, efi_raise_tpl(), efi_restore_tpl(), EFIAPI, EFIRC, efi_snp_device::netdev, priority, rc, strerror(), tag, efi_snp_device::vcfg, and vlan_create().

◆ efi_vlan_find()

EFI_STATUS EFIAPI efi_vlan_find ( EFI_VLAN_CONFIG_PROTOCOL * vcfg,
UINT16 * filter,
UINT16 * count,
EFI_VLAN_FIND_DATA ** entries )
static

Find VLAN device(s)

Parameters
vcfgVLAN configuration protocol
filterVLAN tag, or NULL to find all VLANs
countNumber of VLANs
entriesList of VLANs
Return values
efircEFI status code

Definition at line 1541 of file efi_snp.c.

1543 {
1544 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1545 struct efi_snp_device *snpdev =
1546 container_of ( vcfg, struct efi_snp_device, vcfg );
1547 struct net_device *trunk = snpdev->netdev;
1548 struct net_device *vlan;
1549 struct efi_saved_tpl tpl;
1550 EFI_VLAN_FIND_DATA *entry;
1551 VOID *buffer;
1552 unsigned int tag;
1553 unsigned int tci;
1554 size_t len;
1555 EFI_STATUS efirc;
1556 int rc;
1557
1558 /* Raise TPL */
1559 efi_raise_tpl ( &tpl );
1560
1561 /* Count number of matching VLANs */
1562 *count = 0;
1563 for ( tag = 1 ; VLAN_TAG_IS_VALID ( tag ) ; tag++ ) {
1564 if ( filter && ( tag != *filter ) )
1565 continue;
1566 if ( ! ( vlan = vlan_find ( trunk, tag ) ) )
1567 continue;
1568 (*count)++;
1569 }
1570
1571 /* Allocate buffer to hold results */
1572 len = ( (*count) * sizeof ( *entry ) );
1573 if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
1574 &buffer ) ) != 0 ) {
1575 rc = -EEFI ( efirc );
1576 goto err_alloc;
1577 }
1578
1579 /* Fill in buffer */
1580 *entries = buffer;
1581 entry = *entries;
1582 for ( tag = 1 ; VLAN_TAG_IS_VALID ( tag ) ; tag++ ) {
1583 if ( filter && ( tag != *filter ) )
1584 continue;
1585 if ( ! ( vlan = vlan_find ( trunk, tag ) ) )
1586 continue;
1587 tci = vlan_tci ( vlan );
1588 entry->VlanId = VLAN_TAG ( tci );
1589 entry->Priority = VLAN_PRIORITY ( tci );
1590 assert ( entry->VlanId == tag );
1591 entry++;
1592 }
1593 assert ( entry == &(*entries)[*count] );
1594
1595 /* Success */
1596 rc = 0;
1597
1598 err_alloc:
1599 efi_restore_tpl ( &tpl );
1600 return EFIRC ( rc );
1601}
@ EfiBootServicesData
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
static unsigned int count
Number of entries.
Definition dwmac.h:220
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
__weak unsigned int vlan_tci(struct net_device *netdev __unused)
Get the VLAN tag control information (when VLAN support is not present)
Definition netdevice.c:1199
UINT8_t filter
Receive packet filter.
Definition pxe_api.h:11
EFI_ALLOCATE_POOL AllocatePool
Definition UefiSpec.h:1949
EFI_VLAN_FIND_DATA.
Definition VlanConfig.h:28
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition vlan.c:209
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition vlan.h:55
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition vlan.h:30
#define VLAN_PRIORITY(tci)
Extract VLAN priority from tag control information.
Definition vlan.h:38

References EFI_BOOT_SERVICES::AllocatePool, assert, buffer, container_of, count, EEFI, efi_raise_tpl(), efi_restore_tpl(), efi_systab, EFIAPI, EfiBootServicesData, EFIRC, filter, len, efi_snp_device::netdev, rc, tag, efi_snp_device::vcfg, vlan_find(), VLAN_PRIORITY, VLAN_TAG, VLAN_TAG_IS_VALID, vlan_tci(), and VOID.

◆ efi_vlan_remove()

EFI_STATUS EFIAPI efi_vlan_remove ( EFI_VLAN_CONFIG_PROTOCOL * vcfg,
UINT16 tag )
static

Remove VLAN device.

Parameters
vcfgVLAN configuration protocol
tagVLAN tag
Return values
efircEFI status code

Definition at line 1610 of file efi_snp.c.

1611 {
1612 struct efi_snp_device *snpdev =
1613 container_of ( vcfg, struct efi_snp_device, vcfg );
1614 struct net_device *trunk = snpdev->netdev;
1615 struct net_device *vlan;
1616 struct efi_saved_tpl tpl;
1617 int rc;
1618
1619 /* Raise TPL */
1620 efi_raise_tpl ( &tpl );
1621
1622 /* Identify VLAN device */
1623 vlan = vlan_find ( trunk, tag );
1624 if ( ! vlan ) {
1625 DBGC ( snpdev, "SNPDEV %p could not find VLAN tag %d\n",
1626 snpdev, tag );
1627 rc = -ENOENT;
1628 goto err_find;
1629 }
1630
1631 /* Remove VLAN device */
1632 vlan_destroy ( vlan );
1633 DBGC ( snpdev, "SNPDEV %p removed VLAN tag %d\n", snpdev, tag );
1634
1635 /* Success */
1636 rc = 0;
1637
1638 err_find:
1639 efi_restore_tpl ( &tpl );
1640 return EFIRC ( rc );
1641}
#define ENOENT
No such file or directory.
Definition errno.h:515
int vlan_destroy(struct net_device *netdev)
Destroy VLAN device.
Definition vlan.c:434

References container_of, DBGC, efi_raise_tpl(), efi_restore_tpl(), EFIAPI, EFIRC, ENOENT, efi_snp_device::netdev, rc, tag, efi_snp_device::vcfg, vlan_destroy(), and vlan_find().

◆ efi_snp_get_driver_name()

EFI_STATUS EFIAPI efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL * name2,
CHAR8 *language __unused,
CHAR16 ** driver_name )
static

Look up driver name.

Parameters
name2Component name protocol
languageLanguage to use
driver_nameDriver name to fill in
Return values
efircEFI status code

Definition at line 1666 of file efi_snp.c.

1667 {
1668 struct efi_snp_device *snpdev =
1670
1671 *driver_name = snpdev->driver_name;
1672 return 0;
1673}
EFI_COMPONENT_NAME2_PROTOCOL name2
Component name protocol.
Definition efi_snp.h:59
wchar_t driver_name[16]
Driver name.
Definition efi_snp.h:75

References __unused, container_of, efi_snp_device::driver_name, and efi_snp_device::name2.

Referenced by efi_snp_probe().

◆ efi_snp_get_controller_name()

EFI_STATUS EFIAPI efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL * name2,
EFI_HANDLE device __unused,
EFI_HANDLE child __unused,
CHAR8 *language __unused,
CHAR16 ** controller_name )
static

Look up controller name.

Parameters
name2Component name protocol
deviceDevice
childChild device, or NULL
languageLanguage to use
driver_nameDevice name to fill in
Return values
efircEFI status code

Definition at line 1686 of file efi_snp.c.

1690 {
1691 struct efi_snp_device *snpdev =
1693
1695 return 0;
1696}
wchar_t controller_name[64]
Controller name.
Definition efi_snp.h:77

References __unused, container_of, efi_snp_device::controller_name, EFI_HANDLE, and efi_snp_device::name2.

Referenced by efi_snp_probe().

◆ efi_snp_load_file()

EFI_STATUS EFIAPI efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL * load_file,
EFI_DEVICE_PATH_PROTOCOL *path __unused,
BOOLEAN booting,
UINTN *len __unused,
VOID *data __unused )
static

Load file.

Parameters
loadfileLoad file protocol
pathFile path
bootingLoading as part of a boot attempt
Return values
efircEFI status code

Definition at line 1714 of file efi_snp.c.

1717 {
1718 struct efi_snp_device *snpdev =
1720 struct net_device *netdev = snpdev->netdev;
1721 int rc;
1722
1723 /* Fail unless this is a boot attempt */
1724 if ( ! booting ) {
1725 DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
1726 snpdev );
1727 return EFI_UNSUPPORTED;
1728 }
1729
1730 /* Claim network devices for use by iPXE */
1731 efi_snp_claim();
1732
1733 /* Start watchdog holdoff timer */
1735
1736 /* Boot from network device */
1737 if ( ( rc = ipxe ( netdev ) ) != 0 )
1738 goto err_ipxe;
1739
1740 /* Reset console */
1741 console_reset();
1742
1743 err_ipxe:
1746 return EFIRC ( rc );
1747}
int ipxe(struct net_device *netdev)
Main iPXE flow of execution.
Definition autoboot.c:586
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition efi_snp.h:92
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition efi_snp.h:100
static void efi_watchdog_start(void)
Start EFI watchdog holdoff timer.
static void efi_watchdog_stop(void)
Stop EFI watchdog holdoff timer.
static void console_reset(void)
Reset console.
Definition console.h:215
EFI_LOAD_FILE_PROTOCOL load_file
Load file protocol handle.
Definition efi_snp.h:61

References __unused, console_reset(), container_of, data, DBGC, efi_snp_claim(), efi_snp_release(), EFI_UNSUPPORTED, efi_watchdog_start(), efi_watchdog_stop(), EFIRC, ipxe(), len, efi_snp_device::load_file, efi_snp_device::netdev, netdev, rc, and VOID.

◆ efi_snp_demux()

struct efi_snp_device * efi_snp_demux ( struct net_device * netdev)
static

Locate SNP device corresponding to network device.

Parameters
netdevNetwork device
Return values
snpSNP device, or NULL if not found

Definition at line 1767 of file efi_snp.c.

1767 {
1768 struct efi_snp_device *snpdev;
1769
1770 list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
1771 if ( snpdev->netdev == netdev )
1772 return snpdev;
1773 }
1774 return NULL;
1775}

References efi_snp_device::list, list_for_each_entry, efi_snp_device::netdev, netdev, and NULL.

Referenced by efi_snp_notify(), efi_snp_remove(), and last_opened_snpdev().

◆ efi_snp_probe()

int efi_snp_probe ( struct net_device * netdev,
void *priv __unused )
static

Create SNP device.

Parameters
netdevNetwork device
privPrivate data
Return values
rcReturn status code

Definition at line 1784 of file efi_snp.c.

1784 {
1785 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1786 struct efi_device *efidev;
1787 struct efi_snp_device *snpdev;
1788 unsigned int ifcnt;
1789 void *interface;
1790 unsigned int tci;
1791 char vlan_name[ 12 /* ", VLAN xxxx" + NUL */ ];
1792 int leak = 0;
1793 EFI_STATUS efirc;
1794 int rc;
1795
1796 /* Allocate the SNP device */
1797 snpdev = zalloc ( sizeof ( *snpdev ) );
1798 if ( ! snpdev ) {
1799 rc = -ENOMEM;
1800 goto err_alloc_snp;
1801 }
1802 snpdev->netdev = netdev_get ( netdev );
1803 INIT_LIST_HEAD ( &snpdev->rx );
1804
1805 /* Find parent EFI device, if any */
1806 efidev = efidev_parent ( netdev->dev );
1807 if ( efidev )
1808 snpdev->parent = efidev->device;
1809
1810 /* Sanity check */
1811 if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
1812 DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
1813 "length %d for %s\n", snpdev,
1814 netdev->ll_protocol->ll_addr_len, netdev->name );
1815 rc = -ENOTSUP;
1816 goto err_ll_addr_len;
1817 }
1818
1819 /* Populate the SNP structure */
1820 memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
1821 snpdev->snp.Mode = &snpdev->mode;
1822 if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
1824 &snpdev->snp.WaitForPacket ) ) != 0 ){
1825 rc = -EEFI ( efirc );
1826 DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
1827 snpdev, strerror ( rc ) );
1828 goto err_create_event;
1829 }
1830
1831 /* Populate the SNP mode structure */
1833 efi_snp_set_mode ( snpdev );
1834
1835 /* Populate the NII structure */
1836 memcpy ( &snpdev->nii, &efi_snp_device_nii, sizeof ( snpdev->nii ) );
1837 snpdev->nii.Id = ( ( intptr_t ) &efi_snp_undi );
1838 snpdev->nii.IfNum = efi_undi_ifnum ( snpdev );
1839 efi_snp_undi.EntryPoint = ( ( intptr_t ) efi_undi_issue );
1840 ifcnt = ( ( efi_snp_undi.IFcntExt << 8 ) | efi_snp_undi.IFcnt );
1841 if ( ifcnt < snpdev->nii.IfNum )
1842 ifcnt = snpdev->nii.IfNum;
1843 efi_snp_undi.IFcnt = ( ifcnt & 0xff );
1844 efi_snp_undi.IFcntExt = ( ifcnt >> 8 );
1846 sizeof ( efi_snp_undi ) );
1847
1848 /* Populate the VLAN configuration protocol */
1849 memcpy ( &snpdev->vcfg, &efi_vlan, sizeof ( snpdev->vcfg ) );
1850
1851 /* Populate the component name structure */
1852 efi_snprintf ( snpdev->driver_name,
1853 ( sizeof ( snpdev->driver_name ) /
1854 sizeof ( snpdev->driver_name[0] ) ),
1855 "%s %s", product_short_name, netdev->dev->driver_name );
1856 tci = vlan_tci ( netdev );
1857 if ( tci ) {
1858 snprintf ( vlan_name, sizeof ( vlan_name ), ", VLAN %d",
1859 VLAN_TAG ( tci ) );
1860 } else {
1861 vlan_name[0] = '\0';
1862 }
1863 efi_snprintf ( snpdev->controller_name,
1864 ( sizeof ( snpdev->controller_name ) /
1865 sizeof ( snpdev->controller_name[0] ) ),
1866 "%s %s (%s, %s%s)", product_short_name,
1867 netdev->dev->driver_name, netdev->dev->name,
1868 netdev_addr ( netdev ), vlan_name );
1871 snpdev->name2.SupportedLanguages = "en";
1872
1873 /* Populate the load file protocol structure */
1875 sizeof ( snpdev->load_file ) );
1876
1877 /* Populate the device name */
1878 efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
1879 sizeof ( snpdev->name[0] ) ),
1880 "%s", netdev->name );
1881
1882 /* Construct device path */
1883 snpdev->path = efi_netdev_path ( netdev );
1884 if ( ! snpdev->path ) {
1885 rc = -ENOMEM;
1886 goto err_path;
1887 }
1888
1889 /* Install the SNP */
1890 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1891 &snpdev->handle,
1894 &efi_nii_protocol_guid, &snpdev->nii,
1895 &efi_nii31_protocol_guid, &snpdev->nii,
1899 NULL ) ) != 0 ) {
1900 rc = -EEFI ( efirc );
1901 DBGC ( snpdev, "SNPDEV %p could not install protocols: %s\n",
1902 snpdev, strerror ( rc ) );
1903 goto err_install_protocol_interface;
1904 }
1905
1906 /* SnpDxe will repeatedly start up and shut down our NII/UNDI
1907 * interface (in order to obtain the MAC address) before
1908 * discovering that it cannot install another SNP on the same
1909 * handle. This causes the underlying network device to be
1910 * unexpectedly closed.
1911 *
1912 * Prevent this by opening our own NII (and NII31) protocol
1913 * instances to prevent SnpDxe from attempting to bind to
1914 * them.
1915 */
1916 if ( ( rc = efi_open_by_driver ( snpdev->handle,
1918 &interface ) ) != 0 ) {
1919 DBGC ( snpdev, "SNPDEV %p could not open NII protocol: %s\n",
1920 snpdev, strerror ( rc ) );
1921 goto err_open_nii;
1922 }
1923 if ( ( rc = efi_open_by_driver ( snpdev->handle,
1925 &interface ) ) != 0 ) {
1926 DBGC ( snpdev, "SNPDEV %p could not open NII31 protocol: %s\n",
1927 snpdev, strerror ( rc ) );
1928 goto err_open_nii31;
1929 }
1930
1931 /* Add as child of EFI parent device, if applicable */
1932 if ( snpdev->parent &&
1933 ( ( rc = efi_child_add ( snpdev->parent,
1934 snpdev->handle ) ) != 0 ) ) {
1935 DBGC ( snpdev, "SNPDEV %p could not become child of %s: %s\n",
1936 snpdev, efi_handle_name ( efidev->device ),
1937 strerror ( rc ) );
1938 goto err_efi_child_add;
1939 }
1940
1941 /* Install HII */
1942 if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
1943 DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
1944 snpdev, strerror ( rc ) );
1945 /* HII fails on several platforms. It's
1946 * non-essential, so treat this as a non-fatal
1947 * error.
1948 */
1949 }
1950
1951 /* Add to list of SNP devices */
1952 list_add ( &snpdev->list, &efi_snp_devices );
1953
1954 DBGC ( snpdev, "SNPDEV %p installed for %s as device %s\n",
1955 snpdev, netdev->name, efi_handle_name ( snpdev->handle ) );
1956 return 0;
1957
1958 list_del ( &snpdev->list );
1959 if ( snpdev->package_list )
1960 leak |= efi_snp_hii_uninstall ( snpdev );
1961 if ( snpdev->parent )
1962 efi_child_del ( snpdev->parent, snpdev->handle );
1963 err_efi_child_add:
1965 err_open_nii31:
1967 err_open_nii:
1968 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1969 snpdev->handle,
1972 &efi_nii_protocol_guid, &snpdev->nii,
1973 &efi_nii31_protocol_guid, &snpdev->nii,
1977 NULL ) ) != 0 ) {
1978 DBGC ( snpdev, "SNPDEV %p could not uninstall: %s\n",
1979 snpdev, strerror ( -EEFI ( efirc ) ) );
1980 leak = 1;
1981 }
1982 efi_nullify_snp ( &snpdev->snp );
1983 efi_nullify_nii ( &snpdev->nii );
1984 efi_nullify_vlan ( &snpdev->vcfg );
1985 efi_nullify_name2 ( &snpdev->name2 );
1986 efi_nullify_load_file ( &snpdev->load_file );
1987 err_install_protocol_interface:
1988 if ( ! leak )
1989 free ( snpdev->path );
1990 err_path:
1991 bs->CloseEvent ( snpdev->snp.WaitForPacket );
1992 err_create_event:
1993 err_ll_addr_len:
1994 if ( ! leak ) {
1995 netdev_put ( netdev );
1996 free ( snpdev );
1997 }
1998 err_alloc_snp:
1999 if ( leak )
2000 DBGC ( snpdev, "SNPDEV %p nullified and leaked\n", snpdev );
2001 return rc;
2002}
#define TPL_NOTIFY
Definition UefiSpec.h:650
#define EVT_NOTIFY_WAIT
Definition UefiSpec.h:453
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
struct efi_device * efidev_parent(struct device *dev)
Get parent EFI device.
Definition efi_driver.c:129
EFI_GUID efi_component_name2_protocol_guid
Component name 2 protocol GUID.
Definition efi_guid.c:161
EFI_GUID efi_simple_network_protocol_guid
Simple network protocol GUID.
Definition efi_guid.c:341
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:169
EFI_GUID efi_vlan_config_protocol_guid
VLAN configuration protocol GUID.
Definition efi_guid.c:433
EFI_GUID efi_load_file_protocol_guid
Load file protocol GUID.
Definition efi_guid.c:265
EFI_GUID efi_nii_protocol_guid
Network interface identifier protocol GUID (old version)
Definition efi_guid.c:305
EFI_GUID efi_nii31_protocol_guid
Network interface identifier protocol GUID (new version)
Definition efi_guid.c:309
void efi_nullify_snp(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Nullify SNP interface.
Definition efi_null.c:157
void efi_nullify_nii(EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii)
Nullify NII interface.
Definition efi_null.c:192
void efi_nullify_load_file(EFI_LOAD_FILE_PROTOCOL *load_file)
Nullify Load File Protocol interface.
Definition efi_null.c:298
void efi_nullify_vlan(EFI_VLAN_CONFIG_PROTOCOL *vcfg)
Nullify VLAN configuration interface.
Definition efi_null.c:234
void efi_nullify_name2(EFI_COMPONENT_NAME2_PROTOCOL *name2)
Nullify Component Name Protocol interface.
Definition efi_null.c:273
void efi_close_by_driver(EFI_HANDLE handle, EFI_GUID *protocol)
Close protocol opened for persistent use by a driver.
Definition efi_open.c:279
EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path(struct net_device *netdev)
Construct EFI device path for network device.
Definition efi_path.c:411
static PXE_SW_UNDI efi_snp_undi
UNDI interface.
Definition efi_snp.c:1460
static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp
SNP interface.
Definition efi_snp.c:873
static EFIAPI VOID efi_undi_issue(UINT64 cdb_phys)
UNDI entry point.
Definition efi_snp.c:1356
static uint8_t efi_undi_checksum(void *data, size_t len)
Calculate UNDI byte checksum.
Definition efi_snp.c:921
static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol
Load file protocol.
Definition efi_snp.c:1750
static EFI_STATUS EFIAPI efi_snp_get_controller_name(EFI_COMPONENT_NAME2_PROTOCOL *name2, EFI_HANDLE device __unused, EFI_HANDLE child __unused, CHAR8 *language __unused, CHAR16 **controller_name)
Look up controller name.
Definition efi_snp.c:1686
static void efi_snp_set_mode(struct efi_snp_device *snpdev)
Set EFI SNP mode based on iPXE net device parameters.
Definition efi_snp.c:121
static EFI_VLAN_CONFIG_PROTOCOL efi_vlan
VLAN configuration protocol.
Definition efi_snp.c:1644
static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii
Network Identification Interface (NII)
Definition efi_snp.c:1483
static EFI_STATUS EFIAPI efi_snp_get_driver_name(EFI_COMPONENT_NAME2_PROTOCOL *name2, CHAR8 *language __unused, CHAR16 **driver_name)
Look up driver name.
Definition efi_snp.c:1666
static VOID EFIAPI efi_snp_wait_for_packet(EFI_EVENT event __unused, VOID *context)
Poll event.
Definition efi_snp.c:847
int efi_snp_hii_install(struct efi_snp_device *snpdev)
Install HII protocol and packages for SNP device.
int efi_snp_hii_uninstall(struct efi_snp_device *snpdev)
Uninstall HII protocol and package for SNP device.
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition efi_utils.c:138
int efi_child_add(EFI_HANDLE parent, EFI_HANDLE child)
Add EFI device as child of another EFI device.
Definition efi_utils.c:111
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition efi.h:474
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:565
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
static const char * netdev_addr(struct net_device *netdev)
Get printable network device link-layer address.
Definition netdevice.h:542
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
EFI_CREATE_EVENT CreateEvent
Definition UefiSpec.h:1955
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_CLOSE_EVENT CloseEvent
Definition UefiSpec.h:1959
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
UINT32 State
Reports the current state of the network interface.
EFI_COMPONENT_NAME2_GET_DRIVER_NAME GetDriverName
CHAR8 * SupportedLanguages
A Null-terminated ASCII string array that contains one or more supported language codes.
EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME GetControllerName
UINT16 IfNum
The network interface number that is being identified by this Network Interface Identifier Protocol.
UINT64 Id
The address of the first byte of the identifying structure for this network interface.
EFI_SIMPLE_NETWORK_MODE * Mode
Pointer to the EFI_SIMPLE_NETWORK_MODE data for the device.
An EFI device.
Definition efi_driver.h:18
EFI_HANDLE device
EFI device handle.
Definition efi_driver.h:22
EFI_HANDLE handle
EFI device handle.
Definition efi_snp.h:37
EFI_HANDLE parent
EFI parent device handle (if any)
Definition efi_snp.h:35
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition efi_snp.h:65
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition efi_snp.h:79
wchar_t name[sizeof(((struct net_device *) NULL) ->name)]
Device name.
Definition efi_snp.h:73
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL nii
The network interface identifier.
Definition efi_snp.h:55
An object interface.
Definition interface.h:125
const char product_short_name[]
Product short name string.
Definition version.c:77
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References __unused, EFI_BOOT_SERVICES::CloseEvent, efi_snp_device::controller_name, EFI_BOOT_SERVICES::CreateEvent, DBGC, efi_device::device, efi_snp_device::driver_name, EEFI, efi_child_add(), efi_child_del(), efi_close_by_driver(), efi_component_name2_protocol_guid, efi_device_path_protocol_guid, efi_handle_name(), efi_load_file_protocol_guid, efi_netdev_path(), efi_nii31_protocol_guid, efi_nii_protocol_guid, efi_nullify_load_file(), efi_nullify_name2(), efi_nullify_nii(), efi_nullify_snp(), efi_nullify_vlan(), efi_open_by_driver, efi_simple_network_protocol_guid, efi_snp_device_nii, efi_snp_device_snp, efi_snp_get_controller_name(), efi_snp_get_driver_name(), efi_snp_hii_install(), efi_snp_hii_uninstall(), efi_snp_load_file_protocol, efi_snp_set_mode(), efi_snp_undi, efi_snp_wait_for_packet(), efi_snprintf(), efi_systab, efi_undi_checksum(), efi_undi_ifnum(), efi_undi_issue(), efi_vlan, efi_vlan_config_protocol_guid, efidev_parent(), EfiSimpleNetworkStopped, ENOMEM, ENOTSUP, EVT_NOTIFY_WAIT, free, _EFI_COMPONENT_NAME2_PROTOCOL::GetControllerName, _EFI_COMPONENT_NAME2_PROTOCOL::GetDriverName, efi_snp_device::handle, _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL::Id, _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL::IfNum, INIT_LIST_HEAD, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, efi_snp_device::list, list_add, list_del, efi_snp_device::load_file, memcpy(), _EFI_SIMPLE_NETWORK_PROTOCOL::Mode, efi_snp_device::mode, efi_snp_device::name, efi_snp_device::name2, efi_snp_device::netdev, netdev, netdev_addr(), netdev_get(), netdev_put(), efi_snp_device::nii, NULL, efi_snp_device::package_list, efi_snp_device::parent, efi_snp_device::path, priv, product_short_name, rc, efi_snp_device::rx, efi_snp_device::snp, snprintf(), EFI_SIMPLE_NETWORK_MODE::State, strerror(), _EFI_COMPONENT_NAME2_PROTOCOL::SupportedLanguages, TPL_NOTIFY, EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, efi_snp_device::vcfg, VLAN_TAG, vlan_tci(), _EFI_SIMPLE_NETWORK_PROTOCOL::WaitForPacket, and zalloc().

◆ efi_snp_notify()

void efi_snp_notify ( struct net_device * netdev,
void *priv __unused )
static

Handle SNP device or link state change.

Parameters
netdevNetwork device
privPrivate data

Definition at line 2010 of file efi_snp.c.

2010 {
2011 struct efi_snp_device *snpdev;
2012
2013 /* Locate SNP device */
2014 snpdev = efi_snp_demux ( netdev );
2015 if ( ! snpdev ) {
2016 DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
2017 return;
2018 }
2019
2020 /* Update link state */
2021 snpdev->mode.MediaPresent =
2022 ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
2023 DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
2024 ( snpdev->mode.MediaPresent ? "up" : "down" ) );
2025
2026 /* Update mode state */
2027 efi_snp_set_state ( snpdev );
2028}
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition efi_snp.c:1767
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
BOOLEAN MediaPresent
TRUE if media are connected to the network interface; otherwise FALSE.

References __unused, DBG, DBGC, efi_snp_demux(), efi_snp_set_state(), FALSE, EFI_SIMPLE_NETWORK_MODE::MediaPresent, efi_snp_device::mode, netdev, netdev_link_ok(), priv, and TRUE.

◆ efi_snp_remove()

void efi_snp_remove ( struct net_device * netdev,
void *priv __unused )
static

Destroy SNP device.

Parameters
netdevNetwork device
privPrivate data

Definition at line 2036 of file efi_snp.c.

2036 {
2037 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
2038 struct efi_snp_device *snpdev;
2039 int leak = efi_shutdown_in_progress;
2040 EFI_STATUS efirc;
2041
2042 /* Locate SNP device */
2043 snpdev = efi_snp_demux ( netdev );
2044 if ( ! snpdev ) {
2045 DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
2046 return;
2047 }
2048
2049 /* Uninstall the SNP */
2050 list_del ( &snpdev->list );
2051 if ( snpdev->package_list )
2052 leak |= efi_snp_hii_uninstall ( snpdev );
2053 if ( snpdev->parent )
2054 efi_child_del ( snpdev->parent, snpdev->handle );
2057 if ( ( ! efi_shutdown_in_progress ) &&
2058 ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
2059 snpdev->handle,
2062 &efi_nii_protocol_guid, &snpdev->nii,
2063 &efi_nii31_protocol_guid, &snpdev->nii,
2067 NULL ) ) != 0 ) ) {
2068 DBGC ( snpdev, "SNPDEV %p could not uninstall: %s\n",
2069 snpdev, strerror ( -EEFI ( efirc ) ) );
2070 leak = 1;
2071 }
2072 efi_nullify_snp ( &snpdev->snp );
2073 efi_nullify_nii ( &snpdev->nii );
2074 efi_nullify_vlan ( &snpdev->vcfg );
2075 efi_nullify_name2 ( &snpdev->name2 );
2076 efi_nullify_load_file ( &snpdev->load_file );
2077 if ( ! leak )
2078 free ( snpdev->path );
2079 bs->CloseEvent ( snpdev->snp.WaitForPacket );
2080 if ( ! leak ) {
2081 netdev_put ( snpdev->netdev );
2082 free ( snpdev );
2083 }
2084
2085 /* Report leakage, if applicable */
2086 if ( leak && ( ! efi_shutdown_in_progress ) )
2087 DBGC ( snpdev, "SNPDEV %p nullified and leaked\n", snpdev );
2088}
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60

References __unused, EFI_BOOT_SERVICES::CloseEvent, DBG, DBGC, EEFI, efi_child_del(), efi_close_by_driver(), efi_component_name2_protocol_guid, efi_device_path_protocol_guid, efi_load_file_protocol_guid, efi_nii31_protocol_guid, efi_nii_protocol_guid, efi_nullify_load_file(), efi_nullify_name2(), efi_nullify_nii(), efi_nullify_snp(), efi_nullify_vlan(), efi_shutdown_in_progress, efi_simple_network_protocol_guid, efi_snp_demux(), efi_snp_hii_uninstall(), efi_systab, efi_vlan_config_protocol_guid, free, efi_snp_device::handle, efi_snp_device::list, list_del, efi_snp_device::load_file, efi_snp_device::name2, efi_snp_device::netdev, netdev, netdev_put(), efi_snp_device::nii, NULL, efi_snp_device::package_list, efi_snp_device::parent, efi_snp_device::path, priv, efi_snp_device::snp, strerror(), EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, efi_snp_device::vcfg, and _EFI_SIMPLE_NETWORK_PROTOCOL::WaitForPacket.

◆ find_snpdev()

struct efi_snp_device * find_snpdev ( EFI_HANDLE handle)

Find SNP device by EFI device handle.

Parameters
handleEFI device handle
Return values
snpdevSNP device, or NULL

Definition at line 2104 of file efi_snp.c.

2104 {
2105 struct efi_snp_device *snpdev;
2106
2107 list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
2108 if ( snpdev->handle == handle )
2109 return snpdev;
2110 }
2111 return NULL;
2112}
uint16_t handle
Handle.
Definition smbios.h:5

References EFI_HANDLE, efi_snp_device::handle, handle, efi_snp_device::list, list_for_each_entry, and NULL.

Referenced by snpnet_supported().

◆ last_opened_snpdev()

struct efi_snp_device * last_opened_snpdev ( void )

Get most recently opened SNP device.

Return values
snpdevMost recently opened SNP device, or NULL

Definition at line 2119 of file efi_snp.c.

2119 {
2120 struct net_device *netdev;
2121
2123 if ( ! netdev )
2124 return NULL;
2125
2126 return efi_snp_demux ( netdev );
2127}
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition netdevice.c:1048

References efi_snp_demux(), last_opened_netdev(), netdev, and NULL.

Referenced by efi_image_exec().

◆ efi_snp_add_claim()

void efi_snp_add_claim ( int delta)

Add to SNP claimed/released count.

Parameters
deltaClaim count change

Definition at line 2134 of file efi_snp.c.

2134 {
2135 struct efi_snp_device *snpdev;
2136
2137 /* Raise TPL if we are about to claim devices */
2138 if ( ! efi_snp_claimed )
2140
2141 /* Claim SNP devices */
2142 efi_snp_claimed += delta;
2143 assert ( efi_snp_claimed >= 0 );
2144
2145 /* Update SNP mode state for each interface */
2146 list_for_each_entry ( snpdev, &efi_snp_devices, list )
2147 efi_snp_set_state ( snpdev );
2148
2149 /* Restore TPL if we have released devices */
2150 if ( ! efi_snp_claimed )
2152}
static struct efi_saved_tpl efi_snp_saved_tpl
TPL prior to network devices being claimed.
Definition efi_snp.c:52

References assert, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_saved_tpl, efi_snp_set_state(), efi_snp_device::list, and list_for_each_entry.

Referenced by efi_snp_claim(), and efi_snp_release().

Variable Documentation

◆ efi_snp_claimed

◆ efi_snp_saved_tpl

struct efi_saved_tpl efi_snp_saved_tpl
static

TPL prior to network devices being claimed.

Definition at line 52 of file efi_snp.c.

Referenced by efi_snp_add_claim().

◆ efi_snp_device_snp

EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp
static
Initial value:
= {
.Start = efi_snp_start,
.Stop = efi_snp_stop,
.Initialize = efi_snp_initialize,
.Reset = efi_snp_reset,
.Shutdown = efi_snp_shutdown,
.ReceiveFilters = efi_snp_receive_filters,
.StationAddress = efi_snp_station_address,
.Statistics = efi_snp_statistics,
.MCastIpToMac = efi_snp_mcast_ip_to_mac,
.NvData = efi_snp_nvdata,
.GetStatus = efi_snp_get_status,
.Transmit = efi_snp_transmit,
.Receive = efi_snp_receive,
}
#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
static EFI_STATUS EFIAPI efi_snp_statistics(EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset, UINTN *stats_len, EFI_NETWORK_STATISTICS *stats)
Get (or reset) statistics.
Definition efi_snp.c:438
static EFI_STATUS EFIAPI efi_snp_receive_filters(EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable, UINT32 disable, BOOLEAN mcast_reset, UINTN mcast_count, EFI_MAC_ADDRESS *mcast)
Manage receive filters.
Definition efi_snp.c:367
static EFI_STATUS EFIAPI efi_snp_mcast_ip_to_mac(EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6, EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac)
Convert multicast IP address to MAC address.
Definition efi_snp.c:487
static EFI_STATUS EFIAPI efi_snp_nvdata(EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read, UINTN offset, UINTN len, VOID *data)
Read or write non-volatile storage.
Definition efi_snp.c:525

SNP interface.

Definition at line 873 of file efi_snp.c.

873 {
875 .Start = efi_snp_start,
876 .Stop = efi_snp_stop,
877 .Initialize = efi_snp_initialize,
878 .Reset = efi_snp_reset,
879 .Shutdown = efi_snp_shutdown,
880 .ReceiveFilters = efi_snp_receive_filters,
881 .StationAddress = efi_snp_station_address,
882 .Statistics = efi_snp_statistics,
883 .MCastIpToMac = efi_snp_mcast_ip_to_mac,
884 .NvData = efi_snp_nvdata,
885 .GetStatus = efi_snp_get_status,
886 .Transmit = efi_snp_transmit,
887 .Receive = efi_snp_receive,
888};

Referenced by efi_snp_probe().

◆ efi_snp_undi

PXE_SW_UNDI efi_snp_undi
static
Initial value:
= {
.Signature = PXE_ROMID_SIGNATURE,
.Len = sizeof ( efi_snp_undi ),
.MajorVer = PXE_ROMID_MAJORVER,
.MinorVer = PXE_ROMID_MINORVER,
.Implementation = ( PXE_ROMID_IMP_SW_VIRT_ADDR |
.BusCnt = 1,
.BusType[0] = PXE_BUSTYPE ( 'i', 'P', 'X', 'E' ),
}
#define PXE_ROMID_MAJORVER
UNDI command interface revision.
Definition UefiPxe.h:847
#define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
Definition UefiPxe.h:867
#define PXE_ROMID_REV
!PXE structure format revision
Definition UefiPxe.h:840
#define PXE_ROMID_SIGNATURE
Signature of !PXE structure.
Definition UefiPxe.h:835
#define PXE_ROMID_IMP_STATION_ADDR_SETTABLE
Definition UefiPxe.h:866
#define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED
Definition UefiPxe.h:873
#define PXE_BUSTYPE(a, b, c, d)
Definition UefiPxe.h:23
#define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
Definition UefiPxe.h:868
#define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
Definition UefiPxe.h:869
#define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED
Definition UefiPxe.h:872
#define PXE_ROMID_MINORVER
Definition UefiPxe.h:848
#define PXE_ROMID_IMP_SW_VIRT_ADDR
Definition UefiPxe.h:854
UINT8_t Rev
PCI revision.
Definition pxe_api.h:5

UNDI interface.

Must be aligned on a 16-byte boundary, for no particularly good reason.

Definition at line 1460 of file efi_snp.c.

1460 {
1461 .Signature = PXE_ROMID_SIGNATURE,
1462 .Len = sizeof ( efi_snp_undi ),
1463 .Rev = PXE_ROMID_REV,
1464 .MajorVer = PXE_ROMID_MAJORVER,
1465 .MinorVer = PXE_ROMID_MINORVER,
1466 .Implementation = ( PXE_ROMID_IMP_SW_VIRT_ADDR |
1473 /* SnpDxe checks that BusCnt is non-zero. It makes no further
1474 * use of BusCnt, and never looks as BusType[]. As with much
1475 * of the EDK2 code, this check seems to serve no purpose
1476 * whatsoever but must nonetheless be humoured.
1477 */
1478 .BusCnt = 1,
1479 .BusType[0] = PXE_BUSTYPE ( 'i', 'P', 'X', 'E' ),
1480};

Referenced by efi_snp_probe().

◆ efi_snp_device_nii

EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii
static
Initial value:
= {
.StringId = "UNDI",
.MajorVer = 3,
.MinorVer = 1,
.Ipv6Supported = TRUE,
}
@ EfiNetworkInterfaceUndi
#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION

Network Identification Interface (NII)

Definition at line 1483 of file efi_snp.c.

1483 {
1485 .StringId = "UNDI",
1487 .MajorVer = 3,
1488 .MinorVer = 1,
1489 .Ipv6Supported = TRUE, /* This is a raw packet interface, FFS! */
1490};

Referenced by efi_snp_probe().

◆ efi_vlan

EFI_VLAN_CONFIG_PROTOCOL efi_vlan
static
Initial value:
= {
.Set = efi_vlan_set,
.Find = efi_vlan_find,
.Remove = efi_vlan_remove,
}
static EFI_STATUS EFIAPI efi_vlan_remove(EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 tag)
Remove VLAN device.
Definition efi_snp.c:1610
static EFI_STATUS EFIAPI efi_vlan_find(EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 *filter, UINT16 *count, EFI_VLAN_FIND_DATA **entries)
Find VLAN device(s)
Definition efi_snp.c:1541
static EFI_STATUS EFIAPI efi_vlan_set(EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 tag, UINT8 priority)
Create or modify VLAN device.
Definition efi_snp.c:1507

VLAN configuration protocol.

Definition at line 1644 of file efi_snp.c.

1644 {
1645 .Set = efi_vlan_set,
1646 .Find = efi_vlan_find,
1647 .Remove = efi_vlan_remove,
1648};

Referenced by efi_snp_probe().

◆ efi_snp_load_file_protocol

EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol
static
Initial value:
= {
.LoadFile = efi_snp_load_file,
}
static EFI_STATUS EFIAPI efi_snp_load_file(EFI_LOAD_FILE_PROTOCOL *load_file, EFI_DEVICE_PATH_PROTOCOL *path __unused, BOOLEAN booting, UINTN *len __unused, VOID *data __unused)
Load file.
Definition efi_snp.c:1714

Load file protocol.

Definition at line 1750 of file efi_snp.c.

1750 {
1751 .LoadFile = efi_snp_load_file,
1752};

Referenced by efi_snp_probe().

◆ __net_driver

struct net_driver efi_snp_driver __net_driver
Initial value:
= {
.name = "SNP",
.probe = efi_snp_probe,
.notify = efi_snp_notify,
.remove = efi_snp_remove,
}
static int efi_snp_probe(struct net_device *netdev, void *priv __unused)
Create SNP device.
Definition efi_snp.c:1784
static void efi_snp_notify(struct net_device *netdev, void *priv __unused)
Handle SNP device or link state change.
Definition efi_snp.c:2010
static void efi_snp_remove(struct net_device *netdev, void *priv __unused)
Destroy SNP device.
Definition efi_snp.c:2036

SNP driver.

Definition at line 2091 of file efi_snp.c.

2091 {
2092 .name = "SNP",
2093 .probe = efi_snp_probe,
2094 .notify = efi_snp_notify,
2095 .remove = efi_snp_remove,
2096};