[efi] Add efi_path_vlan() utility function

EFI provides no API for determining the VLAN tag (if any) for a
specified device handle.  There is the EFI_VLAN_CONFIG_PROTOCOL, but
that exists only on the trunk device handle (not on the VLAN device
handle), and provides no way to match VLAN tags against the trunk
device's child device handles.

The EDK2 codebase seems to rely solely on the device path to determine
the VLAN tag for a specified device handle: both NetLibGetVlanId() and
BmGetNetworkDescription() will parse the device path to search for a
VLAN_DEVICE_PATH component.

Add efi_path_vlan() which uses the same device path parsing logic to
determine the VLAN tag.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/844/head
Michael Brown 2022-12-22 14:27:56 +00:00
parent 099e4d39b3
commit b9571ca12e
2 changed files with 24 additions and 0 deletions

View File

@ -26,6 +26,7 @@ efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path );
extern EFI_DEVICE_PATH_PROTOCOL *
efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
extern unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path );
extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first,
... );
extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );

View File

@ -94,6 +94,29 @@ size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
return ( ( ( void * ) end ) - ( ( void * ) path ) );
}
/**
* Get VLAN tag from device path
*
* @v path Device path
* @ret tag VLAN tag, or 0 if not a VLAN
*/
unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path ) {
EFI_DEVICE_PATH_PROTOCOL *next;
VLAN_DEVICE_PATH *vlan;
/* Search for VLAN device path */
for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
( path->SubType == MSG_VLAN_DP ) ) {
vlan = container_of ( path, VLAN_DEVICE_PATH, Header );
return vlan->VlanId;
}
}
/* No VLAN device path found */
return 0;
}
/**
* Concatenate EFI device paths
*