iPXE
Data Structures | Functions | Variables
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)
 
static LIST_HEAD (efi_snp_devices)
 List of SNP devices. More...
 
static void efi_snp_set_state (struct efi_snp_device *snpdev)
 Set EFI SNP mode state. More...
 
static void efi_snp_set_mode (struct efi_snp_device *snpdev)
 Set EFI SNP mode based on iPXE net device parameters. More...
 
static void efi_snp_flush (struct efi_snp_device *snpdev)
 Flush transmit ring and receive queue. More...
 
static void efi_snp_poll (struct efi_snp_device *snpdev)
 Poll net device and count received packets. More...
 
static EFI_STATUS EFIAPI efi_snp_start (EFI_SIMPLE_NETWORK_PROTOCOL *snp)
 Change SNP state from "stopped" to "started". More...
 
static EFI_STATUS EFIAPI efi_snp_stop (EFI_SIMPLE_NETWORK_PROTOCOL *snp)
 Change SNP state from "started" to "stopped". More...
 
static EFI_STATUS EFIAPI efi_snp_initialize (EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINTN extra_rx_bufsize, UINTN extra_tx_bufsize)
 Open the network device. More...
 
static EFI_STATUS EFIAPI efi_snp_reset (EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify)
 Reset the network device. More...
 
static EFI_STATUS EFIAPI efi_snp_shutdown (EFI_SIMPLE_NETWORK_PROTOCOL *snp)
 Shut down the network device. More...
 
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. More...
 
static EFI_STATUS EFIAPI efi_snp_station_address (EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset, EFI_MAC_ADDRESS *new)
 Set station address. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
static VOID EFIAPI efi_snp_wait_for_packet (EFI_EVENT event __unused, VOID *context)
 Poll event. More...
 
static uint8_t efi_undi_checksum (void *data, size_t len)
 Calculate UNDI byte checksum. More...
 
static unsigned int efi_undi_ifnum (struct efi_snp_device *snpdev)
 Get UNDI SNP device interface number. More...
 
static struct efi_snp_deviceefi_undi_snpdev (unsigned int ifnum)
 Identify UNDI SNP device. More...
 
static PXE_STATCODE efi_undi_statcode (EFI_STATUS efirc)
 Convert EFI status code to UNDI status code. More...
 
static EFI_STATUS efi_undi_get_state (struct efi_snp_device *snpdev, PXE_CDB *cdb)
 Get state. More...
 
static EFI_STATUS efi_undi_start (struct efi_snp_device *snpdev)
 Start. More...
 
static EFI_STATUS efi_undi_stop (struct efi_snp_device *snpdev)
 Stop. More...
 
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. More...
 
static EFI_STATUS efi_undi_initialize (struct efi_snp_device *snpdev, PXE_CDB *cdb)
 Initialise. More...
 
static EFI_STATUS efi_undi_reset (struct efi_snp_device *snpdev)
 Reset. More...
 
static EFI_STATUS efi_undi_shutdown (struct efi_snp_device *snpdev)
 Shutdown. More...
 
static EFI_STATUS efi_undi_receive_filters (struct efi_snp_device *snpdev, PXE_CDB *cdb)
 Get/set receive filters. More...
 
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. More...
 
static EFI_STATUS efi_undi_get_status (struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_DB_GET_STATUS *db)
 Get interrupt status. More...
 
static EFI_STATUS efi_undi_fill_header (struct efi_snp_device *snpdev, PXE_CDB *cdb, PXE_CPB_ANY *cpb)
 Fill header. More...
 
static EFI_STATUS efi_undi_transmit (struct efi_snp_device *snpdev, PXE_CPB_TRANSMIT *cpb)
 Transmit. More...
 
static EFI_STATUS efi_undi_receive (struct efi_snp_device *snpdev, PXE_CPB_RECEIVE *cpb, PXE_DB_RECEIVE *db)
 Receive. More...
 
static EFIAPI VOID efi_undi_issue (UINT64 cdb_phys)
 UNDI entry point. More...
 
static EFI_STATUS EFIAPI efi_vlan_set (EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 tag, UINT8 priority)
 Create or modify VLAN device. More...
 
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) More...
 
static EFI_STATUS EFIAPI efi_vlan_remove (EFI_VLAN_CONFIG_PROTOCOL *vcfg, UINT16 tag)
 Remove VLAN device. More...
 
static EFI_STATUS EFIAPI efi_snp_get_driver_name (EFI_COMPONENT_NAME2_PROTOCOL *name2, CHAR8 *language __unused, CHAR16 **driver_name)
 Look up driver name. More...
 
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. More...
 
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. More...
 
static struct efi_snp_deviceefi_snp_demux (struct net_device *netdev)
 Locate SNP device corresponding to network device. More...
 
static int efi_snp_probe (struct net_device *netdev, void *priv __unused)
 Create SNP device. More...
 
static void efi_snp_notify (struct net_device *netdev, void *priv __unused)
 Handle SNP device or link state change. More...
 
static void efi_snp_remove (struct net_device *netdev, void *priv __unused)
 Destroy SNP device. More...
 
struct efi_snp_devicefind_snpdev (EFI_HANDLE handle)
 Find SNP device by EFI device handle. More...
 
struct efi_snp_devicelast_opened_snpdev (void)
 Get most recently opened SNP device. More...
 
void efi_snp_add_claim (int delta)
 Add to SNP claimed/released count. More...
 

Variables

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

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ LIST_HEAD()

static LIST_HEAD ( efi_snp_devices  )
static

List of SNP devices.

◆ efi_snp_set_state()

static void efi_snp_set_state ( struct efi_snp_device snpdev)
static

Set EFI SNP mode state.

Parameters
snpSNP interface

Definition at line 91 of file efi_snp.c.

91  {
92  struct net_device *netdev = snpdev->netdev;
93  EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
94 
95  /* Calculate state */
96  if ( ! snpdev->started ) {
97  /* Start() method not called; report as Stopped */
99  } else if ( ! netdev_is_open ( netdev ) ) {
100  /* Network device not opened; report as Started */
102  } else if ( efi_snp_claimed ) {
103  /* Network device opened but claimed for use by iPXE; report
104  * as Started to inhibit receive polling.
105  */
107  } else {
108  /* Network device opened and available for use via SNP; report
109  * as Initialized.
110  */
112  }
113 }
int started
Started flag.
Definition: efi_snp.h:42
UINT32 State
Reports the current state of the network interface.
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:658
static struct net_device * netdev
Definition: gdbudp.c:52
A network device.
Definition: netdevice.h:352
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition: efi_snp.h:40

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

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()

static 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 120 of file efi_snp.c.

120  {
121  struct net_device *netdev = snpdev->netdev;
122  EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
124  unsigned int ll_addr_len = ll_protocol->ll_addr_len;
125 
126  mode->HwAddressSize = ll_addr_len;
128  mode->MaxPacketSize = netdev->mtu;
132  assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
136  mode->IfType = ntohs ( ll_protocol->ll_proto );
137  mode->MacAddressChangeable = TRUE;
138  mode->MediaPresentSupported = TRUE;
139  mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
140 }
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
UINT32 MediaHeaderSize
The size, in bytes, of the network interface's media header.
BOOLEAN MediaPresent
TRUE if media are connected to the network interface; otherwise FALSE.
size_t mtu
Maximum transmission unit length.
Definition: netdevice.h:415
#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
const uint8_t * ll_broadcast
Link-layer broadcast address.
Definition: netdevice.h:389
BOOLEAN MediaPresentSupported
TRUE if the presence of media can be determined; otherwise FALSE.
#define ntohs(value)
Definition: byteswap.h:136
void(* init_addr)(const void *hw_addr, void *ll_addr)
Initialise link-layer address.
Definition: netdevice.h:150
A link-layer protocol.
Definition: netdevice.h:114
EFI_MAC_ADDRESS CurrentAddress
The current HW MAC address for the network interface.
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
EFI_MAC_ADDRESS BroadcastAddress
The current HW MAC address for broadcast packets.
UINT8 IfType
The interface type of the network interface.
UINT32 MaxPacketSize
The maximum size, in bytes, of the packets supported by the network interface.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition: netdevice.h:636
static struct net_device * netdev
Definition: gdbudp.c:52
BOOLEAN MacAddressChangeable
TRUE if the HW MAC address can be changed.
#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
A network device.
Definition: netdevice.h:352
uint16_t ll_proto
Link-layer protocol.
Definition: netdevice.h:194
#define TRUE
Definition: tlan.h:46
#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
UINT32 HwAddressSize
The size, in bytes, of the network interface's HW address.
UINT32 ReceiveFilterMask
The multicast receive filter settings supported by the network interface.
#define FALSE
Definition: tlan.h:45
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition: efi_snp.h:40
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
EFI_MAC_ADDRESS PermanentAddress
The permanent HW MAC address for the network interface.

References assert(), EFI_SIMPLE_NETWORK_MODE::BroadcastAddress, EFI_SIMPLE_NETWORK_MODE::CurrentAddress, EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST, EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST, EFI_SIMPLE_NETWORK_RECEIVE_UNICAST, FALSE, net_device::hw_addr, EFI_SIMPLE_NETWORK_MODE::HwAddressSize, EFI_SIMPLE_NETWORK_MODE::IfType, ll_protocol::init_addr, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_broadcast, ll_protocol::ll_header_len, ll_protocol::ll_proto, net_device::ll_protocol, EFI_SIMPLE_NETWORK_MODE::MacAddressChangeable, EFI_SIMPLE_NETWORK_MODE::MaxPacketSize, EFI_SIMPLE_NETWORK_MODE::MediaHeaderSize, EFI_SIMPLE_NETWORK_MODE::MediaPresent, EFI_SIMPLE_NETWORK_MODE::MediaPresentSupported, memcpy(), efi_snp_device::mode, net_device::mtu, efi_snp_device::netdev, netdev, netdev_link_ok(), ntohs, EFI_SIMPLE_NETWORK_MODE::PermanentAddress, EFI_SIMPLE_NETWORK_MODE::ReceiveFilterMask, and TRUE.

Referenced by efi_snp_probe().

◆ efi_snp_flush()

static void efi_snp_flush ( struct efi_snp_device snpdev)
static

Flush transmit ring and receive queue.

Parameters
snpdevSNP device

Definition at line 147 of file efi_snp.c.

147  {
148  struct io_buffer *iobuf;
149  struct io_buffer *tmp;
150 
151  /* Reset transmit completion ring */
152  snpdev->tx_prod = 0;
153  snpdev->tx_cons = 0;
154 
155  /* Discard any queued receive buffers */
156  list_for_each_entry_safe ( iobuf, tmp, &snpdev->rx, list ) {
157  list_del ( &iobuf->list );
158  free_iob ( iobuf );
159  }
160 }
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
unsigned long tmp
Definition: linux_pci.h:53
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
unsigned int tx_cons
Transmit completion ring consumer counter.
Definition: efi_snp.h:50
#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:458
struct list_head rx
Receive queue.
Definition: efi_snp.h:52
unsigned int tx_prod
Transmit completion ring producer counter.
Definition: efi_snp.h:48
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
A persistent I/O buffer.
Definition: iobuf.h:33

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()

static void efi_snp_poll ( struct efi_snp_device snpdev)
static

Poll net device and count received packets.

Parameters
snpdevSNP device

Definition at line 167 of file efi_snp.c.

167  {
169  struct io_buffer *iobuf;
170 
171  /* Poll network device */
172  netdev_poll ( snpdev->netdev );
173 
174  /* Retrieve any received packets */
175  while ( ( iobuf = netdev_rx_dequeue ( snpdev->netdev ) ) ) {
176  list_add_tail ( &iobuf->list, &snpdev->rx );
178  bs->SignalEvent ( &snpdev->snp.WaitForPacket );
179  }
180 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
EFI_SIGNAL_EVENT SignalEvent
Definition: UefiSpec.h:1944
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
void netdev_poll(struct net_device *netdev)
Poll for completed and received packets on network device.
Definition: netdevice.c:612
EFI Boot Services Table.
Definition: UefiSpec.h:1917
struct list_head rx
Receive queue.
Definition: efi_snp.h:52
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
EFI_SYSTEM_TABLE * efi_systab
EFI_EVENT WaitForPacket
Event used with WaitForEvent() to wait for a packet to be received.
#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
unsigned int interrupts
Pending interrupt status.
Definition: efi_snp.h:44
struct io_buffer * netdev_rx_dequeue(struct net_device *netdev)
Remove packet from device's receive queue.
Definition: netdevice.c:637
A persistent I/O buffer.
Definition: iobuf.h:33

References EFI_SYSTEM_TABLE::BootServices, 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()

static 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 189 of file efi_snp.c.

189  {
190  struct efi_snp_device *snpdev =
191  container_of ( snp, struct efi_snp_device, snp );
192 
193  DBGC ( snpdev, "SNPDEV %p START\n", snpdev );
194 
195  /* Allow start even if net device is currently claimed by iPXE */
196  if ( efi_snp_claimed ) {
197  DBGC ( snpdev, "SNPDEV %p allowing start while claimed\n",
198  snpdev );
199  }
200 
201  snpdev->started = 1;
202  efi_snp_set_state ( snpdev );
203  return 0;
204 }
int started
Started flag.
Definition: efi_snp.h:42
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
An SNP device.
Definition: efi_snp.h:28

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()

static 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 213 of file efi_snp.c.

213  {
214  struct efi_snp_device *snpdev =
215  container_of ( snp, struct efi_snp_device, snp );
216 
217  DBGC ( snpdev, "SNPDEV %p STOP\n", snpdev );
218 
219  /* Fail if net device is currently claimed for use by iPXE */
220  if ( efi_snp_claimed )
221  return EFI_NOT_READY;
222 
223  snpdev->started = 0;
224  efi_snp_set_state ( snpdev );
225 
226  return 0;
227 }
int started
Started flag.
Definition: efi_snp.h:42
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
An SNP device.
Definition: efi_snp.h:28
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120

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()

static 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 238 of file efi_snp.c.

239  {
240  struct efi_snp_device *snpdev =
241  container_of ( snp, struct efi_snp_device, snp );
242  struct efi_saved_tpl tpl;
243  int rc;
244 
245  DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
246  snpdev, ( ( unsigned long ) extra_rx_bufsize ),
247  ( ( unsigned long ) extra_tx_bufsize ) );
248 
249  /* Do nothing if net device is currently claimed for use by
250  * iPXE. Do not return an error, because this will cause
251  * MnpDxe et al to fail to install the relevant child handles
252  * and to leave behind a partially initialised device handle
253  * that can cause a later system crash.
254  */
255  if ( efi_snp_claimed ) {
256  DBGC ( snpdev, "SNPDEV %p ignoring initialization while "
257  "claimed\n", snpdev );
258  return 0;
259  }
260 
261  /* Raise TPL */
262  efi_raise_tpl ( &tpl );
263 
264  /* Open network device */
265  if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
266  DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
267  snpdev, snpdev->netdev->name, strerror ( rc ) );
268  goto err_open;
269  }
270  efi_snp_set_state ( snpdev );
271 
272  err_open:
273  efi_restore_tpl ( &tpl );
274  return EFIRC ( rc );
275 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An SNP device.
Definition: efi_snp.h:28
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
An EFI saved task priority level.
Definition: efi.h:76
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:861
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

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()

static 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 285 of file efi_snp.c.

285  {
286  struct efi_snp_device *snpdev =
287  container_of ( snp, struct efi_snp_device, snp );
288  struct efi_saved_tpl tpl;
289  int rc;
290 
291  DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
292  snpdev, ( ext_verify ? "with" : "without" ) );
293 
294  /* Fail if net device is currently claimed for use by iPXE */
295  if ( efi_snp_claimed ) {
296  rc = -EAGAIN;
297  goto err_claimed;
298  }
299 
300  /* Raise TPL */
301  efi_raise_tpl ( &tpl );
302 
303  /* Close network device */
304  netdev_close ( snpdev->netdev );
305  efi_snp_set_state ( snpdev );
306  efi_snp_flush ( snpdev );
307 
308  /* Reopen network device */
309  if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
310  DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
311  snpdev, snpdev->netdev->name, strerror ( rc ) );
312  goto err_open;
313  }
314  efi_snp_set_state ( snpdev );
315 
316  err_open:
317  efi_restore_tpl ( &tpl );
318  err_claimed:
319  return EFIRC ( rc );
320 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void efi_snp_flush(struct efi_snp_device *snpdev)
Flush transmit ring and receive queue.
Definition: efi_snp.c:147
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An SNP device.
Definition: efi_snp.h:28
#define EAGAIN
Resource temporarily unavailable.
Definition: errno.h:318
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:895
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
An EFI saved task priority level.
Definition: efi.h:76
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
int netdev_open(struct net_device *netdev)
Open network device.
Definition: netdevice.c:861
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

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()

static 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 329 of file efi_snp.c.

329  {
330  struct efi_snp_device *snpdev =
331  container_of ( snp, struct efi_snp_device, snp );
332  struct efi_saved_tpl tpl;
333 
334  DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
335 
336  /* Fail if net device is currently claimed for use by iPXE */
337  if ( efi_snp_claimed )
338  return EFI_NOT_READY;
339 
340  /* Raise TPL */
341  efi_raise_tpl ( &tpl );
342 
343  /* Close network device */
344  netdev_close ( snpdev->netdev );
345  efi_snp_set_state ( snpdev );
346  efi_snp_flush ( snpdev );
347 
348  /* Restore TPL */
349  efi_restore_tpl ( &tpl );
350 
351  return 0;
352 }
static void efi_snp_flush(struct efi_snp_device *snpdev)
Flush transmit ring and receive queue.
Definition: efi_snp.c:147
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
An SNP device.
Definition: efi_snp.h:28
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
void netdev_close(struct net_device *netdev)
Close network device.
Definition: netdevice.c:895
An EFI saved task priority level.
Definition: efi.h:76
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415

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()

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 
)
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 366 of file efi_snp.c.

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

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()

static 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 400 of file efi_snp.c.

401  {
402  struct efi_snp_device *snpdev =
403  container_of ( snp, struct efi_snp_device, snp );
404  struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
405 
406  DBGC ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
407  ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
408 
409  /* Fail if net device is currently claimed for use by iPXE */
410  if ( efi_snp_claimed )
411  return EFI_NOT_READY;
412 
413  /* Set the MAC address */
414  if ( reset )
415  new = &snpdev->mode.PermanentAddress;
416  memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
417 
418  /* MAC address changes take effect only on netdev_open() */
419  if ( netdev_is_open ( snpdev->netdev ) ) {
420  DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
421  "device open\n", snpdev );
422  }
423 
424  return 0;
425 }
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
#define DBGC(...)
Definition: compiler.h:505
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
A link-layer protocol.
Definition: netdevice.h:114
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:658
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
An SNP device.
Definition: efi_snp.h:28
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition: efi_snp.h:40
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
EFI_MAC_ADDRESS PermanentAddress
The permanent HW MAC address for the network interface.

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()

static 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 437 of file efi_snp.c.

438  {
439  struct efi_snp_device *snpdev =
440  container_of ( snp, struct efi_snp_device, snp );
441  EFI_NETWORK_STATISTICS stats_buf;
442 
443  DBGC ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
444  ( reset ? " reset" : "" ) );
445 
446  /* Fail if net device is currently claimed for use by iPXE */
447  if ( efi_snp_claimed )
448  return EFI_NOT_READY;
449 
450  /* Gather statistics */
451  memset ( &stats_buf, 0, sizeof ( stats_buf ) );
452  stats_buf.TxGoodFrames = snpdev->netdev->tx_stats.good;
453  stats_buf.TxDroppedFrames = snpdev->netdev->tx_stats.bad;
454  stats_buf.TxTotalFrames = ( snpdev->netdev->tx_stats.good +
455  snpdev->netdev->tx_stats.bad );
456  stats_buf.RxGoodFrames = snpdev->netdev->rx_stats.good;
457  stats_buf.RxDroppedFrames = snpdev->netdev->rx_stats.bad;
458  stats_buf.RxTotalFrames = ( snpdev->netdev->rx_stats.good +
459  snpdev->netdev->rx_stats.bad );
460  if ( *stats_len > sizeof ( stats_buf ) )
461  *stats_len = sizeof ( stats_buf );
462  if ( stats )
463  memcpy ( stats, &stats_buf, *stats_len );
464 
465  /* Reset statistics if requested to do so */
466  if ( reset ) {
467  memset ( &snpdev->netdev->tx_stats, 0,
468  sizeof ( snpdev->netdev->tx_stats ) );
469  memset ( &snpdev->netdev->rx_stats, 0,
470  sizeof ( snpdev->netdev->rx_stats ) );
471  }
472 
473  return 0;
474 }
#define DBGC(...)
Definition: compiler.h:505
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
struct net_device_stats tx_stats
TX statistics.
Definition: netdevice.h:423
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
UINT64 RxGoodFrames
Number of valid frames received and copied into receive buffers.
Definition: SimpleNetwork.h:50
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
UINT64 TxTotalFrames
Transmit statistics.
Definition: SimpleNetwork.h:98
UINT64 RxDroppedFrames
Valid frames that were dropped because receive buffers were full.
Definition: SimpleNetwork.h:67
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
UINT64 RxTotalFrames
Total number of frames received.
Definition: SimpleNetwork.h:45
struct net_device_stats rx_stats
RX statistics.
Definition: netdevice.h:425
unsigned int bad
Count of error completions.
Definition: netdevice.h:295
An SNP device.
Definition: efi_snp.h:28
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
unsigned int good
Count of successful completions.
Definition: netdevice.h:293
Simple Network Protocol data structures.
Definition: SimpleNetwork.h:40
void * memset(void *dest, int character, size_t len) __nonnull

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()

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 
)
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 486 of file efi_snp.c.

487  {
488  struct efi_snp_device *snpdev =
489  container_of ( snp, struct efi_snp_device, snp );
490  struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
491  const char *ip_str;
492  int rc;
493 
494  ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
495  inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
496  DBGC ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
497 
498  /* Fail if net device is currently claimed for use by iPXE */
499  if ( efi_snp_claimed )
500  return EFI_NOT_READY;
501 
502  /* Try to hash the address */
503  if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
504  ip, mac ) ) != 0 ) {
505  DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
506  snpdev, ip_str, strerror ( rc ) );
507  return EFIRC ( rc );
508  }
509 
510  return 0;
511 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define AF_INET6
IPv6 Internet addresses.
Definition: socket.h:64
#define DBGC(...)
Definition: compiler.h:505
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
A link-layer protocol.
Definition: netdevice.h:114
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
IP address structure.
Definition: in.h:39
An SNP device.
Definition: efi_snp.h:28
IP4_t ip
Destination IP address.
Definition: pxe_api.h:58
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
Definition: ipv4.c:658
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
int(* mc_hash)(unsigned int af, const void *net_addr, void *ll_addr)
Hash multicast address.
Definition: netdevice.h:172
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372

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()

static 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 524 of file efi_snp.c.

525  {
526  struct efi_snp_device *snpdev =
527  container_of ( snp, struct efi_snp_device, snp );
528 
529  DBGC ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
530  ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
531  ( ( unsigned long ) len ) );
532  if ( ! read )
533  DBGC2_HDA ( snpdev, offset, data, len );
534 
535  /* Fail if net device is currently claimed for use by iPXE */
536  if ( efi_snp_claimed )
537  return EFI_NOT_READY;
538 
539  return EFI_UNSUPPORTED;
540 }
struct option_descriptor read[1]
Definition: nvo_cmd.c:115
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
#define DBGC(...)
Definition: compiler.h:505
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define DBGC2_HDA(...)
Definition: compiler.h:523
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
An SNP device.
Definition: efi_snp.h:28
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22

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

◆ efi_snp_get_status()

static 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 551 of file efi_snp.c.

552  {
553  struct efi_snp_device *snpdev =
554  container_of ( snp, struct efi_snp_device, snp );
555  struct efi_saved_tpl tpl;
556 
557  DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
558 
559  /* Fail if net device is currently claimed for use by iPXE */
560  if ( efi_snp_claimed ) {
561  DBGC2 ( snpdev, "\n" );
562  return EFI_NOT_READY;
563  }
564 
565  /* Raise TPL */
566  efi_raise_tpl ( &tpl );
567 
568  /* Poll the network device */
569  efi_snp_poll ( snpdev );
570 
571  /* Interrupt status. In practice, this seems to be used only
572  * to detect TX completions.
573  */
574  if ( interrupts ) {
575  *interrupts = snpdev->interrupts;
576  DBGC2 ( snpdev, " INTS:%02x", *interrupts );
577  snpdev->interrupts = 0;
578  }
579 
580  /* TX completions */
581  if ( txbuf ) {
582  if ( snpdev->tx_prod != snpdev->tx_cons ) {
583  *txbuf = snpdev->tx[snpdev->tx_cons++ % EFI_SNP_NUM_TX];
584  } else {
585  *txbuf = NULL;
586  }
587  DBGC2 ( snpdev, " TX:%p", *txbuf );
588  }
589 
590  /* Restore TPL */
591  efi_restore_tpl ( &tpl );
592 
593  DBGC2 ( snpdev, "\n" );
594  return 0;
595 }
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
#define EFI_SNP_NUM_TX
SNP transmit completion ring size.
Definition: efi_snp.h:25
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
unsigned int tx_cons
Transmit completion ring consumer counter.
Definition: efi_snp.h:50
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
VOID * tx[EFI_SNP_NUM_TX]
Transmit completion ring.
Definition: efi_snp.h:46
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
An SNP device.
Definition: efi_snp.h:28
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
unsigned int tx_prod
Transmit completion ring producer counter.
Definition: efi_snp.h:48
An EFI saved task priority level.
Definition: efi.h:76
#define DBGC2(...)
Definition: compiler.h:522
static void efi_snp_poll(struct efi_snp_device *snpdev)
Poll net device and count received packets.
Definition: efi_snp.c:167
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
unsigned int interrupts
Pending interrupt status.
Definition: efi_snp.h:44

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, and efi_snp_device::tx_prod.

Referenced by efi_undi_get_status().

◆ efi_snp_transmit()

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 
)
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 610 of file efi_snp.c.

613  {
614  struct efi_snp_device *snpdev =
615  container_of ( snp, struct efi_snp_device, snp );
616  struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
617  struct efi_saved_tpl tpl;
618  struct io_buffer *iobuf;
619  size_t payload_len;
620  unsigned int tx_fill;
621  int rc;
622 
623  DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
624  ( ( unsigned long ) len ) );
625  if ( ll_header_len ) {
626  if ( ll_src ) {
627  DBGC2 ( snpdev, " src %s",
628  ll_protocol->ntoa ( ll_src ) );
629  }
630  if ( ll_dest ) {
631  DBGC2 ( snpdev, " dest %s",
632  ll_protocol->ntoa ( ll_dest ) );
633  }
634  if ( net_proto ) {
635  DBGC2 ( snpdev, " proto %04x", *net_proto );
636  }
637  }
638  DBGC2 ( snpdev, "\n" );
639 
640  /* Fail if net device is currently claimed for use by iPXE */
641  if ( efi_snp_claimed ) {
642  rc = -EAGAIN;
643  goto err_claimed;
644  }
645 
646  /* Raise TPL */
647  efi_raise_tpl ( &tpl );
648 
649  /* Sanity checks */
650  if ( ll_header_len ) {
651  if ( ll_header_len != ll_protocol->ll_header_len ) {
652  DBGC ( snpdev, "SNPDEV %p TX invalid header length "
653  "%ld\n", snpdev,
654  ( ( unsigned long ) ll_header_len ) );
655  rc = -EINVAL;
656  goto err_sanity;
657  }
658  if ( len < ll_header_len ) {
659  DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
660  snpdev, ( ( unsigned long ) len ) );
661  rc = -EINVAL;
662  goto err_sanity;
663  }
664  if ( ! ll_dest ) {
665  DBGC ( snpdev, "SNPDEV %p TX missing destination "
666  "address\n", snpdev );
667  rc = -EINVAL;
668  goto err_sanity;
669  }
670  if ( ! net_proto ) {
671  DBGC ( snpdev, "SNPDEV %p TX missing network "
672  "protocol\n", snpdev );
673  rc = -EINVAL;
674  goto err_sanity;
675  }
676  if ( ! ll_src )
677  ll_src = &snpdev->mode.CurrentAddress;
678  }
679 
680  /* Allocate buffer */
681  payload_len = ( len - ll_protocol->ll_header_len );
682  iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
683  payload_len : IOB_ZLEN ) );
684  if ( ! iobuf ) {
685  DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
686  "buffer\n", snpdev, ( ( unsigned long ) len ) );
687  rc = -ENOMEM;
688  goto err_alloc_iob;
689  }
690  iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
692  memcpy ( iob_put ( iobuf, len ), data, len );
693 
694  /* Create link-layer header, if specified */
695  if ( ll_header_len ) {
696  iob_pull ( iobuf, ll_protocol->ll_header_len );
697  if ( ( rc = ll_protocol->push ( snpdev->netdev,
698  iobuf, ll_dest, ll_src,
699  htons ( *net_proto ) )) != 0 ){
700  DBGC ( snpdev, "SNPDEV %p TX could not construct "
701  "header: %s\n", snpdev, strerror ( rc ) );
702  goto err_ll_push;
703  }
704  }
705 
706  /* Transmit packet */
707  if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
708  DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
709  snpdev, strerror ( rc ) );
710  goto err_tx;
711  }
712 
713  /* Record in transmit completion ring. If we run out of
714  * space, report the failure even though we have already
715  * transmitted the packet.
716  *
717  * This allows us to report completions only for packets for
718  * which we had reported successfully initiating transmission,
719  * while continuing to support clients that never poll for
720  * transmit completions.
721  */
722  tx_fill = ( snpdev->tx_prod - snpdev->tx_cons );
723  if ( tx_fill >= EFI_SNP_NUM_TX ) {
724  DBGC ( snpdev, "SNPDEV %p TX completion ring full\n", snpdev );
725  rc = -ENOBUFS;
726  goto err_ring_full;
727  }
728  snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
730 
731  /* Restore TPL */
732  efi_restore_tpl ( &tpl );
733 
734  return 0;
735 
736  err_ring_full:
737  err_tx:
738  err_ll_push:
739  free_iob ( iobuf );
740  err_alloc_iob:
741  err_sanity:
742  efi_restore_tpl ( &tpl );
743  err_claimed:
744  return EFIRC ( rc );
745 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:120
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define DBGC(...)
Definition: compiler.h:505
#define EFI_SNP_NUM_TX
SNP transmit completion ring size.
Definition: efi_snp.h:25
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
A link-layer protocol.
Definition: netdevice.h:114
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:127
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned int tx_cons
Transmit completion ring consumer counter.
Definition: efi_snp.h:50
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition: netdevice.h:45
VOID * tx[EFI_SNP_NUM_TX]
Transmit completion ring.
Definition: efi_snp.h:46
#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
An SNP device.
Definition: efi_snp.h:28
int netdev_tx(struct net_device *netdev, struct io_buffer *iobuf)
Transmit raw packet via network device.
Definition: netdevice.c:334
#define EAGAIN
Resource temporarily unavailable.
Definition: errno.h:318
unsigned int tx_prod
Transmit completion ring producer counter.
Definition: efi_snp.h:48
#define iob_reserve(iobuf, len)
Definition: iobuf.h:67
An EFI saved task priority level.
Definition: efi.h:76
uint32_t len
Length.
Definition: ena.h:14
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
#define DBGC2(...)
Definition: compiler.h:522
#define IOB_ZLEN
Minimum I/O buffer length.
Definition: iobuf.h:24
uint8_t data[48]
Additional event data.
Definition: ena.h:22
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:163
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition: efi_snp.h:40
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
#define htons(value)
Definition: byteswap.h:135
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
unsigned int interrupts
Pending interrupt status.
Definition: efi_snp.h:44
A persistent I/O buffer.
Definition: iobuf.h:33

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, and efi_snp_device::tx_prod.

Referenced by efi_undi_transmit().

◆ efi_snp_receive()

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 
)
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 760 of file efi_snp.c.

763  {
764  struct efi_snp_device *snpdev =
765  container_of ( snp, struct efi_snp_device, snp );
766  struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
767  struct efi_saved_tpl tpl;
768  struct io_buffer *iobuf;
769  const void *iob_ll_dest;
770  const void *iob_ll_src;
771  uint16_t iob_net_proto;
772  unsigned int iob_flags;
773  size_t copy_len;
774  int rc;
775 
776  DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
777  ( ( unsigned long ) *len ) );
778 
779  /* Fail if net device is currently claimed for use by iPXE */
780  if ( efi_snp_claimed ) {
781  rc = -EAGAIN;
782  goto err_claimed;
783  }
784 
785  /* Raise TPL */
786  efi_raise_tpl ( &tpl );
787 
788  /* Poll the network device */
789  efi_snp_poll ( snpdev );
790 
791  /* Check for an available packet */
792  iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
793  if ( ! iobuf ) {
794  DBGC2 ( snpdev, "\n" );
795  rc = -EAGAIN;
796  goto out_no_packet;
797  }
798  DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
799 
800  /* Dequeue packet */
801  list_del ( &iobuf->list );
802 
803  /* Return packet to caller, truncating to buffer length */
804  copy_len = iob_len ( iobuf );
805  if ( copy_len > *len )
806  copy_len = *len;
807  memcpy ( data, iobuf->data, copy_len );
808  *len = iob_len ( iobuf );
809 
810  /* Attempt to decode link-layer header */
811  if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
812  &iob_ll_src, &iob_net_proto,
813  &iob_flags ) ) != 0 ) {
814  DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
815  snpdev, strerror ( rc ) );
816  goto out_bad_ll_header;
817  }
818 
819  /* Return link-layer header parameters to caller, if required */
820  if ( ll_header_len )
821  *ll_header_len = ll_protocol->ll_header_len;
822  if ( ll_src )
823  memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
824  if ( ll_dest )
825  memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
826  if ( net_proto )
827  *net_proto = ntohs ( iob_net_proto );
828 
829  /* Check buffer length */
830  rc = ( ( copy_len == *len ) ? 0 : -ERANGE );
831 
832  out_bad_ll_header:
833  free_iob ( iobuf );
834  out_no_packet:
835  efi_restore_tpl ( &tpl );
836  err_claimed:
837  return EFIRC ( rc );
838 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
A link-layer protocol.
Definition: netdevice.h:114
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
#define ERANGE
Result too large.
Definition: errno.h:639
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
An SNP device.
Definition: efi_snp.h:28
#define EAGAIN
Resource temporarily unavailable.
Definition: errno.h:318
struct list_head rx
Receive queue.
Definition: efi_snp.h:52
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:141
An EFI saved task priority level.
Definition: efi.h:76
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:48
static void efi_snp_poll(struct efi_snp_device *snpdev)
Poll net device and count received packets.
Definition: efi_snp.c:167
uint8_t data[48]
Additional event data.
Definition: ena.h:22
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
A persistent I/O buffer.
Definition: iobuf.h:33

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, and strerror().

Referenced by efi_undi_receive().

◆ efi_snp_wait_for_packet()

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

Poll event.

Parameters
eventEvent
contextEvent context

Definition at line 846 of file efi_snp.c.

847  {
848  struct efi_snp_device *snpdev = context;
849  struct efi_saved_tpl tpl;
850 
851  DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
852 
853  /* Do nothing unless the net device is open */
854  if ( ! netdev_is_open ( snpdev->netdev ) )
855  return;
856 
857  /* Do nothing if net device is currently claimed for use by iPXE */
858  if ( efi_snp_claimed )
859  return;
860 
861  /* Raise TPL */
862  efi_raise_tpl ( &tpl );
863 
864  /* Poll the network device */
865  efi_snp_poll ( snpdev );
866 
867  /* Restore TPL */
868  efi_restore_tpl ( &tpl );
869 }
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:658
An SNP device.
Definition: efi_snp.h:28
An EFI saved task priority level.
Definition: efi.h:76
static void efi_snp_poll(struct efi_snp_device *snpdev)
Poll net device and count received packets.
Definition: efi_snp.c:167
#define DBGCP(...)
Definition: compiler.h:539
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415

References DBGCP, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_poll(), efi_snp_device::netdev, and netdev_is_open().

Referenced by efi_snp_probe().

◆ efi_undi_checksum()

static 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 920 of file efi_snp.c.

920  {
921  uint8_t *bytes = data;
922  uint8_t sum = 0;
923 
924  while ( len-- )
925  sum += *bytes++;
926  return sum;
927 }
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t bytes[64]
Definition: ib_mad.h:16

References bytes, data, and len.

Referenced by efi_snp_probe().

◆ efi_undi_ifnum()

static 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 935 of file efi_snp.c.

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

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

Referenced by efi_snp_probe(), and efi_undi_snpdev().

◆ efi_undi_snpdev()

static 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 950 of file efi_snp.c.

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

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

Referenced by efi_undi_issue().

◆ efi_undi_statcode()

static 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 966 of file efi_snp.c.

966  {
967 
968  switch ( efirc ) {
973  case EFI_NOT_READY: return PXE_STATCODE_NO_DATA;
974  default:
976  }
977 }
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
#define EFI_PROTOCOL_ERROR
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:138
#define EFI_OUT_OF_RESOURCES
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
#define PXE_STATCODE_DEVICE_FAILURE
Definition: UefiPxe.h:615
#define PXE_STATCODE_UNSUPPORTED
Definition: UefiPxe.h:617
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
#define EFI_INVALID_PARAMETER
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:116
#define PXE_STATCODE_NO_DATA
Definition: UefiPxe.h:624
#define PXE_STATCODE_BUFFER_FULL
Definition: UefiPxe.h:618
#define PXE_STATCODE_INVALID_CDB
Definition: UefiPxe.h:606
#define PXE_STATCODE_INVALID_PARAMETER
Definition: UefiPxe.h:619

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()

static 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 986 of file efi_snp.c.

987  {
988  EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
989 
990  DBGC ( snpdev, "UNDI %p GET STATE\n", snpdev );
991 
992  /* Return current state */
995  } else if ( mode->State == EfiSimpleNetworkStarted ) {
997  } else {
999  }
1000 
1001  return 0;
1002 }
#define PXE_STATFLAGS_GET_STATE_STARTED
Definition: UefiPxe.h:425
#define DBGC(...)
Definition: compiler.h:505
UINT32 State
Reports the current state of the network interface.
PXE_STATFLAGS StatFlags
Definition: UefiPxe.h:883
#define PXE_STATFLAGS_GET_STATE_STOPPED
Definition: UefiPxe.h:426
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition: efi_snp.h:40
#define PXE_STATFLAGS_GET_STATE_INITIALIZED
Definition: UefiPxe.h:424

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

Referenced by efi_undi_issue().

◆ efi_undi_start()

static EFI_STATUS efi_undi_start ( struct efi_snp_device snpdev)
static

Start.

Parameters
snpdevSNP device
Return values
efircEFI status code

Definition at line 1010 of file efi_snp.c.

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

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

Referenced by efi_undi_issue().

◆ efi_undi_stop()

static EFI_STATUS efi_undi_stop ( struct efi_snp_device snpdev)
static

Stop.

Parameters
snpdevSNP device
Return values
efircEFI status code

Definition at line 1028 of file efi_snp.c.

1028  {
1029  EFI_STATUS efirc;
1030 
1031  DBGC ( snpdev, "UNDI %p STOP\n", snpdev );
1032 
1033  /* Stop SNP device */
1034  if ( ( efirc = efi_snp_stop ( &snpdev->snp ) ) != 0 )
1035  return efirc;
1036 
1037  return 0;
1038 }
#define DBGC(...)
Definition: compiler.h:505
static EFI_STATUS EFIAPI efi_snp_stop(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Change SNP state from "started" to "stopped".
Definition: efi_snp.c:213
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31

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

Referenced by efi_undi_issue().

◆ efi_undi_get_init_info()

static 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 1048 of file efi_snp.c.

1050  {
1051  struct net_device *netdev = snpdev->netdev;
1053 
1054  DBGC ( snpdev, "UNDI %p GET INIT INFO\n", snpdev );
1055 
1056  /* Populate structure */
1057  memset ( db, 0, sizeof ( *db ) );
1058  db->FrameDataLen = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
1059  db->MediaHeaderLen = ll_protocol->ll_header_len;
1060  db->HWaddrLen = ll_protocol->ll_addr_len;
1061  db->IFtype = ntohs ( ll_protocol->ll_proto );
1064 
1065  return 0;
1066 }
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
#define DBGC(...)
Definition: compiler.h:505
#define ntohs(value)
Definition: byteswap.h:136
A link-layer protocol.
Definition: netdevice.h:114
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
static struct net_device * netdev
Definition: gdbudp.c:52
#define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED
Definition: UefiPxe.h:439
A network device.
Definition: netdevice.h:352
#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
Definition: UefiPxe.h:443
uint16_t ll_proto
Link-layer protocol.
Definition: netdevice.h:194
static struct dmfe_private * db
Definition: dmfe.c:177
PXE_STATFLAGS StatFlags
Definition: UefiPxe.h:883
size_t max_pkt_len
Maximum packet length.
Definition: netdevice.h:409
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
void * memset(void *dest, int character, size_t len) __nonnull

References db, DBGC, ll_protocol::ll_addr_len, ll_protocol::ll_header_len, ll_protocol::ll_proto, net_device::ll_protocol, net_device::max_pkt_len, 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()

static 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 1075 of file efi_snp.c.

1076  {
1077  struct net_device *netdev = snpdev->netdev;
1078  EFI_STATUS efirc;
1079 
1080  DBGC ( snpdev, "UNDI %p INITIALIZE\n", snpdev );
1081 
1082  /* Reset SNP device */
1083  if ( ( efirc = efi_snp_initialize ( &snpdev->snp, 0, 0 ) ) != 0 )
1084  return efirc;
1085 
1086  /* Report link state */
1087  if ( ! netdev_link_ok ( netdev ) )
1089 
1090  return 0;
1091 }
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:238
#define DBGC(...)
Definition: compiler.h:505
#define PXE_STATFLAGS_INITIALIZED_NO_MEDIA
UNDI Initialize.
Definition: UefiPxe.h:448
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition: netdevice.h:636
static struct net_device * netdev
Definition: gdbudp.c:52
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
A network device.
Definition: netdevice.h:352
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
PXE_STATFLAGS StatFlags
Definition: UefiPxe.h:883

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()

static EFI_STATUS efi_undi_reset ( struct efi_snp_device snpdev)
static

Reset.

Parameters
snpdevSNP device
efircEFI status code

Definition at line 1099 of file efi_snp.c.

1099  {
1100  EFI_STATUS efirc;
1101 
1102  DBGC ( snpdev, "UNDI %p RESET\n", snpdev );
1103 
1104  /* Reset SNP device */
1105  if ( ( efirc = efi_snp_reset ( &snpdev->snp, 0 ) ) != 0 )
1106  return efirc;
1107 
1108  return 0;
1109 }
#define DBGC(...)
Definition: compiler.h:505
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
static EFI_STATUS EFIAPI efi_snp_reset(EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify)
Reset the network device.
Definition: efi_snp.c:285

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

Referenced by efi_undi_issue().

◆ efi_undi_shutdown()

static EFI_STATUS efi_undi_shutdown ( struct efi_snp_device snpdev)
static

Shutdown.

Parameters
snpdevSNP device
efircEFI status code

Definition at line 1117 of file efi_snp.c.

1117  {
1118  EFI_STATUS efirc;
1119 
1120  DBGC ( snpdev, "UNDI %p SHUTDOWN\n", snpdev );
1121 
1122  /* Reset SNP device */
1123  if ( ( efirc = efi_snp_shutdown ( &snpdev->snp ) ) != 0 )
1124  return efirc;
1125 
1126  return 0;
1127 }
#define DBGC(...)
Definition: compiler.h:505
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
static EFI_STATUS EFIAPI efi_snp_shutdown(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Shut down the network device.
Definition: efi_snp.c:329
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31

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

Referenced by efi_undi_issue().

◆ efi_undi_receive_filters()

static 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 1136 of file efi_snp.c.

1137  {
1138 
1139  DBGC ( snpdev, "UNDI %p RECEIVE FILTERS\n", snpdev );
1140 
1141  /* Mark everything as supported */
1146 
1147  return 0;
1148 }
#define DBGC(...)
Definition: compiler.h:505
#define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST
UNDI Receive Filters.
Definition: UefiPxe.h:485
#define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST
If set, all multicast packets will be received.
Definition: UefiPxe.h:506
PXE_STATFLAGS StatFlags
Definition: UefiPxe.h:883
#define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST
If set, broadcast packets will be received.
Definition: UefiPxe.h:490
#define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS
If set, all packets will be received.
Definition: UefiPxe.h:501

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()

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 
)
static

Get/set station address.

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

Definition at line 1158 of file efi_snp.c.

1161  {
1162  struct net_device *netdev = snpdev->netdev;
1164  void *mac;
1165  int reset;
1166  EFI_STATUS efirc;
1167 
1168  DBGC ( snpdev, "UNDI %p STATION ADDRESS\n", snpdev );
1169 
1170  /* Update address if applicable */
1171  reset = ( cdb->OpFlags & PXE_OPFLAGS_STATION_ADDRESS_RESET );
1172  mac = ( cpb ? &cpb->StationAddr : NULL );
1173  if ( ( reset || mac ) &&
1174  ( ( efirc = efi_snp_station_address ( &snpdev->snp, reset,
1175  mac ) ) != 0 ) )
1176  return efirc;
1177 
1178  /* Fill in current addresses, if applicable */
1179  if ( db ) {
1180  memset ( db, 0, sizeof ( *db ) );
1181  memcpy ( &db->StationAddr, netdev->ll_addr,
1183  memcpy ( &db->BroadcastAddr, netdev->ll_broadcast,
1185  memcpy ( &db->PermanentAddr, netdev->hw_addr,
1187  }
1188 
1189  return 0;
1190 }
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
PXE_OPFLAGS OpFlags
Definition: UefiPxe.h:877
#define DBGC(...)
Definition: compiler.h:505
const uint8_t * ll_broadcast
Link-layer broadcast address.
Definition: netdevice.h:389
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:400
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
PXE_MAC_ADDR StationAddr
If supplied and supported, the current station MAC address will be changed.
Definition: UefiPxe.h:1338
A link-layer protocol.
Definition: netdevice.h:114
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t hw_addr_len
Hardware address length.
Definition: netdevice.h:196
static struct net_device * netdev
Definition: gdbudp.c:52
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
A network device.
Definition: netdevice.h:352
#define PXE_OPFLAGS_STATION_ADDRESS_RESET
Definition: UefiPxe.h:317
static struct dmfe_private * db
Definition: dmfe.c:177
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
void * memset(void *dest, int character, size_t len) __nonnull

References db, DBGC, efi_snp_station_address(), net_device::hw_addr, ll_protocol::hw_addr_len, net_device::ll_addr, ll_protocol::ll_addr_len, net_device::ll_broadcast, net_device::ll_protocol, 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()

static 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 1200 of file efi_snp.c.

1201  {
1202  UINT32 interrupts;
1203  VOID *txbuf;
1204  struct io_buffer *rxbuf;
1205  EFI_STATUS efirc;
1206 
1207  DBGC2 ( snpdev, "UNDI %p GET STATUS\n", snpdev );
1208 
1209  /* Get status */
1210  if ( ( efirc = efi_snp_get_status ( &snpdev->snp, &interrupts,
1211  &txbuf ) ) != 0 )
1212  return efirc;
1213 
1214  /* Report status */
1215  memset ( db, 0, sizeof ( *db ) );
1216  if ( interrupts & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT )
1218  if ( interrupts & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT )
1220  if ( txbuf ) {
1221  db->TxBuffer[0] = ( ( intptr_t ) txbuf );
1222  } else {
1224  /* The specification states clearly that UNDI drivers
1225  * should set TXBUF_QUEUE_EMPTY if all completed
1226  * buffer addresses are written into the returned data
1227  * block. However, SnpDxe chooses to interpret
1228  * TXBUF_QUEUE_EMPTY as a synonym for
1229  * NO_TXBUFS_WRITTEN, thereby rendering it entirely
1230  * pointless. Work around this UEFI stupidity, as per
1231  * usual.
1232  */
1233  if ( snpdev->tx_prod == snpdev->tx_cons )
1234  cdb->StatFlags |=
1236  }
1237  rxbuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
1238  if ( rxbuf )
1239  db->RxFrameLen = iob_len ( rxbuf );
1240  if ( ! netdev_link_ok ( snpdev->netdev ) )
1242 
1243  return 0;
1244 }
#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:571
unsigned int UINT32
Definition: ProcessorBind.h:98
unsigned long intptr_t
Definition: stdint.h:21
#define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY
This flag is set if the transmitted buffer queue is empty.
Definition: UefiPxe.h:565
#define PXE_STATFLAGS_GET_STATUS_RECEIVE
If set, at least one receive interrupt occurred.
Definition: UefiPxe.h:544
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define list_first_entry(list, type, member)
Get the container of the first entry in a list.
Definition: list.h:333
unsigned int tx_cons
Transmit completion ring consumer counter.
Definition: efi_snp.h:50
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition: netdevice.h:636
#define EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA
This flag is set if there is no media detected.
Definition: UefiPxe.h:576
#define VOID
Undeclared type.
Definition: Base.h:271
struct list_head rx
Receive queue.
Definition: efi_snp.h:52
unsigned int tx_prod
Transmit completion ring producer counter.
Definition: efi_snp.h:48
static struct dmfe_private * db
Definition: dmfe.c:177
struct list_head list
List of which this buffer is a member.
Definition: iobuf.h:40
#define DBGC2(...)
Definition: compiler.h:522
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:551
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
PXE_STATFLAGS StatFlags
Definition: UefiPxe.h:883
#define PXE_STATFLAGS_GET_STATUS_TRANSMIT
If set, at least one transmit interrupt occurred.
Definition: UefiPxe.h:549
#define EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33

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()

static 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 1254 of file efi_snp.c.

1255  {
1256  struct net_device *netdev = snpdev->netdev;
1258  PXE_CPB_FILL_HEADER *whole = &cpb->fill_header;
1260  VOID *data;
1261  void *dest;
1262  void *src;
1263  uint16_t proto;
1264  struct io_buffer iobuf;
1265  int rc;
1266 
1267  /* SnpDxe will (pointlessly) use PXE_CPB_FILL_HEADER_FRAGMENTED
1268  * even though we choose to explicitly not claim support for
1269  * fragments via PXE_ROMID_IMP_FRAG_SUPPORTED.
1270  */
1272  data = ( ( void * ) ( intptr_t ) fragged->FragDesc[0].FragAddr);
1273  dest = &fragged->DestAddr;
1274  src = &fragged->SrcAddr;
1275  proto = fragged->Protocol;
1276  } else {
1277  data = ( ( void * ) ( intptr_t ) whole->MediaHeader );
1278  dest = &whole->DestAddr;
1279  src = &whole->SrcAddr;
1280  proto = whole->Protocol;
1281  }
1282 
1283  /* Construct link-layer header */
1284  iob_populate ( &iobuf, data, 0, ll_protocol->ll_header_len );
1285  iob_reserve ( &iobuf, ll_protocol->ll_header_len );
1286  if ( ( rc = ll_protocol->push ( netdev, &iobuf, dest, src,
1287  proto ) ) != 0 )
1288  return EFIRC ( rc );
1289 
1290  return 0;
1291 }
PXE_UINT16 Protocol
Protocol type.
Definition: UefiPxe.h:1594
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
struct s_pxe_cpb_fill_header_fragmented::@544 FragDesc[MAX_XMIT_FRAGMENTS]
Array of packet fragment descriptors.
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
PXE_MAC_ADDR SrcAddr
Source and destination MAC addresses.
Definition: UefiPxe.h:1611
static void const void * src
Definition: crypto.h:244
PXE_OPFLAGS OpFlags
Definition: UefiPxe.h:877
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:190
unsigned long intptr_t
Definition: stdint.h:21
PXE_MAC_ADDR DestAddr
Definition: UefiPxe.h:1576
PXE_MAC_ADDR SrcAddr
Source and destination MAC addresses.
Definition: UefiPxe.h:1575
A link-layer protocol.
Definition: netdevice.h:114
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:127
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
PXE_CPB_FILL_HEADER_FRAGMENTED fill_header_fragmented
Definition: efi_snp.c:900
PXE_MEDIA_PROTOCOL Protocol
Protocol type.
Definition: UefiPxe.h:1624
static struct net_device * netdev
Definition: gdbudp.c:52
static void * dest
Definition: strings.h:176
#define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED
Definition: UefiPxe.h:375
A network device.
Definition: netdevice.h:352
PXE_CPB_FILL_HEADER fill_header
Definition: efi_snp.c:899
#define VOID
Undeclared type.
Definition: Base.h:271
#define iob_reserve(iobuf, len)
Definition: iobuf.h:67
PXE_UINT64 MediaHeader
Address of first byte of media header.
Definition: UefiPxe.h:1582
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
PXE_UINT64 FragAddr
Address of this packet fragment.
Definition: UefiPxe.h:1649
A persistent I/O buffer.
Definition: iobuf.h:33

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, net_device::ll_protocol, 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()

static 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 1300 of file efi_snp.c.

1301  {
1302  VOID *data = ( ( void * ) ( intptr_t ) cpb->FrameAddr );
1303  EFI_STATUS efirc;
1304 
1305  DBGC2 ( snpdev, "UNDI %p TRANSMIT\n", snpdev );
1306 
1307  /* Transmit packet */
1308  if ( ( efirc = efi_snp_transmit ( &snpdev->snp, 0, cpb->DataLen,
1309  data, NULL, NULL, NULL ) ) != 0 )
1310  return efirc;
1311 
1312  return 0;
1313 }
PXE_UINT32 DataLen
Length of the data portion of the frame buffer in bytes.
Definition: UefiPxe.h:1674
unsigned long intptr_t
Definition: stdint.h:21
PXE_UINT64 FrameAddr
Address of first byte of frame buffer.
Definition: UefiPxe.h:1668
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:610
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
#define VOID
Undeclared type.
Definition: Base.h:271
#define DBGC2(...)
Definition: compiler.h:522
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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()

static 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 1322 of file efi_snp.c.

1324  {
1325  struct net_device *netdev = snpdev->netdev;
1327  VOID *data = ( ( void * ) ( intptr_t ) cpb->BufferAddr );
1328  UINTN hdr_len;
1329  UINTN len = cpb->BufferLen;
1332  UINT16 proto;
1333  EFI_STATUS efirc;
1334 
1335  DBGC2 ( snpdev, "UNDI %p RECEIVE\n", snpdev );
1336 
1337  /* Receive packet */
1338  if ( ( efirc = efi_snp_receive ( &snpdev->snp, &hdr_len, &len, data,
1339  &src, &dest, &proto ) ) != 0 )
1340  return efirc;
1341 
1342  /* Describe frame */
1343  memset ( db, 0, sizeof ( *db ) );
1344  memcpy ( &db->SrcAddr, &src, ll_protocol->ll_addr_len );
1345  memcpy ( &db->DestAddr, &dest, ll_protocol->ll_addr_len );
1346  db->FrameLen = len;
1347  db->Protocol = proto;
1348  db->MediaHeaderLen = ll_protocol->ll_header_len;
1350 
1351  return 0;
1352 }
PXE_UINT32 BufferLen
Length of receive buffer.
Definition: UefiPxe.h:1737
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
32-byte buffer containing a network Media Access Control address.
Definition: UefiBaseType.h:97
static void const void * src
Definition: crypto.h:244
unsigned long intptr_t
Definition: stdint.h:21
A link-layer protocol.
Definition: netdevice.h:114
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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:760
static struct net_device * netdev
Definition: gdbudp.c:52
static void * dest
Definition: strings.h:176
unsigned short UINT16
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
PXE_UINT64 BufferAddr
Address of first byte of receive buffer.
Definition: UefiPxe.h:1730
A network device.
Definition: netdevice.h:352
UINT64 UINTN
Unsigned value of native width.
#define VOID
Undeclared type.
Definition: Base.h:271
static struct dmfe_private * db
Definition: dmfe.c:177
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define PXE_FRAME_TYPE_PROMISCUOUS
Definition: UefiPxe.h:666
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
void * memset(void *dest, int character, size_t len) __nonnull

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, net_device::ll_protocol, 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()

static EFIAPI VOID efi_undi_issue ( UINT64  cdb_phys)
static

UNDI entry point.

Definition at line 1355 of file efi_snp.c.

1355  {
1356  PXE_CDB *cdb = ( ( void * ) ( intptr_t ) cdb_phys );
1357  PXE_CPB_ANY *cpb = ( ( void * ) ( intptr_t ) cdb->CPBaddr );
1358  PXE_DB_ANY *db = ( ( void * ) ( intptr_t ) cdb->DBaddr );
1359  struct efi_snp_device *snpdev;
1360  EFI_STATUS efirc;
1361 
1362  /* Identify device */
1363  snpdev = efi_undi_snpdev ( cdb->IFnum );
1364  if ( ! snpdev ) {
1365  DBGC ( cdb, "UNDI invalid interface number %d\n", cdb->IFnum );
1368  return;
1369  }
1370 
1371  /* Fail if net device is currently claimed for use by iPXE */
1372  if ( efi_snp_claimed ) {
1373  cdb->StatCode = PXE_STATCODE_BUSY;
1375  return;
1376  }
1377 
1378  /* Handle opcode */
1381  switch ( cdb->OpCode ) {
1382 
1383  case PXE_OPCODE_GET_STATE:
1384  efirc = efi_undi_get_state ( snpdev, cdb );
1385  break;
1386 
1387  case PXE_OPCODE_START:
1388  efirc = efi_undi_start ( snpdev );
1389  break;
1390 
1391  case PXE_OPCODE_STOP:
1392  efirc = efi_undi_stop ( snpdev );
1393  break;
1394 
1396  efirc = efi_undi_get_init_info ( snpdev, cdb,
1397  &db->get_init_info );
1398  break;
1399 
1400  case PXE_OPCODE_INITIALIZE:
1401  efirc = efi_undi_initialize ( snpdev, cdb );
1402  break;
1403 
1404  case PXE_OPCODE_RESET:
1405  efirc = efi_undi_reset ( snpdev );
1406  break;
1407 
1408  case PXE_OPCODE_SHUTDOWN:
1409  efirc = efi_undi_shutdown ( snpdev );
1410  break;
1411 
1413  efirc = efi_undi_receive_filters ( snpdev, cdb );
1414  break;
1415 
1417  efirc = efi_undi_station_address ( snpdev, cdb,
1418  &cpb->station_address,
1419  &db->station_address );
1420  break;
1421 
1422  case PXE_OPCODE_GET_STATUS:
1423  efirc = efi_undi_get_status ( snpdev, cdb, &db->get_status );
1424  break;
1425 
1427  efirc = efi_undi_fill_header ( snpdev, cdb, cpb );
1428  break;
1429 
1430  case PXE_OPCODE_TRANSMIT:
1431  efirc = efi_undi_transmit ( snpdev, &cpb->transmit );
1432  break;
1433 
1434  case PXE_OPCODE_RECEIVE:
1435  efirc = efi_undi_receive ( snpdev, &cpb->receive,
1436  &db->receive );
1437  break;
1438 
1439  default:
1440  DBGC ( snpdev, "UNDI %p unsupported opcode %#04x\n",
1441  snpdev, cdb->OpCode );
1442  efirc = EFI_UNSUPPORTED;
1443  break;
1444  }
1445 
1446  /* Convert EFI status code to UNDI status code */
1447  if ( efirc != 0 ) {
1450  cdb->StatCode = efi_undi_statcode ( efirc );
1451  }
1452 }
static EFI_STATUS efi_undi_shutdown(struct efi_snp_device *snpdev)
Shutdown.
Definition: efi_snp.c:1117
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
static PXE_STATCODE efi_undi_statcode(EFI_STATUS efirc)
Convert EFI status code to UNDI status code.
Definition: efi_snp.c:966
static EFI_STATUS efi_undi_get_state(struct efi_snp_device *snpdev, PXE_CDB *cdb)
Get state.
Definition: efi_snp.c:986
#define PXE_OPCODE_SHUTDOWN
Change the UNDI operational state from Initialized to Started.
Definition: UefiPxe.h:122
PXE_STATCODE StatCode
Definition: UefiPxe.h:882
static EFI_STATUS efi_undi_receive_filters(struct efi_snp_device *snpdev, PXE_CDB *cdb)
Get/set receive filters.
Definition: efi_snp.c:1136
static EFI_STATUS efi_undi_transmit(struct efi_snp_device *snpdev, PXE_CPB_TRANSMIT *cpb)
Transmit.
Definition: efi_snp.c:1300
#define DBGC(...)
Definition: compiler.h:505
#define PXE_STATFLAGS_COMMAND_FAILED
Definition: UefiPxe.h:417
#define PXE_OPCODE_INITIALIZE
Changed UNDI operational state from Started to Initialized.
Definition: UefiPxe.h:112
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:1048
#define PXE_STATCODE_BUSY
Definition: UefiPxe.h:608
unsigned long intptr_t
Definition: stdint.h:21
#define PXE_OPCODE_FILL_HEADER
Fill media header in packet for transmit.
Definition: UefiPxe.h:162
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
PXE_CPB_RECEIVE receive
Definition: efi_snp.c:902
static EFI_STATUS efi_undi_stop(struct efi_snp_device *snpdev)
Stop.
Definition: efi_snp.c:1028
#define PXE_OPCODE_STATION_ADDRESS
Read & change station MAC address.
Definition: UefiPxe.h:137
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:1158
static EFI_STATUS efi_undi_reset(struct efi_snp_device *snpdev)
Reset.
Definition: efi_snp.c:1099
#define PXE_OPCODE_RESET
Re-initialize the NIC H/W.
Definition: UefiPxe.h:117
#define PXE_OPCODE_TRANSMIT
Transmit packet(s).
Definition: UefiPxe.h:167
#define PXE_STATFLAGS_STATUS_MASK
Common StatFlags that can be returned by all commands.
Definition: UefiPxe.h:415
PXE_CPB_STATION_ADDRESS station_address
Definition: efi_snp.c:898
PXE_UINT64 CPBaddr
Definition: UefiPxe.h:880
static EFI_STATUS efi_undi_receive(struct efi_snp_device *snpdev, PXE_CPB_RECEIVE *cpb, PXE_DB_RECEIVE *db)
Receive.
Definition: efi_snp.c:1322
static struct efi_snp_device * efi_undi_snpdev(unsigned int ifnum)
Identify UNDI SNP device.
Definition: efi_snp.c:950
Union type for data blocks.
Definition: efi_snp.c:906
An SNP device.
Definition: efi_snp.h:28
PXE_CPB_TRANSMIT transmit
Definition: efi_snp.c:901
#define PXE_OPCODE_STOP
Change UNDI operational state from Started to Stopped.
Definition: UefiPxe.h:97
#define PXE_OPCODE_GET_STATUS
Get & clear interrupt status.
Definition: UefiPxe.h:157
static struct dmfe_private * db
Definition: dmfe.c:177
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:1254
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:1200
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
PXE_STATFLAGS StatFlags
Definition: UefiPxe.h:883
#define PXE_OPCODE_RECEIVE
Receive packet.
Definition: UefiPxe.h:172
#define PXE_OPCODE_RECEIVE_FILTERS
Read & change state of packet receive filters.
Definition: UefiPxe.h:132
#define PXE_STATCODE_INVALID_CDB
Definition: UefiPxe.h:606
#define PXE_OPCODE_GET_STATE
Return UNDI operational state.
Definition: UefiPxe.h:87
#define PXE_OPCODE_GET_INIT_INFO
Get UNDI initialization information.
Definition: UefiPxe.h:102
static EFI_STATUS efi_undi_initialize(struct efi_snp_device *snpdev, PXE_CDB *cdb)
Initialise.
Definition: efi_snp.c:1075
PXE_UINT16 IFnum
Definition: UefiPxe.h:884
#define PXE_OPCODE_START
Change UNDI operational state from Stopped to Started.
Definition: UefiPxe.h:92
PXE_OPCODE OpCode
Definition: UefiPxe.h:876
#define PXE_STATFLAGS_COMMAND_COMPLETE
Definition: UefiPxe.h:416
Union type for command parameter blocks.
Definition: efi_snp.c:897
PXE_UINT64 DBaddr
Definition: UefiPxe.h:881
#define PXE_STATCODE_SUCCESS
Common StatCodes returned by all UNDI commands, UNDI protocol functions and BC protocol functions.
Definition: UefiPxe.h:604
static EFI_STATUS efi_undi_start(struct efi_snp_device *snpdev)
Start.
Definition: efi_snp.c:1010

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, 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, and PXE_CPB_ANY::transmit.

Referenced by efi_snp_probe().

◆ efi_vlan_set()

static 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 1506 of file efi_snp.c.

1507  {
1508  struct efi_snp_device *snpdev =
1509  container_of ( vcfg, struct efi_snp_device, vcfg );
1510  struct net_device *trunk = snpdev->netdev;
1511  struct efi_saved_tpl tpl;
1512  int rc;
1513 
1514  /* Raise TPL */
1515  efi_raise_tpl ( &tpl );
1516 
1517  /* Create or modify VLAN device */
1518  if ( ( rc = vlan_create ( trunk, tag, priority ) ) != 0 ) {
1519  DBGC ( snpdev, "SNPDEV %p could not create VLAN tag %d: %s\n",
1520  snpdev, tag, strerror ( rc ) );
1521  goto err_create;
1522  }
1523  DBGC ( snpdev, "SNPDEV %p created VLAN tag %d priority %d\n",
1524  snpdev, tag, priority );
1525 
1526  err_create:
1527  efi_restore_tpl ( &tpl );
1528  return EFIRC ( rc );
1529 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_VLAN_CONFIG_PROTOCOL vcfg
VLAN configuration protocol.
Definition: efi_snp.h:56
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
#define DBGC(...)
Definition: compiler.h:505
int vlan_create(struct net_device *trunk, unsigned int tag, unsigned int priority)
Create VLAN device.
Definition: vlan.c:343
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A network device.
Definition: netdevice.h:352
An SNP device.
Definition: efi_snp.h:28
An EFI saved task priority level.
Definition: efi.h:76
uint16_t priority
Priotity.
Definition: stp.h:12
uint64_t tag
Identity tag.
Definition: edd.h:30
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

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

◆ efi_vlan_find()

static 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 1540 of file efi_snp.c.

1542  {
1544  struct efi_snp_device *snpdev =
1545  container_of ( vcfg, struct efi_snp_device, vcfg );
1546  struct net_device *trunk = snpdev->netdev;
1547  struct net_device *vlan;
1548  struct efi_saved_tpl tpl;
1550  VOID *buffer;
1551  unsigned int tag;
1552  unsigned int tci;
1553  size_t len;
1554  EFI_STATUS efirc;
1555  int rc;
1556 
1557  /* Raise TPL */
1558  efi_raise_tpl ( &tpl );
1559 
1560  /* Count number of matching VLANs */
1561  *count = 0;
1562  for ( tag = 1 ; VLAN_TAG_IS_VALID ( tag ) ; tag++ ) {
1563  if ( filter && ( tag != *filter ) )
1564  continue;
1565  if ( ! ( vlan = vlan_find ( trunk, tag ) ) )
1566  continue;
1567  (*count)++;
1568  }
1569 
1570  /* Allocate buffer to hold results */
1571  len = ( (*count) * sizeof ( *entry ) );
1572  if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
1573  &buffer ) ) != 0 ) {
1574  rc = -EEFI ( efirc );
1575  goto err_alloc;
1576  }
1577 
1578  /* Fill in buffer */
1579  *entries = buffer;
1580  entry = *entries;
1581  for ( tag = 1 ; VLAN_TAG_IS_VALID ( tag ) ; tag++ ) {
1582  if ( filter && ( tag != *filter ) )
1583  continue;
1584  if ( ! ( vlan = vlan_find ( trunk, tag ) ) )
1585  continue;
1586  tci = vlan_tci ( vlan );
1587  entry->VlanId = VLAN_TAG ( tci );
1588  entry->Priority = VLAN_PRIORITY ( tci );
1589  assert ( entry->VlanId == tag );
1590  entry++;
1591  }
1592  assert ( entry == &(*entries)[*count] );
1593 
1594  /* Success */
1595  rc = 0;
1596 
1597  err_alloc:
1598  efi_restore_tpl ( &tpl );
1599  return EFIRC ( rc );
1600 }
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition: vlan.h:29
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
EFI_VLAN_CONFIG_PROTOCOL vcfg
VLAN configuration protocol.
Definition: efi_snp.h:56
UINT8_t filter
Receive packet filter.
Definition: pxe_api.h:68
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
#define VLAN_TAG_IS_VALID(tag)
Check VLAN tag is valid.
Definition: vlan.h:54
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:208
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_VLAN_FIND_DATA.
Definition: VlanConfig.h:27
A network device.
Definition: netdevice.h:352
An SNP device.
Definition: efi_snp.h:28
#define VOID
Undeclared type.
Definition: Base.h:271
An EFI saved task priority level.
Definition: efi.h:76
uint32_t len
Length.
Definition: ena.h:14
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
uint16_t count
Number of entries.
Definition: ena.h:22
__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:1198
EFI_SYSTEM_TABLE * efi_systab
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
uint64_t tag
Identity tag.
Definition: edd.h:30
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
#define VLAN_PRIORITY(tci)
Extract VLAN priority from tag control information.
Definition: vlan.h:37
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
EFI_ALLOCATE_POOL AllocatePool
Definition: UefiSpec.h:1935

References EFI_BOOT_SERVICES::AllocatePool, assert(), EFI_SYSTEM_TABLE::BootServices, buffer, container_of, count, EEFI, efi_raise_tpl(), efi_restore_tpl(), efi_systab, EfiBootServicesData, EFIRC, entry, 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()

static 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 1609 of file efi_snp.c.

1610  {
1611  struct efi_snp_device *snpdev =
1612  container_of ( vcfg, struct efi_snp_device, vcfg );
1613  struct net_device *trunk = snpdev->netdev;
1614  struct net_device *vlan;
1615  struct efi_saved_tpl tpl;
1616  int rc;
1617 
1618  /* Raise TPL */
1619  efi_raise_tpl ( &tpl );
1620 
1621  /* Identify VLAN device */
1622  vlan = vlan_find ( trunk, tag );
1623  if ( ! vlan ) {
1624  DBGC ( snpdev, "SNPDEV %p could not find VLAN tag %d\n",
1625  snpdev, tag );
1626  rc = -ENOENT;
1627  goto err_find;
1628  }
1629 
1630  /* Remove VLAN device */
1631  vlan_destroy ( vlan );
1632  DBGC ( snpdev, "SNPDEV %p removed VLAN tag %d\n", snpdev, tag );
1633 
1634  /* Success */
1635  rc = 0;
1636 
1637  err_find:
1638  efi_restore_tpl ( &tpl );
1639  return EFIRC ( rc );
1640 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
EFI_VLAN_CONFIG_PROTOCOL vcfg
VLAN configuration protocol.
Definition: efi_snp.h:56
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
struct net_device * vlan_find(struct net_device *trunk, unsigned int tag)
Identify VLAN device.
Definition: vlan.c:208
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
A network device.
Definition: netdevice.h:352
An SNP device.
Definition: efi_snp.h:28
int vlan_destroy(struct net_device *netdev)
Destroy VLAN device.
Definition: vlan.c:433
An EFI saved task priority level.
Definition: efi.h:76
uint64_t tag
Identity tag.
Definition: edd.h:30
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

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

◆ efi_snp_get_driver_name()

static 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 1665 of file efi_snp.c.

1666  {
1667  struct efi_snp_device *snpdev =
1668  container_of ( name2, struct efi_snp_device, name2 );
1669 
1670  *driver_name = snpdev->driver_name;
1671  return 0;
1672 }
EFI_COMPONENT_NAME2_PROTOCOL name2
Component name protocol.
Definition: efi_snp.h:58
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An SNP device.
Definition: efi_snp.h:28
wchar_t driver_name[16]
Driver name.
Definition: efi_snp.h:74

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

Referenced by efi_snp_probe().

◆ efi_snp_get_controller_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 
)
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 1685 of file efi_snp.c.

1689  {
1690  struct efi_snp_device *snpdev =
1691  container_of ( name2, struct efi_snp_device, name2 );
1692 
1693  *controller_name = snpdev->controller_name;
1694  return 0;
1695 }
EFI_COMPONENT_NAME2_PROTOCOL name2
Component name protocol.
Definition: efi_snp.h:58
wchar_t controller_name[64]
Controller name.
Definition: efi_snp.h:76
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An SNP device.
Definition: efi_snp.h:28

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

Referenced by efi_snp_probe().

◆ 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 
)
static

Load file.

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

Definition at line 1713 of file efi_snp.c.

1716  {
1717  struct efi_snp_device *snpdev =
1719  struct net_device *netdev = snpdev->netdev;
1720  int rc;
1721 
1722  /* Fail unless this is a boot attempt */
1723  if ( ! booting ) {
1724  DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
1725  snpdev );
1726  return EFI_UNSUPPORTED;
1727  }
1728 
1729  /* Claim network devices for use by iPXE */
1730  efi_snp_claim();
1731 
1732  /* Start watchdog holdoff timer */
1734 
1735  /* Boot from network device */
1736  if ( ( rc = ipxe ( netdev ) ) != 0 )
1737  goto err_ipxe;
1738 
1739  /* Reset console */
1740  console_reset();
1741 
1742  err_ipxe:
1744  efi_snp_release();
1745  return EFIRC ( rc );
1746 }
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:117
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:91
int ipxe(struct net_device *netdev)
Main iPXE flow of execution.
Definition: autoboot.c:585
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void efi_watchdog_start(void)
Start EFI watchdog holdoff timer.
Definition: efi_watchdog.h:17
static struct net_device * netdev
Definition: gdbudp.c:52
static void efi_watchdog_stop(void)
Stop EFI watchdog holdoff timer.
Definition: efi_watchdog.h:26
A network device.
Definition: netdevice.h:352
An SNP device.
Definition: efi_snp.h:28
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:99
static void console_reset(void)
Reset console.
Definition: console.h:214
EFI_LOAD_FILE_PROTOCOL load_file
Load file protocol handle.
Definition: efi_snp.h:60
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163

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

◆ efi_snp_demux()

static 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 1766 of file efi_snp.c.

1766  {
1767  struct efi_snp_device *snpdev;
1768 
1769  list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
1770  if ( snpdev->netdev == netdev )
1771  return snpdev;
1772  }
1773  return NULL;
1774 }
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static struct net_device * netdev
Definition: gdbudp.c:52
An SNP device.
Definition: efi_snp.h:28
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct list_head list
List of SNP devices.
Definition: efi_snp.h:30

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()

static 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 1783 of file efi_snp.c.

1783  {
1785  struct efi_device *efidev;
1786  struct efi_snp_device *snpdev;
1787  unsigned int ifcnt;
1788  void *interface;
1789  unsigned int tci;
1790  char vlan_name[ 12 /* ", VLAN xxxx" + NUL */ ];
1791  int leak = 0;
1792  EFI_STATUS efirc;
1793  int rc;
1794 
1795  /* Find parent EFI device */
1796  efidev = efidev_parent ( netdev->dev );
1797  if ( ! efidev ) {
1798  DBG ( "SNP skipping non-EFI device %s\n", netdev->name );
1799  rc = 0;
1800  goto err_no_efidev;
1801  }
1802 
1803  /* Allocate the SNP device */
1804  snpdev = zalloc ( sizeof ( *snpdev ) );
1805  if ( ! snpdev ) {
1806  rc = -ENOMEM;
1807  goto err_alloc_snp;
1808  }
1809  snpdev->netdev = netdev_get ( netdev );
1810  snpdev->efidev = efidev;
1811  INIT_LIST_HEAD ( &snpdev->rx );
1812 
1813  /* Sanity check */
1814  if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
1815  DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
1816  "length %d for %s\n", snpdev,
1818  rc = -ENOTSUP;
1819  goto err_ll_addr_len;
1820  }
1821 
1822  /* Populate the SNP structure */
1823  memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
1824  snpdev->snp.Mode = &snpdev->mode;
1825  if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
1826  efi_snp_wait_for_packet, snpdev,
1827  &snpdev->snp.WaitForPacket ) ) != 0 ){
1828  rc = -EEFI ( efirc );
1829  DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
1830  snpdev, strerror ( rc ) );
1831  goto err_create_event;
1832  }
1833 
1834  /* Populate the SNP mode structure */
1836  efi_snp_set_mode ( snpdev );
1837 
1838  /* Populate the NII structure */
1839  memcpy ( &snpdev->nii, &efi_snp_device_nii, sizeof ( snpdev->nii ) );
1840  snpdev->nii.Id = ( ( intptr_t ) &efi_snp_undi );
1841  snpdev->nii.IfNum = efi_undi_ifnum ( snpdev );
1843  ifcnt = ( ( efi_snp_undi.IFcntExt << 8 ) | efi_snp_undi.IFcnt );
1844  if ( ifcnt < snpdev->nii.IfNum )
1845  ifcnt = snpdev->nii.IfNum;
1846  efi_snp_undi.IFcnt = ( ifcnt & 0xff );
1847  efi_snp_undi.IFcntExt = ( ifcnt >> 8 );
1849  sizeof ( efi_snp_undi ) );
1850 
1851  /* Populate the VLAN configuration protocol */
1852  memcpy ( &snpdev->vcfg, &efi_vlan, sizeof ( snpdev->vcfg ) );
1853 
1854  /* Populate the component name structure */
1855  efi_snprintf ( snpdev->driver_name,
1856  ( sizeof ( snpdev->driver_name ) /
1857  sizeof ( snpdev->driver_name[0] ) ),
1858  "%s %s", product_short_name, netdev->dev->driver_name );
1859  tci = vlan_tci ( netdev );
1860  if ( tci ) {
1861  snprintf ( vlan_name, sizeof ( vlan_name ), ", VLAN %d",
1862  VLAN_TAG ( tci ) );
1863  } else {
1864  vlan_name[0] = '\0';
1865  }
1866  efi_snprintf ( snpdev->controller_name,
1867  ( sizeof ( snpdev->controller_name ) /
1868  sizeof ( snpdev->controller_name[0] ) ),
1869  "%s %s (%s, %s%s)", product_short_name,
1871  netdev_addr ( netdev ), vlan_name );
1874  snpdev->name2.SupportedLanguages = "en";
1875 
1876  /* Populate the load file protocol structure */
1878  sizeof ( snpdev->load_file ) );
1879 
1880  /* Populate the device name */
1881  efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
1882  sizeof ( snpdev->name[0] ) ),
1883  "%s", netdev->name );
1884 
1885  /* Construct device path */
1886  snpdev->path = efi_netdev_path ( netdev );
1887  if ( ! snpdev->path ) {
1888  rc = -ENOMEM;
1889  goto err_path;
1890  }
1891 
1892  /* Install the SNP */
1893  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1894  &snpdev->handle,
1897  &efi_nii_protocol_guid, &snpdev->nii,
1898  &efi_nii31_protocol_guid, &snpdev->nii,
1902  NULL ) ) != 0 ) {
1903  rc = -EEFI ( efirc );
1904  DBGC ( snpdev, "SNPDEV %p could not install protocols: %s\n",
1905  snpdev, strerror ( rc ) );
1906  goto err_install_protocol_interface;
1907  }
1908 
1909  /* SnpDxe will repeatedly start up and shut down our NII/UNDI
1910  * interface (in order to obtain the MAC address) before
1911  * discovering that it cannot install another SNP on the same
1912  * handle. This causes the underlying network device to be
1913  * unexpectedly closed.
1914  *
1915  * Prevent this by opening our own NII (and NII31) protocol
1916  * instances to prevent SnpDxe from attempting to bind to
1917  * them.
1918  */
1919  if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
1921  efi_image_handle, snpdev->handle,
1924  rc = -EEFI ( efirc );
1925  DBGC ( snpdev, "SNPDEV %p could not open NII protocol: %s\n",
1926  snpdev, strerror ( rc ) );
1927  goto err_open_nii;
1928  }
1929  if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
1931  efi_image_handle, snpdev->handle,
1934  rc = -EEFI ( efirc );
1935  DBGC ( snpdev, "SNPDEV %p could not open NII31 protocol: %s\n",
1936  snpdev, strerror ( rc ) );
1937  goto err_open_nii31;
1938  }
1939 
1940  /* Add as child of EFI parent device */
1941  if ( ( rc = efi_child_add ( efidev->device, snpdev->handle ) ) != 0 ) {
1942  DBGC ( snpdev, "SNPDEV %p could not become child of %s: %s\n",
1943  snpdev, efi_handle_name ( efidev->device ),
1944  strerror ( rc ) );
1945  goto err_efi_child_add;
1946  }
1947 
1948  /* Install HII */
1949  if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
1950  DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
1951  snpdev, strerror ( rc ) );
1952  /* HII fails on several platforms. It's
1953  * non-essential, so treat this as a non-fatal
1954  * error.
1955  */
1956  }
1957 
1958  /* Add to list of SNP devices */
1959  list_add ( &snpdev->list, &efi_snp_devices );
1960 
1961  /* Close device path */
1964 
1965  DBGC ( snpdev, "SNPDEV %p installed for %s as device %s\n",
1966  snpdev, netdev->name, efi_handle_name ( snpdev->handle ) );
1967  return 0;
1968 
1969  list_del ( &snpdev->list );
1970  if ( snpdev->package_list )
1971  leak |= efi_snp_hii_uninstall ( snpdev );
1972  efi_child_del ( efidev->device, snpdev->handle );
1973  err_efi_child_add:
1975  efi_image_handle, snpdev->handle );
1976  err_open_nii31:
1977  bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
1978  efi_image_handle, snpdev->handle );
1979  err_open_nii:
1980  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
1981  snpdev->handle,
1984  &efi_nii_protocol_guid, &snpdev->nii,
1985  &efi_nii31_protocol_guid, &snpdev->nii,
1989  NULL ) ) != 0 ) {
1990  DBGC ( snpdev, "SNPDEV %p could not uninstall: %s\n",
1991  snpdev, strerror ( -EEFI ( efirc ) ) );
1992  leak = 1;
1993  }
1994  efi_nullify_snp ( &snpdev->snp );
1995  efi_nullify_nii ( &snpdev->nii );
1996  efi_nullify_vlan ( &snpdev->vcfg );
1997  efi_nullify_name2 ( &snpdev->name2 );
1998  efi_nullify_load_file ( &snpdev->load_file );
1999  err_install_protocol_interface:
2000  if ( ! leak )
2001  free ( snpdev->path );
2002  err_path:
2003  bs->CloseEvent ( snpdev->snp.WaitForPacket );
2004  err_create_event:
2005  err_ll_addr_len:
2006  if ( ! leak ) {
2007  netdev_put ( netdev );
2008  free ( snpdev );
2009  }
2010  err_alloc_snp:
2011  err_no_efidev:
2012  if ( leak )
2013  DBGC ( snpdev, "SNPDEV %p nullified and leaked\n", snpdev );
2014  return rc;
2015 }
EFI_GUID efi_nii31_protocol_guid
Network interface identifier protocol GUID (new version)
Definition: efi_guid.c:279
const char product_short_name[]
Product short name string.
Definition: version.c:76
#define VLAN_TAG(tci)
Extract VLAN tag from tag control information.
Definition: vlan.h:29
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
EFI_VLAN_CONFIG_PROTOCOL vcfg
VLAN configuration protocol.
Definition: efi_snp.h:56
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL nii
The network interface identifier.
Definition: efi_snp.h:54
EFI_COMPONENT_NAME2_PROTOCOL name2
Component name protocol.
Definition: efi_snp.h:58
32-byte buffer containing a network Media Access Control address.
Definition: UefiBaseType.h:97
EFI_GUID efi_simple_network_protocol_guid
Simple network protocol GUID.
Definition: efi_guid.c:307
#define DBGC(...)
Definition: compiler.h:505
static PXE_SW_UNDI efi_snp_undi
UNDI interface.
Definition: efi_snp.c:1459
char name[40]
Name.
Definition: device.h:75
#define EFI_OPEN_PROTOCOL_BY_DRIVER
Definition: UefiSpec.h:1347
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1996
#define EFI_OPEN_PROTOCOL_EXCLUSIVE
Definition: UefiSpec.h:1348
EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME GetControllerName
EFI_CLOSE_EVENT CloseEvent
Definition: UefiSpec.h:1945
static unsigned int efi_undi_ifnum(struct efi_snp_device *snpdev)
Get UNDI SNP device interface number.
Definition: efi_snp.c:935
EFI_HANDLE device
EFI device handle.
Definition: efi_driver.h:21
UINT32 State
Reports the current state of the network interface.
int efi_child_add(EFI_HANDLE parent, EFI_HANDLE child)
Add EFI device as child of another EFI device.
Definition: efi_utils.c:122
unsigned long intptr_t
Definition: stdint.h:21
wchar_t controller_name[64]
Controller name.
Definition: efi_snp.h:76
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1987
static const char * netdev_addr(struct net_device *netdev)
Get printable network device link-layer address.
Definition: netdevice.h:538
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
#define TPL_NOTIFY
Definition: UefiSpec.h:639
static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp
SNP interface.
Definition: efi_snp.c:872
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
UINT64 Id
The address of the first byte of the identifying structure for this network interface.
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:1665
EFI_SIMPLE_NETWORK_MODE * Mode
Pointer to the EFI_SIMPLE_NETWORK_MODE data for the device.
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:156
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
int efi_snp_hii_uninstall(struct efi_snp_device *snpdev)
Uninstall HII protocol and package for SNP device.
Definition: efi_snp_hii.c:796
int efi_snp_hii_install(struct efi_snp_device *snpdev)
Install HII protocol and packages for SNP device.
Definition: efi_snp_hii.c:658
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:64
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
An object interface.
Definition: interface.h:124
EFI_COMPONENT_NAME2_GET_DRIVER_NAME GetDriverName
static struct net_device * netdev
Definition: gdbudp.c:52
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:106
EFI_CREATE_EVENT CreateEvent
Definition: UefiSpec.h:1941
static EFI_VLAN_CONFIG_PROTOCOL efi_vlan
VLAN configuration protocol.
Definition: efi_snp.c:1643
EFI_GUID efi_vlan_config_protocol_guid
VLAN configuration protocol GUID.
Definition: efi_guid.c:387
static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol
Load file protocol.
Definition: efi_snp.c:1749
const char * driver_name
Driver name.
Definition: device.h:77
wchar_t name[sizeof(((struct net_device *) NULL) ->name)]
Device name.
Definition: efi_snp.h:72
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
static EFIAPI VOID efi_undi_issue(UINT64 cdb_phys)
UNDI entry point.
Definition: efi_snp.c:1355
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path(struct net_device *netdev)
Construct EFI device path for network device.
Definition: efi_path.c:336
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
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:120
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
An SNP device.
Definition: efi_snp.h:28
PXE_UINT8 Fudge
makes 8-bit cksum zero.
Definition: UefiPxe.h:812
struct efi_device * efidev
The underlying EFI device.
Definition: efi_snp.h:34
#define EVT_NOTIFY_WAIT
Definition: UefiSpec.h:442
An EFI device.
Definition: efi_driver.h:17
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:561
void efi_nullify_vlan(EFI_VLAN_CONFIG_PROTOCOL *vcfg)
Nullify VLAN configuration interface.
Definition: efi_null.c:233
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
EFI_GUID efi_component_name2_protocol_guid
Component name 2 protocol GUID.
Definition: efi_guid.c:135
static uint8_t efi_undi_checksum(void *data, size_t len)
Calculate UNDI byte checksum.
Definition: efi_snp.c:920
struct list_head rx
Receive queue.
Definition: efi_snp.h:52
static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii
Network Identification Interface (NII)
Definition: efi_snp.c:1482
wchar_t driver_name[16]
Driver name.
Definition: efi_snp.h:74
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
EFI_GUID efi_nii_protocol_guid
Network interface identifier protocol GUID (old version)
Definition: efi_guid.c:275
void efi_nullify_name2(EFI_COMPONENT_NAME2_PROTOCOL *name2)
Nullify Component Name Protocol interface.
Definition: efi_null.c:272
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
CHAR8 * SupportedLanguages
A Null-terminated ASCII string array that contains one or more supported language codes.
PXE_UINT8 IFcntExt
physical connector count upper byte.
Definition: UefiPxe.h:817
EFI_LOAD_FILE_PROTOCOL load_file
Load file protocol handle.
Definition: efi_snp.h:60
PXE_UINT64 EntryPoint
API entry point.
Definition: UefiPxe.h:820
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
PXE_UINT8 IFcnt
physical connector count lower byte.
Definition: UefiPxe.h:814
void efi_nullify_load_file(EFI_LOAD_FILE_PROTOCOL *load_file)
Nullify Load File Protocol interface.
Definition: efi_null.c:297
__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:1198
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1986
void efi_nullify_nii(EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii)
Nullify NII interface.
Definition: efi_null.c:191
struct efi_device * efidev_parent(struct device *dev)
Get parent EFI device.
Definition: efi_driver.c:155
UINT16 IfNum
The network interface number that is being identified by this Network Interface Identifier Protocol.
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
EFI_GUID efi_load_file_protocol_guid
Load file protocol GUID.
Definition: efi_guid.c:235
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:78
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition: efi_snp.h:40
static VOID EFIAPI efi_snp_wait_for_packet(EFI_EVENT event __unused, VOID *context)
Poll event.
Definition: efi_snp.c:846
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
EFI_EVENT WaitForPacket
Event used with WaitForEvent() to wait for a packet to be received.
void efi_nullify_snp(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Nullify SNP interface.
Definition: efi_null.c:156
struct list_head list
List of SNP devices.
Definition: efi_snp.h:30
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
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:1685

References EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseEvent, EFI_BOOT_SERVICES::CloseProtocol, efi_snp_device::controller_name, EFI_BOOT_SERVICES::CreateEvent, DBG, DBGC, net_device::dev, efi_device::device, efi_snp_device::driver_name, device::driver_name, EEFI, efi_child_add(), efi_child_del(), efi_component_name2_protocol_guid, efi_device_path_protocol_guid, efi_handle_name(), efi_image_handle, 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_PROTOCOL_BY_DRIVER, EFI_OPEN_PROTOCOL_EXCLUSIVE, 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, efi_snp_device::efidev, efidev_parent(), EfiSimpleNetworkStopped, ENOMEM, ENOTSUP, s_pxe_sw_undi::EntryPoint, EVT_NOTIFY_WAIT, free, s_pxe_sw_undi::Fudge, _EFI_COMPONENT_NAME2_PROTOCOL::GetControllerName, _EFI_COMPONENT_NAME2_PROTOCOL::GetDriverName, efi_snp_device::handle, _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL::Id, s_pxe_sw_undi::IFcnt, s_pxe_sw_undi::IFcntExt, _EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL::IfNum, INIT_LIST_HEAD, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, efi_snp_device::list, list_add, list_del, ll_protocol::ll_addr_len, net_device::ll_protocol, efi_snp_device::load_file, memcpy(), efi_snp_device::mode, _EFI_SIMPLE_NETWORK_PROTOCOL::Mode, efi_snp_device::name, device::name, net_device::name, efi_snp_device::name2, efi_snp_device::netdev, netdev, netdev_addr(), netdev_get(), netdev_put(), efi_snp_device::nii, NULL, EFI_BOOT_SERVICES::OpenProtocol, efi_snp_device::package_list, efi_snp_device::path, 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()

static 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 2023 of file efi_snp.c.

2023  {
2024  struct efi_snp_device *snpdev;
2025 
2026  /* Locate SNP device */
2027  snpdev = efi_snp_demux ( netdev );
2028  if ( ! snpdev ) {
2029  DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
2030  return;
2031  }
2032 
2033  /* Update link state */
2034  snpdev->mode.MediaPresent =
2035  ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
2036  DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
2037  ( snpdev->mode.MediaPresent ? "up" : "down" ) );
2038 
2039  /* Update mode state */
2040  efi_snp_set_state ( snpdev );
2041 }
BOOLEAN MediaPresent
TRUE if media are connected to the network interface; otherwise FALSE.
#define DBGC(...)
Definition: compiler.h:505
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition: netdevice.h:636
static struct net_device * netdev
Definition: gdbudp.c:52
An SNP device.
Definition: efi_snp.h:28
#define TRUE
Definition: tlan.h:46
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define FALSE
Definition: tlan.h:45
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
EFI_SIMPLE_NETWORK_MODE mode
The SNP "mode" (parameters)
Definition: efi_snp.h:40
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition: efi_snp.c:1766

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

◆ efi_snp_remove()

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

Destroy SNP device.

Parameters
netdevNetwork device
privPrivate data

Definition at line 2049 of file efi_snp.c.

2049  {
2051  struct efi_snp_device *snpdev;
2052  int leak = efi_shutdown_in_progress;
2053  EFI_STATUS efirc;
2054 
2055  /* Locate SNP device */
2056  snpdev = efi_snp_demux ( netdev );
2057  if ( ! snpdev ) {
2058  DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
2059  return;
2060  }
2061 
2062  /* Uninstall the SNP */
2063  list_del ( &snpdev->list );
2064  if ( snpdev->package_list )
2065  leak |= efi_snp_hii_uninstall ( snpdev );
2066  efi_child_del ( snpdev->efidev->device, snpdev->handle );
2067  bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
2068  efi_image_handle, snpdev->handle );
2070  efi_image_handle, snpdev->handle );
2071  if ( ( ! efi_shutdown_in_progress ) &&
2072  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
2073  snpdev->handle,
2076  &efi_nii_protocol_guid, &snpdev->nii,
2077  &efi_nii31_protocol_guid, &snpdev->nii,
2081  NULL ) ) != 0 ) ) {
2082  DBGC ( snpdev, "SNPDEV %p could not uninstall: %s\n",
2083  snpdev, strerror ( -EEFI ( efirc ) ) );
2084  leak = 1;
2085  }
2086  efi_nullify_snp ( &snpdev->snp );
2087  efi_nullify_nii ( &snpdev->nii );
2088  efi_nullify_vlan ( &snpdev->vcfg );
2089  efi_nullify_name2 ( &snpdev->name2 );
2090  efi_nullify_load_file ( &snpdev->load_file );
2091  if ( ! leak )
2092  free ( snpdev->path );
2093  bs->CloseEvent ( snpdev->snp.WaitForPacket );
2094  if ( ! leak ) {
2095  netdev_put ( snpdev->netdev );
2096  free ( snpdev );
2097  }
2098 
2099  /* Report leakage, if applicable */
2100  if ( leak && ( ! efi_shutdown_in_progress ) )
2101  DBGC ( snpdev, "SNPDEV %p nullified and leaked\n", snpdev );
2102 }
EFI_GUID efi_nii31_protocol_guid
Network interface identifier protocol GUID (new version)
Definition: efi_guid.c:279
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
EFI_VLAN_CONFIG_PROTOCOL vcfg
VLAN configuration protocol.
Definition: efi_snp.h:56
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL nii
The network interface identifier.
Definition: efi_snp.h:54
EFI_COMPONENT_NAME2_PROTOCOL name2
Component name protocol.
Definition: efi_snp.h:58
EFI_GUID efi_simple_network_protocol_guid
Simple network protocol GUID.
Definition: efi_guid.c:307
#define DBGC(...)
Definition: compiler.h:505
EFI_CLOSE_EVENT CloseEvent
Definition: UefiSpec.h:1945
EFI_HANDLE device
EFI device handle.
Definition: efi_driver.h:21
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1987
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
struct net_device * netdev
The underlying iPXE network device.
Definition: efi_snp.h:32
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:156
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
int efi_snp_hii_uninstall(struct efi_snp_device *snpdev)
Uninstall HII protocol and package for SNP device.
Definition: efi_snp_hii.c:796
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:64
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
static struct net_device * netdev
Definition: gdbudp.c:52
EFI_GUID efi_vlan_config_protocol_guid
VLAN configuration protocol GUID.
Definition: efi_guid.c:387
EFI_SIMPLE_NETWORK_PROTOCOL snp
The SNP structure itself.
Definition: efi_snp.h:38
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1997
An SNP device.
Definition: efi_snp.h:28
struct efi_device * efidev
The underlying EFI device.
Definition: efi_snp.h:34
void efi_nullify_vlan(EFI_VLAN_CONFIG_PROTOCOL *vcfg)
Nullify VLAN configuration interface.
Definition: efi_null.c:233
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
EFI_GUID efi_component_name2_protocol_guid
Component name 2 protocol GUID.
Definition: efi_guid.c:135
EFI_GUID efi_nii_protocol_guid
Network interface identifier protocol GUID (old version)
Definition: efi_guid.c:275
void efi_nullify_name2(EFI_COMPONENT_NAME2_PROTOCOL *name2)
Nullify Component Name Protocol interface.
Definition: efi_null.c:272
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
EFI_LOAD_FILE_PROTOCOL load_file
Load file protocol handle.
Definition: efi_snp.h:60
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
void efi_nullify_load_file(EFI_LOAD_FILE_PROTOCOL *load_file)
Nullify Load File Protocol interface.
Definition: efi_null.c:297
EFI_SYSTEM_TABLE * efi_systab
void efi_nullify_nii(EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii)
Nullify NII interface.
Definition: efi_null.c:191
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
EFI_GUID efi_load_file_protocol_guid
Load file protocol GUID.
Definition: efi_guid.c:235
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:78
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition: efi_snp.c:1766
EFI_EVENT WaitForPacket
Event used with WaitForEvent() to wait for a packet to be received.
void efi_nullify_snp(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Nullify SNP interface.
Definition: efi_null.c:156
struct list_head list
List of SNP devices.
Definition: efi_snp.h:30
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:58

References EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseEvent, EFI_BOOT_SERVICES::CloseProtocol, DBG, DBGC, efi_device::device, EEFI, efi_child_del(), efi_component_name2_protocol_guid, efi_device_path_protocol_guid, efi_image_handle, 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, efi_snp_device::efidev, free, efi_snp_device::handle, efi_snp_device::list, list_del, efi_snp_device::load_file, net_device::name, efi_snp_device::name2, efi_snp_device::netdev, netdev, netdev_put(), efi_snp_device::nii, NULL, efi_snp_device::package_list, efi_snp_device::path, 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 2118 of file efi_snp.c.

2118  {
2119  struct efi_snp_device *snpdev;
2120 
2121  list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
2122  if ( snpdev->handle == handle )
2123  return snpdev;
2124  }
2125  return NULL;
2126 }
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:36
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
An SNP device.
Definition: efi_snp.h:28
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct list_head list
List of SNP devices.
Definition: efi_snp.h:30

References handle, efi_snp_device::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 2133 of file efi_snp.c.

2133  {
2134  struct net_device *netdev;
2135 
2137  if ( ! netdev )
2138  return NULL;
2139 
2140  return efi_snp_demux ( netdev );
2141 }
static struct net_device * netdev
Definition: gdbudp.c:52
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition: netdevice.c:1047
A network device.
Definition: netdevice.h:352
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition: efi_snp.c:1766

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 2148 of file efi_snp.c.

2148  {
2149  struct efi_snp_device *snpdev;
2150 
2151  /* Raise TPL if we are about to claim devices */
2152  if ( ! efi_snp_claimed )
2154 
2155  /* Claim SNP devices */
2156  efi_snp_claimed += delta;
2157  assert ( efi_snp_claimed >= 0 );
2158 
2159  /* Update SNP mode state for each interface */
2160  list_for_each_entry ( snpdev, &efi_snp_devices, list )
2161  efi_snp_set_state ( snpdev );
2162 
2163  /* Restore TPL if we have released devices */
2164  if ( ! efi_snp_claimed )
2166 }
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition: efi_init.c:399
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
static struct efi_saved_tpl efi_snp_saved_tpl
TPL prior to network devices being claimed.
Definition: efi_snp.c:51
An SNP device.
Definition: efi_snp.h:28
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:415
struct list_head list
List of SNP devices.
Definition: efi_snp.h:30

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

int efi_snp_claimed
static

◆ efi_snp_saved_tpl

struct efi_saved_tpl efi_snp_saved_tpl
static

TPL prior to network devices being claimed.

Definition at line 51 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,
}
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:238
static EFI_STATUS EFIAPI efi_snp_start(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Change SNP state from "stopped" to "started".
Definition: efi_snp.c:189
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:400
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:366
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:524
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:760
#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
static EFI_STATUS EFIAPI efi_snp_stop(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Change SNP state from "started" to "stopped".
Definition: efi_snp.c:213
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:486
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:610
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:437
static EFI_STATUS EFIAPI efi_snp_shutdown(EFI_SIMPLE_NETWORK_PROTOCOL *snp)
Shut down the network device.
Definition: efi_snp.c:329
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:551
static EFI_STATUS EFIAPI efi_snp_reset(EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify)
Reset the network device.
Definition: efi_snp.c:285

SNP interface.

Definition at line 872 of file efi_snp.c.

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:846
#define PXE_ROMID_SIGNATURE
Signature of !PXE structure.
Definition: UefiPxe.h:834
#define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED
Definition: UefiPxe.h:872
#define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
Definition: UefiPxe.h:868
#define PXE_BUSTYPE(a, b, c, d)
Definition: UefiPxe.h:22
static PXE_SW_UNDI efi_snp_undi
UNDI interface.
Definition: efi_snp.c:1459
#define PXE_ROMID_IMP_STATION_ADDR_SETTABLE
Definition: UefiPxe.h:865
UINT8_t Rev
PCI revision.
Definition: pxe_api.h:62
#define PXE_ROMID_MINORVER
Definition: UefiPxe.h:847
#define PXE_ROMID_IMP_SW_VIRT_ADDR
Definition: UefiPxe.h:853
#define PXE_ROMID_REV
!PXE structure format revision
Definition: UefiPxe.h:839
#define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
Definition: UefiPxe.h:867
#define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
Definition: UefiPxe.h:866
#define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED
Definition: UefiPxe.h:871

UNDI interface.

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

Definition at line 1459 of file efi_snp.c.

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,
}
#define TRUE
Definition: tlan.h:46
#define EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION

Network Identification Interface (NII)

Definition at line 1482 of file efi_snp.c.

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:1609
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:1540
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:1506

VLAN configuration protocol.

Definition at line 1643 of file efi_snp.c.

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:1713

Load file protocol.

Definition at line 1749 of file efi_snp.c.

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 void efi_snp_notify(struct net_device *netdev, void *priv __unused)
Handle SNP device or link state change.
Definition: efi_snp.c:2023
static void efi_snp_remove(struct net_device *netdev, void *priv __unused)
Destroy SNP device.
Definition: efi_snp.c:2049
static int efi_snp_probe(struct net_device *netdev, void *priv __unused)
Create SNP device.
Definition: efi_snp.c:1783

SNP driver.

Definition at line 2105 of file efi_snp.c.