bnx2x: Obtain Bus Device Function from register
authorAriel Elior <ariele@broadcom.com>
Thu, 26 Jan 2012 06:01:47 +0000 (06:01 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 26 Jan 2012 18:39:51 +0000 (13:39 -0500)
BDF was obtained from kernel but since in virtualized environment
(e.g. physical device assigment in KVM) the function number may
not be the real one, the info must be obtained from the device.

Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h

index e56b8326652e20bd42cc17e888a3cd6a041707d8..115d77a8bebbb8630980f90d01422036111bf37c 100644 (file)
@@ -10546,6 +10546,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 {
        struct bnx2x *bp;
        int rc;
+       u32 pci_cfg_dword;
        bool chip_is_e1x = (board_type == BCM57710 ||
                            board_type == BCM57711 ||
                            board_type == BCM57711E);
@@ -10556,7 +10557,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
        bp->dev = dev;
        bp->pdev = pdev;
        bp->flags = 0;
-       bp->pf_num = PCI_FUNC(pdev->devfn);
 
        rc = pci_enable_device(pdev);
        if (rc) {
@@ -10623,6 +10623,21 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
                goto err_out_release;
        }
 
+       /* In E1/E1H use pci device function given by kernel.
+        * In E2/E3 read physical function from ME register since these chips
+        * support Physical Device Assignment where kernel BDF maybe arbitrary
+        * (depending on hypervisor).
+        */
+       if (chip_is_e1x)
+               bp->pf_num = PCI_FUNC(pdev->devfn);
+       else {/* chip is E2/3*/
+               pci_read_config_dword(bp->pdev,
+                                     PCICFG_ME_REGISTER, &pci_cfg_dword);
+               bp->pf_num = (u8)((pci_cfg_dword & ME_REG_ABS_PF_NUM) >>
+                   ME_REG_ABS_PF_NUM_SHIFT);
+       }
+       DP(BNX2X_MSG_SP, "me reg PF num: %d\n", bp->pf_num);
+
        bnx2x_set_power_state(bp, PCI_D0);
 
        /* clean indirect addresses */
index dddbcf6e154ec58d8d1f0720706df5ad0076c338..8c79e00b37e8c14a77e4b1c888c3bb26959ca936 100644 (file)
 #define PCICFG_MSI_CONTROL_64_BIT_ADDR_CAP     (0x1<<23)
 #define PCICFG_MSI_CONTROL_MSI_PVMASK_CAPABLE  (0x1<<24)
 #define PCICFG_GRC_ADDRESS                             0x78
-#define PCICFG_GRC_DATA                                0x80
+#define PCICFG_GRC_DATA                                0x80
+#define PCICFG_ME_REGISTER                             0x98
 #define PCICFG_MSIX_CAP_ID_OFFSET                      0xa0
 #define PCICFG_MSIX_CONTROL_TABLE_SIZE         (0x7ff<<16)
 #define PCICFG_MSIX_CONTROL_RESERVED           (0x7<<27)