iPXE
snpnet.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <ipxe/iobuf.h>
27 #include <ipxe/netdevice.h>
28 #include <ipxe/ethernet.h>
29 #include <ipxe/if_ether.h>
30 #include <ipxe/vsprintf.h>
31 #include <ipxe/timer.h>
32 #include <ipxe/efi/efi.h>
34 #include <ipxe/efi/efi_driver.h>
35 #include <ipxe/efi/efi_utils.h>
36 #include <ipxe/efi/efi_snp.h>
37 #include "snpnet.h"
38 
39 /** @file
40  *
41  * SNP NIC driver
42  *
43  */
44 
45 /** An SNP NIC */
46 struct snp_nic {
47  /** EFI device */
48  struct efi_device *efidev;
49  /** Simple network protocol */
51  /** Generic device */
52  struct device dev;
53 
54  /** Maximum packet size
55  *
56  * This is calculated as the sum of MediaHeaderSize and
57  * MaxPacketSize, and may therefore be an overestimate.
58  */
59  size_t mtu;
60 
61  /** Current transmit buffer */
62  struct io_buffer *txbuf;
63  /** Current receive buffer */
64  struct io_buffer *rxbuf;
65 };
66 
67 /** Maximum number of received packets per poll */
68 #define SNP_RX_QUOTA 4
69 
70 /** Maximum initialisation retry count */
71 #define SNP_INITIALIZE_RETRY_MAX 10
72 
73 /** Delay between each initialisation retry */
74 #define SNP_INITIALIZE_RETRY_DELAY_MS 10
75 
76 /** Additional padding for receive buffers
77  *
78  * Some SNP implementations seem to require additional space in the
79  * allocated receive buffers, otherwise full-length packets will be
80  * silently dropped.
81  *
82  * The EDK2 MnpDxe driver happens to allocate an additional 8 bytes of
83  * padding (4 for a VLAN tag, 4 for the Ethernet frame checksum).
84  * Match this behaviour since drivers are very likely to have been
85  * tested against MnpDxe.
86  */
87 #define SNP_RX_PAD 8
88 
89 /**
90  * Format SNP MAC address (for debugging)
91  *
92  * @v mac MAC address
93  * @v len Length of MAC address
94  * @ret text MAC address as text
95  */
96 static const char * snpnet_mac_text ( EFI_MAC_ADDRESS *mac, size_t len ) {
97  static char buf[ sizeof ( *mac ) * 3 /* "xx:" or "xx\0" */ ];
98  size_t used = 0;
99  unsigned int i;
100 
101  for ( i = 0 ; i < len ; i++ ) {
102  used += ssnprintf ( &buf[used], ( sizeof ( buf ) - used ),
103  "%s%02x", ( used ? ":" : "" ),
104  mac->Addr[i] );
105  }
106  return buf;
107 }
108 
109 /**
110  * Dump SNP mode information (for debugging)
111  *
112  * @v netdev Network device
113  */
114 static void snpnet_dump_mode ( struct net_device *netdev ) {
115  struct snp_nic *snp = netdev->priv;
116  EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
117  size_t mac_len = mode->HwAddressSize;
118  unsigned int i;
119 
120  /* Do nothing unless debugging is enabled */
121  if ( ! DBG_EXTRA )
122  return;
123 
124  DBGC2 ( snp, "SNP %s st %d type %d hdr %d pkt %d rxflt %#x/%#x%s "
125  "nvram %d acc %d mcast %d/%d\n", netdev->name, mode->State,
126  mode->IfType, mode->MediaHeaderSize, mode->MaxPacketSize,
128  ( mode->MultipleTxSupported ? " multitx" : "" ),
129  mode->NvRamSize, mode->NvRamAccessSize,
130  mode->MCastFilterCount, mode->MaxMCastFilterCount );
131  DBGC2 ( snp, "SNP %s hw %s", netdev->name,
132  snpnet_mac_text ( &mode->PermanentAddress, mac_len ) );
133  DBGC2 ( snp, " addr %s%s",
134  snpnet_mac_text ( &mode->CurrentAddress, mac_len ),
135  ( mode->MacAddressChangeable ? "" : "(f)" ) );
136  DBGC2 ( snp, " bcast %s\n",
137  snpnet_mac_text ( &mode->BroadcastAddress, mac_len ) );
138  for ( i = 0 ; i < mode->MCastFilterCount ; i++ ) {
139  DBGC2 ( snp, "SNP %s mcast %s\n", netdev->name,
140  snpnet_mac_text ( &mode->MCastFilter[i], mac_len ) );
141  }
142  DBGC2 ( snp, "SNP %s media %s\n", netdev->name,
143  ( mode->MediaPresentSupported ?
144  ( mode->MediaPresent ? "present" : "not present" ) :
145  "presence not supported" ) );
146 }
147 
148 /**
149  * Check link state
150  *
151  * @v netdev Network device
152  */
153 static void snpnet_check_link ( struct net_device *netdev ) {
154  struct snp_nic *snp = netdev->priv;
155  EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
156 
157  /* Do nothing unless media presence detection is supported */
158  if ( ! mode->MediaPresentSupported )
159  return;
160 
161  /* Report any link status change */
162  if ( mode->MediaPresent && ( ! netdev_link_ok ( netdev ) ) ) {
164  } else if ( ( ! mode->MediaPresent ) && netdev_link_ok ( netdev ) ) {
166  }
167 }
168 
169 /**
170  * Transmit packet
171  *
172  * @v netdev Network device
173  * @v iobuf I/O buffer
174  * @ret rc Return status code
175  */
176 static int snpnet_transmit ( struct net_device *netdev,
177  struct io_buffer *iobuf ) {
178  struct snp_nic *snp = netdev->priv;
179  EFI_STATUS efirc;
180  int rc;
181 
182  /* Do nothing if shutdown is in progress */
184  return -ECANCELED;
185 
186  /* Defer the packet if there is already a transmission in progress */
187  if ( snp->txbuf ) {
188  netdev_tx_defer ( netdev, iobuf );
189  return 0;
190  }
191 
192  /* Pad to minimum Ethernet length, to work around underlying
193  * drivers that do not correctly handle frame padding
194  * themselves.
195  */
196  iob_pad ( iobuf, ETH_ZLEN );
197 
198  /* Transmit packet */
199  if ( ( efirc = snp->snp->Transmit ( snp->snp, 0, iob_len ( iobuf ),
200  iobuf->data, NULL, NULL,
201  NULL ) ) != 0 ) {
202  rc = -EEFI ( efirc );
203  DBGC ( snp, "SNP %s could not transmit: %s\n",
204  netdev->name, strerror ( rc ) );
205  return rc;
206  }
207  snp->txbuf = iobuf;
208 
209  return 0;
210 }
211 
212 /**
213  * Poll for completed packets
214  *
215  * @v netdev Network device
216  */
217 static void snpnet_poll_tx ( struct net_device *netdev ) {
218  struct snp_nic *snp = netdev->priv;
219  struct io_buffer *iobuf;
220  UINT32 irq;
221  VOID *txbuf;
222  EFI_STATUS efirc;
223  int rc;
224 
225  /* Get status */
226  txbuf = NULL;
227  if ( ( efirc = snp->snp->GetStatus ( snp->snp, &irq, &txbuf ) ) != 0 ) {
228  rc = -EEFI ( efirc );
229  DBGC ( snp, "SNP %s could not get status: %s\n",
230  netdev->name, strerror ( rc ) );
231  netdev_rx_err ( netdev, NULL, rc );
232  return;
233  }
234 
235  /* Do nothing unless we have a completion */
236  if ( ! txbuf )
237  return;
238 
239  /* Sanity check */
240  if ( ! snp->txbuf ) {
241  DBGC ( snp, "SNP %s reported spurious TX completion\n",
242  netdev->name );
244  return;
245  }
246 
247  /* Complete transmission */
248  iobuf = snp->txbuf;
249  snp->txbuf = NULL;
250  netdev_tx_complete ( netdev, iobuf );
251 }
252 
253 /**
254  * Poll for received packets
255  *
256  * @v netdev Network device
257  */
258 static void snpnet_poll_rx ( struct net_device *netdev ) {
259  struct snp_nic *snp = netdev->priv;
260  UINTN len;
261  unsigned int quota;
262  EFI_STATUS efirc;
263  int rc;
264 
265  /* Retrieve up to SNP_RX_QUOTA packets */
266  for ( quota = SNP_RX_QUOTA ; quota ; quota-- ) {
267 
268  /* Allocate buffer, if required */
269  if ( ! snp->rxbuf ) {
270  snp->rxbuf = alloc_iob ( snp->mtu + SNP_RX_PAD );
271  if ( ! snp->rxbuf ) {
272  /* Leave for next poll */
273  break;
274  }
275  }
276 
277  /* Receive packet */
278  len = iob_tailroom ( snp->rxbuf );
279  if ( ( efirc = snp->snp->Receive ( snp->snp, NULL, &len,
280  snp->rxbuf->data, NULL,
281  NULL, NULL ) ) != 0 ) {
282 
283  /* EFI_NOT_READY is just the usual "no packet"
284  * status indication; ignore it.
285  */
286  if ( efirc == EFI_NOT_READY )
287  break;
288 
289  /* Anything else is an error */
290  rc = -EEFI ( efirc );
291  DBGC ( snp, "SNP %s could not receive: %s\n",
292  netdev->name, strerror ( rc ) );
293  netdev_rx_err ( netdev, NULL, rc );
294  break;
295  }
296 
297  /* Hand off to network stack */
298  iob_put ( snp->rxbuf, len );
299  netdev_rx ( netdev, snp->rxbuf );
300  snp->rxbuf = NULL;
301  }
302 }
303 
304 /**
305  * Poll for completed packets
306  *
307  * @v netdev Network device
308  */
309 static void snpnet_poll ( struct net_device *netdev ) {
310 
311  /* Do nothing if shutdown is in progress */
313  return;
314 
315  /* Process any TX completions */
317 
318  /* Process any RX completions */
320 
321  /* Check for link state changes */
323 }
324 
325 /**
326  * Set receive filters
327  *
328  * @v netdev Network device
329  * @ret rc Return status code
330  */
331 static int snpnet_rx_filters ( struct net_device *netdev ) {
332  struct snp_nic *snp = netdev->priv;
333  UINT32 filters[] = {
334  snp->snp->Mode->ReceiveFilterMask,
344  };
345  unsigned int i;
346  EFI_STATUS efirc;
347  int rc;
348 
349  /* Try possible receive filters in turn */
350  for ( i = 0; i < ( sizeof ( filters ) / sizeof ( filters[0] ) ); i++ ) {
351  efirc = snp->snp->ReceiveFilters ( snp->snp, filters[i],
353  0, NULL );
354  if ( efirc == 0 )
355  return 0;
356  rc = -EEFI ( efirc );
357  DBGC ( snp, "SNP %s could not set receive filters %#02x (have "
358  "%#02x): %s\n", netdev->name, filters[i],
359  snp->snp->Mode->ReceiveFilterSetting, strerror ( rc ) );
360  }
361 
362  return rc;
363 }
364 
365 /**
366  * Open network device
367  *
368  * @v netdev Network device
369  * @ret rc Return status code
370  */
371 static int snpnet_open ( struct net_device *netdev ) {
372  struct snp_nic *snp = netdev->priv;
373  EFI_MAC_ADDRESS *mac = ( ( void * ) netdev->ll_addr );
374  EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
375  EFI_STATUS efirc;
376  unsigned int retry;
377  int rc;
378 
379  /* Try setting MAC address (before initialising) */
380  if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
381  rc = -EEFI ( efirc );
382  DBGC ( snp, "SNP %s could not set station address before "
383  "initialising: %s\n", netdev->name, strerror ( rc ) );
384  /* Ignore error */
385  }
386 
387  /* Initialise NIC, retrying multiple times if link stays down */
388  for ( retry = 0 ; ; ) {
389 
390  /* Initialise NIC */
391  if ( ( efirc = snp->snp->Initialize ( snp->snp,
392  0, 0 ) ) != 0 ) {
393  rc = -EEFI ( efirc );
395  DBGC ( snp, "SNP %s could not initialise: %s\n",
396  netdev->name, strerror ( rc ) );
397  return rc;
398  }
399 
400  /* Stop if we have link up (or no link detection capability) */
401  if ( ( ! mode->MediaPresentSupported ) || mode->MediaPresent )
402  break;
403 
404  /* Stop if we have exceeded our retry count. This is
405  * not a failure; it is plausible that we genuinely do
406  * not have link up.
407  */
408  if ( ++retry >= SNP_INITIALIZE_RETRY_MAX )
409  break;
410  DBGC ( snp, "SNP %s retrying initialisation (retry %d)\n",
411  netdev->name, retry );
412 
413  /* Delay to allow time for link to establish */
415 
416  /* Shut down and retry; this is sometimes necessary in
417  * order to persuade the underlying SNP driver to
418  * actually update the link state.
419  */
420  if ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) {
421  rc = -EEFI ( efirc );
423  DBGC ( snp, "SNP %s could not shut down: %s\n",
424  netdev->name, strerror ( rc ) );
425  return rc;
426  }
427  }
428 
429  /* Try setting MAC address (after initialising) */
430  if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
431  rc = -EEFI ( efirc );
432  DBGC ( snp, "SNP %s could not set station address after "
433  "initialising: %s\n", netdev->name, strerror ( rc ) );
434  /* Ignore error */
435  }
436 
437  /* Set receive filters */
438  if ( ( rc = snpnet_rx_filters ( netdev ) ) != 0 ) {
439  /* Ignore error */
440  }
441 
442  /* Dump mode information (for debugging) */
444 
445  return 0;
446 }
447 
448 /**
449  * Close network device
450  *
451  * @v netdev Network device
452  */
453 static void snpnet_close ( struct net_device *netdev ) {
454  struct snp_nic *snp = netdev->priv;
455  EFI_STATUS efirc;
456  int rc;
457 
458  /* Shut down NIC (unless whole system shutdown is in progress) */
459  if ( ( ! efi_shutdown_in_progress ) &&
460  ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
461  rc = -EEFI ( efirc );
462  DBGC ( snp, "SNP %s could not shut down: %s\n",
463  netdev->name, strerror ( rc ) );
464  /* Nothing we can do about this */
465  }
466 
467  /* Discard transmit buffer, if applicable */
468  if ( snp->txbuf ) {
470  snp->txbuf = NULL;
471  }
472 
473  /* Discard receive buffer, if applicable */
474  if ( snp->rxbuf ) {
475  free_iob ( snp->rxbuf );
476  snp->rxbuf = NULL;
477  }
478 }
479 
480 /** SNP network device operations */
482  .open = snpnet_open,
483  .close = snpnet_close,
484  .transmit = snpnet_transmit,
485  .poll = snpnet_poll,
486 };
487 
488 /**
489  * Check to see if driver supports a device
490  *
491  * @v device EFI device handle
492  * @v protocol Protocol GUID
493  * @ret rc Return status code
494  */
497  EFI_HANDLE parent;
498  EFI_STATUS efirc;
499  int rc;
500 
501  /* Check that this is not a device we are providing ourselves */
502  if ( find_snpdev ( device ) != NULL ) {
503  DBGCP ( device, "HANDLE %s is provided by this binary\n",
504  efi_handle_name ( device ) );
505  return -ENOTTY;
506  }
507 
508  /* Test for presence of protocol */
509  if ( ( efirc = bs->OpenProtocol ( device, protocol,
512  DBGCP ( device, "HANDLE %s is not a %s device\n",
514  efi_guid_ntoa ( protocol ) );
515  return -EEFI ( efirc );
516  }
517 
518  /* Check that there are no instances of this protocol further
519  * up this device path.
520  */
521  if ( ( rc = efi_locate_device ( device, protocol,
522  &parent, 1 ) ) == 0 ) {
523  DBGC2 ( device, "HANDLE %s has %s-supporting parent ",
525  efi_guid_ntoa ( protocol ) );
526  DBGC2 ( device, "%s\n", efi_handle_name ( parent ) );
527  return -ENOTTY;
528  }
529 
530  DBGC ( device, "HANDLE %s is a %s device\n",
532  return 0;
533 }
534 
535 /**
536  * Attach driver to device
537  *
538  * @v efidev EFI device
539  * @ret rc Return status code
540  */
541 int snpnet_start ( struct efi_device *efidev ) {
543  EFI_HANDLE device = efidev->device;
545  struct net_device *netdev;
546  struct snp_nic *snp;
547  void *interface;
548  EFI_STATUS efirc;
549  int rc;
550 
551  /* Open SNP protocol */
552  if ( ( efirc = bs->OpenProtocol ( device,
557  rc = -EEFI ( efirc );
558  DBGC ( device, "SNP %s cannot open SNP protocol: %s\n",
559  efi_handle_name ( device ), strerror ( rc ) );
562  goto err_open_protocol;
563  }
564 
565  /* Allocate and initialise structure */
566  netdev = alloc_etherdev ( sizeof ( *snp ) );
567  if ( ! netdev ) {
568  rc = -ENOMEM;
569  goto err_alloc;
570  }
572  snp = netdev->priv;
573  snp->efidev = efidev;
574  snp->snp = interface;
575  mode = snp->snp->Mode;
577 
578  /* Populate underlying device information */
579  efi_device_info ( device, "SNP", &snp->dev );
580  snp->dev.driver_name = "SNP";
581  snp->dev.parent = &efidev->dev;
582  list_add ( &snp->dev.siblings, &efidev->dev.children );
583  INIT_LIST_HEAD ( &snp->dev.children );
584  netdev->dev = &snp->dev;
585 
586  /* Bring to the Started state */
587  if ( ( mode->State == EfiSimpleNetworkStopped ) &&
588  ( ( efirc = snp->snp->Start ( snp->snp ) ) != 0 ) ) {
589  rc = -EEFI ( efirc );
590  DBGC ( device, "SNP %s could not start: %s\n",
591  efi_handle_name ( device ), strerror ( rc ) );
592  goto err_start;
593  }
594  if ( ( mode->State == EfiSimpleNetworkInitialized ) &&
595  ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
596  rc = -EEFI ( efirc );
597  DBGC ( device, "SNP %s could not shut down: %s\n",
598  efi_handle_name ( device ), strerror ( rc ) );
599  goto err_shutdown;
600  }
601 
602  /* Populate network device parameters */
603  if ( mode->HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
604  DBGC ( device, "SNP %s has invalid hardware address length "
605  "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
606  rc = -ENOTSUP;
607  goto err_hw_addr_len;
608  }
611  if ( mode->HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
612  DBGC ( device, "SNP %s has invalid link-layer address length "
613  "%d\n", efi_handle_name ( device ), mode->HwAddressSize);
614  rc = -ENOTSUP;
615  goto err_ll_addr_len;
616  }
617  memcpy ( netdev->ll_addr, &mode->CurrentAddress,
619  snp->mtu = ( snp->snp->Mode->MaxPacketSize +
620  snp->snp->Mode->MediaHeaderSize );
621 
622  /* Register network device */
623  if ( ( rc = register_netdev ( netdev ) ) != 0 )
624  goto err_register_netdev;
625  DBGC ( device, "SNP %s registered as %s\n",
627 
628  /* Set initial link state */
629  if ( snp->snp->Mode->MediaPresentSupported ) {
631  } else {
633  }
634 
635  return 0;
636 
638  err_register_netdev:
639  err_ll_addr_len:
640  err_hw_addr_len:
641  err_shutdown:
642  err_start:
643  list_del ( &snp->dev.siblings );
645  netdev_put ( netdev );
646  err_alloc:
649  err_open_protocol:
650  return rc;
651 }
652 
653 /**
654  * Detach driver from device
655  *
656  * @v efidev EFI device
657  */
658 void snpnet_stop ( struct efi_device *efidev ) {
660  struct net_device *netdev = efidev_get_drvdata ( efidev );
661  struct snp_nic *snp = netdev->priv;
663  EFI_STATUS efirc;
664  int rc;
665 
666  /* Unregister network device */
668 
669  /* Stop SNP protocol (unless whole system shutdown is in progress) */
670  if ( ( ! efi_shutdown_in_progress ) &&
671  ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) ) {
672  rc = -EEFI ( efirc );
673  DBGC ( device, "SNP %s could not stop: %s\n",
674  efi_handle_name ( device ), strerror ( rc ) );
675  /* Nothing we can do about this */
676  }
677 
678  /* Free network device */
679  list_del ( &snp->dev.siblings );
681  netdev_put ( netdev );
682 
683  /* Close SNP protocol */
686 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
EFI_SIMPLE_NETWORK_STATION_ADDRESS StationAddress
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition: netdevice.h:752
UINT32 NvRamSize
The size, in bytes, of the NVRAM device attached to the network interface.
#define iob_put(iobuf, len)
Definition: iobuf.h:120
static void snpnet_dump_mode(struct net_device *netdev)
Dump SNP mode information (for debugging)
Definition: snpnet.c:114
static void snpnet_poll(struct net_device *netdev)
Poll for completed packets.
Definition: snpnet.c:309
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:586
The EFI_SIMPLE_NETWORK_PROTOCOL protocol is used to initialize access to a network adapter.
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:171
void netdev_tx_defer(struct net_device *netdev, struct io_buffer *iobuf)
Defer transmitted packet.
Definition: netdevice.c:412
#define SNP_RX_PAD
Additional padding for receive buffers.
Definition: snpnet.c:87
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
EFI driver interface.
UINT32 MediaHeaderSize
The size, in bytes, of the network interface's media header.
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
BOOLEAN MediaPresent
TRUE if media are connected to the network interface; otherwise FALSE.
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
void netdev_tx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard transmitted packet.
Definition: netdevice.c:440
128 bit buffer containing a unique identifier value.
Definition: Base.h:215
EFI_SIMPLE_NETWORK_PROTOCOL * snp
Simple network protocol.
Definition: snpnet.c:50
Error codes.
int snpnet_supported(EFI_HANDLE device, EFI_GUID *protocol)
Check to see if driver supports a device.
Definition: snpnet.c:495
32-byte buffer containing a network Media Access Control address.
Definition: UefiBaseType.h:97
void snpnet_stop(struct efi_device *efidev)
Detach driver from device.
Definition: snpnet.c:658
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
static int snpnet_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: snpnet.c:176
#define EPIPE
Broken pipe.
Definition: errno.h:619
printf() and friends
EFI_GUID efi_simple_network_protocol_guid
Simple network protocol GUID.
Definition: efi_guid.c:307
#define DBGC(...)
Definition: compiler.h:505
#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
unsigned int UINT32
Definition: ProcessorBind.h:98
#define EFI_OPEN_PROTOCOL_BY_DRIVER
Definition: UefiSpec.h:1347
#define EFI_OPEN_PROTOCOL_EXCLUSIVE
Definition: UefiSpec.h:1348
BOOLEAN MediaPresentSupported
TRUE if the presence of media can be determined; otherwise FALSE.
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition: netdevice.c:230
iPXE timers
#define DBGC_EFI_OPENERS(...)
Definition: efi.h:321
EFI_HANDLE device
EFI device handle.
Definition: efi_driver.h:21
UINT32 State
Reports the current state of the network interface.
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1987
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
struct io_buffer * rxbuf
Current receive buffer.
Definition: snpnet.c:64
#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
EFI_MAC_ADDRESS CurrentAddress
The current HW MAC address for the network interface.
EFI utilities.
#define ECANCELED
Operation canceled.
Definition: errno.h:343
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
EFI_SIMPLE_NETWORK_MODE * Mode
Pointer to the EFI_SIMPLE_NETWORK_MODE data for the device.
int snpnet_start(struct efi_device *efidev)
Attach driver to device.
Definition: snpnet.c:541
EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]
Array containing the addresses of the current multicast address receive filters.
EFI_MAC_ADDRESS BroadcastAddress
The current HW MAC address for broadcast packets.
static const char * snpnet_mac_text(EFI_MAC_ADDRESS *mac, size_t len)
Format SNP MAC address (for debugging)
Definition: snpnet.c:96
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition: vsprintf.c:420
BOOLEAN MultipleTxSupported
TRUE if the network interface can transmit more than one packet at a time.
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:515
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
UINT8 IfType
The interface type of the network interface.
#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL
Definition: UefiSpec.h:1345
UINT32 MaxPacketSize
The maximum size, in bytes, of the packets supported by the network interface.
#define ENOMEM
Not enough space.
Definition: errno.h:534
A hardware device.
Definition: device.h:73
void * memcpy(void *dest, const void *src, size_t len) __nonnull
FILE_LICENCE(GPL2_OR_LATER)
UINT32 ReceiveFilterSetting
The current multicast receive filter settings.
UINT32 MCastFilterCount
The current number of multicast address receive filters.
EFI_SIMPLE_NETWORK_INITIALIZE Initialize
struct io_buffer * txbuf
Current transmit buffer.
Definition: snpnet.c:62
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
Ethernet protocol.
An object interface.
Definition: interface.h:124
uint8_t hw_addr_len
Hardware address length.
Definition: netdevice.h:196
void * priv
Driver private data.
Definition: netdevice.h:431
EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown
EFI_SIMPLE_NETWORK_GET_STATUS GetStatus
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition: netdevice.h:774
The EFI_SIMPLE_NETWORK_PROTOCOL provides services to initialize a network interface,...
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
static void snpnet_check_link(struct net_device *netdev)
Check link state.
Definition: snpnet.c:153
EFI_SIMPLE_NETWORK_TRANSMIT Transmit
static void snpnet_close(struct net_device *netdev)
Close network device.
Definition: snpnet.c:453
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
BOOLEAN MacAddressChangeable
TRUE if the HW MAC address can be changed.
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_debug.c:254
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
static void * efidev_get_drvdata(struct efi_device *efidev)
Get EFI driver-private data.
Definition: efi_driver.h:85
A network device.
Definition: netdevice.h:352
An SNP NIC.
Definition: snpnet.c:46
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:175
struct device dev
Generic device.
Definition: snpnet.c:52
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:528
UINT32 NvRamAccessSize
The size that must be used for all NVRAM reads and writes.
SNP NIC driver.
UINT64 UINTN
Unsigned value of native width.
#define EFI_NOT_READY
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:120
An EFI device.
Definition: efi_driver.h:17
#define SNP_RX_QUOTA
Maximum number of received packets per poll.
Definition: snpnet.c:68
static int snpnet_open(struct net_device *netdev)
Open network device.
Definition: snpnet.c:371
static int snpnet_rx_filters(struct net_device *netdev)
Set receive filters.
Definition: snpnet.c:331
static void snpnet_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition: snpnet.c:217
#define ETH_ZLEN
Definition: if_ether.h:10
#define SNP_INITIALIZE_RETRY_MAX
Maximum initialisation retry count.
Definition: snpnet.c:71
int efi_locate_device(EFI_HANDLE device, EFI_GUID *protocol, EFI_HANDLE *parent, unsigned int skip)
Locate parent device supporting a given protocol.
Definition: efi_utils.c:45
EFI_SIMPLE_NETWORK_START Start
#define VOID
Undeclared type.
Definition: Base.h:271
struct efi_device * efidev
EFI device.
Definition: snpnet.c:48
#define TRUE
Definition: tlan.h:46
EFI API.
Network device operations.
Definition: netdevice.h:213
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:548
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
EFI_SIMPLE_NETWORK_RECEIVE Receive
Network device management.
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
struct efi_snp_device * find_snpdev(EFI_HANDLE handle)
Find SNP device by EFI device handle.
Definition: efi_snp.c:2118
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition: netdevice.c:470
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:362
#define DBGC2(...)
Definition: compiler.h:522
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
UINT32 HwAddressSize
The size, in bytes, of the network interface's HW address.
UINT32 MaxMCastFilterCount
The maximum number of multicast address receive filters supported by the driver.
void * data
Start of data.
Definition: iobuf.h:48
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
struct list_head children
Devices attached to this device.
Definition: device.h:83
UINT32 ReceiveFilterMask
The multicast receive filter settings supported by the network interface.
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
#define DBGCP(...)
Definition: compiler.h:539
static void snpnet_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition: snpnet.c:258
#define FALSE
Definition: tlan.h:45
#define SNP_INITIALIZE_RETRY_DELAY_MS
Delay between each initialisation retry.
Definition: snpnet.c:74
EFI_SIMPLE_NETWORK_RECEIVE_FILTERS ReceiveFilters
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1986
uint16_t protocol
Protocol ID.
Definition: stp.h:18
iPXE EFI SNP interface
EFI_SIMPLE_NETWORK_STOP Stop
#define DBG_EXTRA
Definition: compiler.h:319
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
static void efidev_set_drvdata(struct efi_device *efidev, void *priv)
Set EFI driver-private data.
Definition: efi_driver.h:74
struct device dev
Generic device.
Definition: efi_driver.h:19
uint32_t len
Length.
Definition: ena.h:14
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition: iobpad.c:49
static struct net_device_operations snpnet_operations
SNP network device operations.
Definition: snpnet.c:481
Definition: efi.h:59
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:372
size_t mtu
Maximum packet size.
Definition: snpnet.c:59
void efi_device_info(EFI_HANDLE device, const char *prefix, struct device *dev)
Get underlying device information.
Definition: efi_utils.c:209
EFI_MAC_ADDRESS PermanentAddress
The permanent HW MAC address for the network interface.
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:58
A persistent I/O buffer.
Definition: iobuf.h:33