diff options
author | Michael Brown <mcb30@ipxe.org> | 2019-04-27 20:21:22 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2019-04-27 20:25:57 +0100 |
commit | c901b5ca455659002cedb61a73fa080c9955e737 (patch) | |
tree | 10b3884af97b938ab534767e653ec2fe0c1da9db /src/drivers/net/intelxl.c | |
parent | fe680c8228563369804948010954128aacb7db74 (diff) | |
download | ipxe-c901b5ca455659002cedb61a73fa080c9955e737.tar.gz |
[intelxl] Use VLAN tag in receive descriptor if present
The physical function driver does not allow the virtual function to
request that VLAN tags are left unstripped. Extract and use the VLAN
tag from the receive descriptor if present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/intelxl.c')
-rw-r--r-- | src/drivers/net/intelxl.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index 3e40fa4ae..66221cbaf 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/netdevice.h> #include <ipxe/ethernet.h> #include <ipxe/if_ether.h> +#include <ipxe/vlan.h> #include <ipxe/iobuf.h> #include <ipxe/malloc.h> #include <ipxe/pci.h> @@ -1254,6 +1255,7 @@ static void intelxl_poll_rx ( struct net_device *netdev ) { struct intelxl_rx_writeback_descriptor *rx_wb; struct io_buffer *iobuf; unsigned int rx_idx; + unsigned int tag; size_t len; /* Check for received packets */ @@ -1273,16 +1275,23 @@ static void intelxl_poll_rx ( struct net_device *netdev ) { len = INTELXL_RX_WB_LEN ( le32_to_cpu ( rx_wb->len ) ); iob_put ( iobuf, len ); + /* Find VLAN device, if applicable */ + if ( rx_wb->flags & cpu_to_le32 ( INTELXL_RX_WB_FL_VLAN ) ) { + tag = VLAN_TAG ( le16_to_cpu ( rx_wb->vlan ) ); + } else { + tag = 0; + } + /* Hand off to network stack */ if ( rx_wb->flags & cpu_to_le32 ( INTELXL_RX_WB_FL_RXE ) ) { DBGC ( intelxl, "INTELXL %p RX %d error (length %zd, " "flags %08x)\n", intelxl, rx_idx, len, le32_to_cpu ( rx_wb->flags ) ); - netdev_rx_err ( netdev, iobuf, -EIO ); + vlan_netdev_rx_err ( netdev, tag, iobuf, -EIO ); } else { DBGC2 ( intelxl, "INTELXL %p RX %d complete (length " "%zd)\n", intelxl, rx_idx, len ); - netdev_rx ( netdev, iobuf ); + vlan_netdev_rx ( netdev, tag, iobuf ); } intelxl->rx.cons++; } |