mirror of
https://gitlab.com/qemu-project/ipxe.git
synced 2025-11-03 07:59:06 +08:00
Compare commits
2 Commits
loongarch6
...
efivlan
| Author | SHA1 | Date | |
|---|---|---|---|
| a2fff570be | |||
| 0bde40d4ba |
@ -19,9 +19,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/efi/Protocol/PxeBaseCode.h>
|
||||
#include <ipxe/efi/Protocol/SimpleNetwork.h>
|
||||
#include <ipxe/efi/Protocol/UsbIo.h>
|
||||
#include <ipxe/efi/Protocol/VlanConfig.h>
|
||||
|
||||
extern void efi_nullify_snp ( EFI_SIMPLE_NETWORK_PROTOCOL *snp );
|
||||
extern void efi_nullify_nii ( EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii );
|
||||
extern void efi_nullify_vlan ( EFI_VLAN_CONFIG_PROTOCOL *vcfg );
|
||||
extern void efi_nullify_name2 ( EFI_COMPONENT_NAME2_PROTOCOL *name2 );
|
||||
extern void efi_nullify_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file );
|
||||
extern void efi_nullify_hii ( EFI_HII_CONFIG_ACCESS_PROTOCOL *hii );
|
||||
|
||||
@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#include <ipxe/efi/Protocol/HiiConfigAccess.h>
|
||||
#include <ipxe/efi/Protocol/HiiDatabase.h>
|
||||
#include <ipxe/efi/Protocol/LoadFile.h>
|
||||
#include <ipxe/efi/Protocol/VlanConfig.h>
|
||||
|
||||
/** SNP transmit completion ring size */
|
||||
#define EFI_SNP_NUM_TX 32
|
||||
@ -51,6 +52,8 @@ struct efi_snp_device {
|
||||
struct list_head rx;
|
||||
/** The network interface identifier */
|
||||
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL nii;
|
||||
/** VLAN configuration protocol */
|
||||
EFI_VLAN_CONFIG_PROTOCOL vcfg;
|
||||
/** Component name protocol */
|
||||
EFI_COMPONENT_NAME2_PROTOCOL name2;
|
||||
/** Load file protocol handle */
|
||||
|
||||
@ -61,7 +61,21 @@ struct vlan_header {
|
||||
*/
|
||||
#define VLAN_PRIORITY_IS_VALID( priority ) ( (priority) <= 7 )
|
||||
|
||||
extern unsigned int vlan_tag ( struct net_device *netdev );
|
||||
extern unsigned int vlan_tci ( struct net_device *netdev );
|
||||
|
||||
/**
|
||||
* Get the VLAN tag
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret tag VLAN tag, or 0 if device is not a VLAN device
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
vlan_tag ( struct net_device *netdev ) {
|
||||
return VLAN_TAG ( vlan_tci ( netdev ) );
|
||||
}
|
||||
|
||||
extern struct net_device * vlan_find ( struct net_device *trunk,
|
||||
unsigned int tag );
|
||||
extern int vlan_can_be_trunk ( struct net_device *trunk );
|
||||
extern int vlan_create ( struct net_device *trunk, unsigned int tag,
|
||||
unsigned int priority );
|
||||
|
||||
@ -193,6 +193,48 @@ void efi_nullify_nii ( EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii ) {
|
||||
nii->Id = ( ( intptr_t ) &efi_null_undi );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* VLAN configuration protocol
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
efi_null_vlan_set ( EFI_VLAN_CONFIG_PROTOCOL *vcfg __unused,
|
||||
UINT16 tag __unused, UINT8 priority __unused ) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
efi_null_vlan_find ( EFI_VLAN_CONFIG_PROTOCOL *vcfg __unused,
|
||||
UINT16 *filter __unused, UINT16 *count __unused,
|
||||
EFI_VLAN_FIND_DATA **entries __unused ) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static EFI_STATUS EFIAPI
|
||||
efi_null_vlan_remove ( EFI_VLAN_CONFIG_PROTOCOL *vcfg __unused,
|
||||
UINT16 tag __unused ) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static EFI_VLAN_CONFIG_PROTOCOL efi_null_vlan = {
|
||||
.Set = efi_null_vlan_set,
|
||||
.Find = efi_null_vlan_find,
|
||||
.Remove = efi_null_vlan_remove,
|
||||
};
|
||||
|
||||
/**
|
||||
* Nullify VLAN configuration interface
|
||||
*
|
||||
* @v vcfg VLAN configuration protocol
|
||||
*/
|
||||
void efi_nullify_vlan ( EFI_VLAN_CONFIG_PROTOCOL *vcfg ) {
|
||||
|
||||
memcpy ( vcfg, &efi_null_vlan, sizeof ( *vcfg ) );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Component name protocol
|
||||
|
||||
@ -1488,6 +1488,135 @@ static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii = {
|
||||
.Ipv6Supported = TRUE, /* This is a raw packet interface, FFS! */
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* VLAN configuration protocol
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create or modify VLAN device
|
||||
*
|
||||
* @v vcfg VLAN configuration protocol
|
||||
* @v tag VLAN tag
|
||||
* @v priority Default VLAN priority
|
||||
* @ret efirc EFI status code
|
||||
*/
|
||||
static EFI_STATUS EFIAPI efi_vlan_set ( EFI_VLAN_CONFIG_PROTOCOL *vcfg,
|
||||
UINT16 tag, UINT8 priority ) {
|
||||
struct efi_snp_device *snpdev =
|
||||
container_of ( vcfg, struct efi_snp_device, vcfg );
|
||||
struct net_device *trunk = snpdev->netdev;
|
||||
int rc;
|
||||
|
||||
/* Create or modify VLAN device */
|
||||
if ( ( rc = vlan_create ( trunk, tag, priority ) ) != 0 ) {
|
||||
DBGC ( snpdev, "SNPDEV %p could not create VLAN tag %d: %s\n",
|
||||
snpdev, tag, strerror ( rc ) );
|
||||
return EFIRC ( rc );
|
||||
}
|
||||
|
||||
DBGC ( snpdev, "SNPDEV %p created VLAN tag %d priority %d\n",
|
||||
snpdev, tag, priority );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find VLAN device(s)
|
||||
*
|
||||
* @v vcfg VLAN configuration protocol
|
||||
* @v filter VLAN tag, or NULL to find all VLANs
|
||||
* @v count Number of VLANs
|
||||
* @v entries List of VLANs
|
||||
* @ret efirc EFI status code
|
||||
*/
|
||||
static EFI_STATUS EFIAPI efi_vlan_find ( EFI_VLAN_CONFIG_PROTOCOL *vcfg,
|
||||
UINT16 *filter, UINT16 *count,
|
||||
EFI_VLAN_FIND_DATA **entries ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
struct efi_snp_device *snpdev =
|
||||
container_of ( vcfg, struct efi_snp_device, vcfg );
|
||||
struct net_device *trunk = snpdev->netdev;
|
||||
struct net_device *vlan;
|
||||
EFI_VLAN_FIND_DATA *entry;
|
||||
VOID *buffer;
|
||||
unsigned int tag;
|
||||
unsigned int tci;
|
||||
size_t len;
|
||||
EFI_STATUS efirc;
|
||||
|
||||
/* Count number of matching VLANs */
|
||||
*count = 0;
|
||||
for ( tag = 1 ; VLAN_TAG_IS_VALID ( tag ) ; tag++ ) {
|
||||
if ( filter && ( tag != *filter ) )
|
||||
continue;
|
||||
if ( ! ( vlan = vlan_find ( trunk, tag ) ) )
|
||||
continue;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
/* Allocate buffer to hold results */
|
||||
len = ( (*count) * sizeof ( *entry ) );
|
||||
if ( ( efirc = bs->AllocatePool ( EfiBootServicesData, len,
|
||||
&buffer ) ) != 0 )
|
||||
return efirc;
|
||||
|
||||
/* Fill in buffer */
|
||||
*entries = buffer;
|
||||
entry = *entries;
|
||||
for ( tag = 1 ; VLAN_TAG_IS_VALID ( tag ) ; tag++ ) {
|
||||
if ( filter && ( tag != *filter ) )
|
||||
continue;
|
||||
if ( ! ( vlan = vlan_find ( trunk, tag ) ) )
|
||||
continue;
|
||||
tci = vlan_tci ( vlan );
|
||||
entry->VlanId = VLAN_TAG ( tci );
|
||||
entry->Priority = VLAN_PRIORITY ( tci );
|
||||
assert ( entry->VlanId == tag );
|
||||
entry++;
|
||||
}
|
||||
assert ( entry == &(*entries)[*count] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove VLAN device
|
||||
*
|
||||
* @v vcfg VLAN configuration protocol
|
||||
* @v tag VLAN tag
|
||||
* @ret efirc EFI status code
|
||||
*/
|
||||
static EFI_STATUS EFIAPI efi_vlan_remove ( EFI_VLAN_CONFIG_PROTOCOL *vcfg,
|
||||
UINT16 tag ) {
|
||||
struct efi_snp_device *snpdev =
|
||||
container_of ( vcfg, struct efi_snp_device, vcfg );
|
||||
struct net_device *trunk = snpdev->netdev;
|
||||
struct net_device *vlan;
|
||||
|
||||
/* Identify VLAN device */
|
||||
vlan = vlan_find ( trunk, tag );
|
||||
if ( ! vlan ) {
|
||||
DBGC ( snpdev, "SNPDEV %p could not find VLAN tag %d\n",
|
||||
snpdev, tag );
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Remove VLAN device */
|
||||
vlan_destroy ( vlan );
|
||||
|
||||
DBGC ( snpdev, "SNPDEV %p removed VLAN tag %d\n", snpdev, tag );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** VLAN configuration protocol */
|
||||
static EFI_VLAN_CONFIG_PROTOCOL efi_vlan = {
|
||||
.Set = efi_vlan_set,
|
||||
.Find = efi_vlan_find,
|
||||
.Remove = efi_vlan_remove,
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Component name protocol
|
||||
@ -1687,6 +1816,9 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||
efi_snp_undi.Fudge -= efi_undi_checksum ( &efi_snp_undi,
|
||||
sizeof ( efi_snp_undi ) );
|
||||
|
||||
/* Populate the VLAN configuration protocol */
|
||||
memcpy ( &snpdev->vcfg, &efi_vlan, sizeof ( snpdev->vcfg ) );
|
||||
|
||||
/* Populate the component name structure */
|
||||
efi_snprintf ( snpdev->driver_name,
|
||||
( sizeof ( snpdev->driver_name ) /
|
||||
@ -1725,6 +1857,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||
&efi_device_path_protocol_guid, snpdev->path,
|
||||
&efi_nii_protocol_guid, &snpdev->nii,
|
||||
&efi_nii31_protocol_guid, &snpdev->nii,
|
||||
&efi_vlan_config_protocol_guid, &snpdev->vcfg,
|
||||
&efi_component_name2_protocol_guid, &snpdev->name2,
|
||||
&efi_load_file_protocol_guid, &snpdev->load_file,
|
||||
NULL ) ) != 0 ) {
|
||||
@ -1811,6 +1944,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||
&efi_device_path_protocol_guid, snpdev->path,
|
||||
&efi_nii_protocol_guid, &snpdev->nii,
|
||||
&efi_nii31_protocol_guid, &snpdev->nii,
|
||||
&efi_vlan_config_protocol_guid, &snpdev->vcfg,
|
||||
&efi_component_name2_protocol_guid, &snpdev->name2,
|
||||
&efi_load_file_protocol_guid, &snpdev->load_file,
|
||||
NULL ) ) != 0 ) {
|
||||
@ -1820,6 +1954,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||
}
|
||||
efi_nullify_snp ( &snpdev->snp );
|
||||
efi_nullify_nii ( &snpdev->nii );
|
||||
efi_nullify_vlan ( &snpdev->vcfg );
|
||||
efi_nullify_name2 ( &snpdev->name2 );
|
||||
efi_nullify_load_file ( &snpdev->load_file );
|
||||
err_install_protocol_interface:
|
||||
|
||||
@ -1171,12 +1171,12 @@ static void net_step ( struct process *process __unused ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the VLAN tag (when VLAN support is not present)
|
||||
* Get the VLAN tag control information (when VLAN support is not present)
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret tag 0, indicating that device is not a VLAN device
|
||||
*/
|
||||
__weak unsigned int vlan_tag ( struct net_device *netdev __unused ) {
|
||||
__weak unsigned int vlan_tci ( struct net_device *netdev __unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -199,8 +199,7 @@ static void vlan_sync ( struct net_device *netdev ) {
|
||||
* @v tag VLAN tag
|
||||
* @ret netdev VLAN device, if any
|
||||
*/
|
||||
static struct net_device * vlan_find ( struct net_device *trunk,
|
||||
unsigned int tag ) {
|
||||
struct net_device * vlan_find ( struct net_device *trunk, unsigned int tag ) {
|
||||
struct net_device *netdev;
|
||||
struct vlan_device *vlan;
|
||||
|
||||
@ -288,17 +287,17 @@ struct net_protocol vlan_protocol __net_protocol = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the VLAN tag
|
||||
* Get the VLAN tag control information
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret tag VLAN tag, or 0 if device is not a VLAN device
|
||||
* @ret tci VLAN tag control information, or 0 if not a VLAN device
|
||||
*/
|
||||
unsigned int vlan_tag ( struct net_device *netdev ) {
|
||||
unsigned int vlan_tci ( struct net_device *netdev ) {
|
||||
struct vlan_device *vlan;
|
||||
|
||||
if ( netdev->op == &vlan_operations ) {
|
||||
vlan = netdev->priv;
|
||||
return vlan->tag;
|
||||
return ( VLAN_TCI ( vlan->tag, vlan->priority ) );
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user