diff options
author | Michael Brown <mcb30@ipxe.org> | 2020-11-21 13:19:27 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2020-11-21 13:35:11 +0000 |
commit | 76a7bfe939b4b6ea88690e8c6960c65d57c01b5e (patch) | |
tree | 473a19a882a6cc0989d2c30a2cc52ba65c091236 /src/drivers | |
parent | b6eb17cbd790b8336a9a5fe1878008f905642c9b (diff) | |
download | ipxe-76a7bfe939b4b6ea88690e8c6960c65d57c01b5e.zip ipxe-76a7bfe939b4b6ea88690e8c6960c65d57c01b5e.tar.gz ipxe-76a7bfe939b4b6ea88690e8c6960c65d57c01b5e.tar.bz2 |
[intelxl] Read PCI bus:dev.fn number from PFFUNC_RID register
For the physical function driver, the transmit queue needs to be
configured to be associated with the relevant physical function
number. This is currently obtained from the bus:dev.fn address of the
underlying PCI device.
In the case of a virtual machine using the physical function via PCI
passthrough, the PCI bus:dev.fn address within the virtual machine is
unrelated to the real physical function number. Such a function will
typically be presented to the virtual machine as a single-function
device. The function number extracted from the PCI bus:dev.fn address
will therefore always be zero.
Fix by reading from the Function Requester ID Information Register,
which always returns the real PCI bus:dev.fn address as used by the
physical host.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/net/intelxl.c | 6 | ||||
-rw-r--r-- | src/drivers/net/intelxl.h | 5 |
2 files changed, 9 insertions, 2 deletions
diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index fda8eff..d929f48 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -1643,6 +1643,7 @@ static struct net_device_operations intelxl_operations = { static int intelxl_probe ( struct pci_device *pci ) { struct net_device *netdev; struct intelxl_nic *intelxl; + uint32_t pffunc_rid; uint32_t pfgen_portnum; uint32_t pflan_qalloc; int rc; @@ -1658,7 +1659,6 @@ static int intelxl_probe ( struct pci_device *pci ) { pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; memset ( intelxl, 0, sizeof ( *intelxl ) ); - intelxl->pf = PCI_FUNC ( pci->busdevfn ); intelxl->intr = INTELXL_PFINT_DYN_CTL0; intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD, &intelxl_admin_offsets ); @@ -1685,7 +1685,9 @@ static int intelxl_probe ( struct pci_device *pci ) { if ( ( rc = intelxl_reset ( intelxl ) ) != 0 ) goto err_reset; - /* Get port number and base queue number */ + /* Get function number, port number and base queue number */ + pffunc_rid = readl ( intelxl->regs + INTELXL_PFFUNC_RID ); + intelxl->pf = INTELXL_PFFUNC_RID_FUNC_NUM ( pffunc_rid ); pfgen_portnum = readl ( intelxl->regs + INTELXL_PFGEN_PORTNUM ); intelxl->port = INTELXL_PFGEN_PORTNUM_PORT_NUM ( pfgen_portnum ); pflan_qalloc = readl ( intelxl->regs + INTELXL_PFLAN_QALLOC ); diff --git a/src/drivers/net/intelxl.h b/src/drivers/net/intelxl.h index 2d33ed8..ef9152f 100644 --- a/src/drivers/net/intelxl.h +++ b/src/drivers/net/intelxl.h @@ -985,6 +985,11 @@ intelxl_init_ring ( struct intelxl_ring *ring, unsigned int count, size_t len, /** Time to delay for device reset, in milliseconds */ #define INTELXL_RESET_DELAY_MS 100 +/** Function Requester ID Information Register */ +#define INTELXL_PFFUNC_RID 0x09c000 +#define INTELXL_PFFUNC_RID_FUNC_NUM(x) \ + ( ( (x) >> 0 ) & 0x3 ) /**< Function number */ + /** PF Queue Allocation Register */ #define INTELXL_PFLAN_QALLOC 0x1c0400 #define INTELXL_PFLAN_QALLOC_FIRSTQ(x) \ |