aboutsummaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2020-11-21 13:19:27 +0000
committerMichael Brown <mcb30@ipxe.org>2020-11-21 13:35:11 +0000
commit76a7bfe939b4b6ea88690e8c6960c65d57c01b5e (patch)
tree473a19a882a6cc0989d2c30a2cc52ba65c091236 /src/drivers
parentb6eb17cbd790b8336a9a5fe1878008f905642c9b (diff)
downloadipxe-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.c6
-rw-r--r--src/drivers/net/intelxl.h5
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) \