#include <ipxe/efi/efi.h>
-extern int efi_set_autoboot_ll_addr ( EFI_HANDLE device );
+extern int efi_set_autoboot_ll_addr ( EFI_HANDLE device,
+ EFI_DEVICE_PATH_PROTOCOL *path );
#endif /* _IPXE_EFI_AUTOBOOT_H */
extern void set_autoboot_busloc ( unsigned int bus_type,
unsigned int location );
-extern void set_autoboot_ll_addr ( const void *ll_addr, size_t len );
+extern void set_autoboot_ll_addr ( const void *ll_addr, size_t len,
+ unsigned int vlan );
extern int uriboot ( struct uri *filename, struct uri **root_paths,
unsigned int root_path_count, int drive,
#include <string.h>
#include <errno.h>
#include <ipxe/efi/efi.h>
+#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_autoboot.h>
#include <ipxe/efi/Protocol/SimpleNetwork.h>
#include <usr/autoboot.h>
* Identify autoboot device
*
* @v device Device handle
+ * @v path Device path
* @ret rc Return status code
*/
-int efi_set_autoboot_ll_addr ( EFI_HANDLE device ) {
+int efi_set_autoboot_ll_addr ( EFI_HANDLE device,
+ EFI_DEVICE_PATH_PROTOCOL *path ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
union {
EFI_SIMPLE_NETWORK_PROTOCOL *snp;
} snp;
EFI_SIMPLE_NETWORK_MODE *mode;
EFI_STATUS efirc;
+ unsigned int vlan;
int rc;
/* Look for an SNP instance on the image's device handle */
/* Record autoboot device */
mode = snp.snp->Mode;
- set_autoboot_ll_addr ( &mode->CurrentAddress, mode->HwAddressSize );
+ vlan = efi_path_vlan ( path );
+ set_autoboot_ll_addr ( &mode->CurrentAddress, mode->HwAddressSize,
+ vlan );
DBGC ( device, "EFI %s found autoboot link-layer address:\n",
efi_handle_name ( device ) );
DBGC_HDA ( device, 0, &mode->CurrentAddress, mode->HwAddressSize );
+ if ( vlan ) {
+ DBGC ( device, "EFI %s found autoboot VLAN %d\n",
+ efi_handle_name ( device ), vlan );
+ }
/* Close protocol */
bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
EFI_DEVICE_PATH_PROTOCOL *path = efi_loaded_image_path;
/* Identify autoboot device, if any */
- efi_set_autoboot_ll_addr ( device );
+ efi_set_autoboot_ll_addr ( device, path );
/* Store cached DHCP packet, if any */
efi_cachedhcp_record ( device, path );
#include <stdio.h>
#include <errno.h>
#include <ipxe/netdevice.h>
+#include <ipxe/vlan.h>
#include <ipxe/dhcp.h>
#include <ipxe/settings.h>
#include <ipxe/image.h>
/** Link-layer address of preferred autoboot device, if known */
static uint8_t autoboot_ll_addr[MAX_LL_ADDR_LEN];
+/** VLAN tag of preferred autoboot device, if known */
+static unsigned int autoboot_vlan;
+
/** Device location of preferred autoboot device, if known */
static struct device_description autoboot_desc;
*/
static int is_autoboot_ll_addr ( struct net_device *netdev ) {
- return ( memcmp ( netdev->ll_addr, autoboot_ll_addr,
- netdev->ll_protocol->ll_addr_len ) == 0 );
+ return ( ( memcmp ( netdev->ll_addr, autoboot_ll_addr,
+ netdev->ll_protocol->ll_addr_len ) == 0 ) &&
+ ( vlan_tag ( netdev ) == autoboot_vlan ) );
}
/**
*
* @v ll_addr Link-layer address
* @v len Length of link-layer address
+ * @v vlan VLAN tag
*/
-void set_autoboot_ll_addr ( const void *ll_addr, size_t len ) {
+void set_autoboot_ll_addr ( const void *ll_addr, size_t len,
+ unsigned int vlan ) {
/* Record autoboot link-layer address (truncated if necessary) */
if ( len > sizeof ( autoboot_ll_addr ) )
len = sizeof ( autoboot_ll_addr );
memcpy ( autoboot_ll_addr, ll_addr, len );
+ /* Record autoboot VLAN tag */
+ autoboot_vlan = vlan;
+
/* Mark autoboot device as present */
is_autoboot_device = is_autoboot_ll_addr;
}