[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>
pull/171/head
Michael Brown 2020-11-21 13:19:27 +00:00
parent b6eb17cbd7
commit 76a7bfe939
2 changed files with 9 additions and 2 deletions

View File

@ -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 );

View File

@ -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) \