]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
tg3: Determine PCI function number in one place
authorMatt Carlson <mcarlson@broadcom.com>
Wed, 13 Jul 2011 09:27:30 +0000 (09:27 +0000)
committerJoe Jin <joe.jin@oracle.com>
Tue, 15 May 2012 08:32:10 +0000 (16:32 +0800)
tg3 devices will need to know exactly what function number they are so
that they can communicate their status to the other functions.  In a KVM
environment, the function number of a device presented by the kernel
might not be the true function number, so an alternative method to
determine the function number is needed.

This patch used to contain an implementation for the alternative method,
but recently we discovered a hardware bug that renders it incorrect.
While new method is not yet known, it is still useful to consolidate the
code that determines the PCI function to one location and use the
results throughout the code.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 69f11c9936ba310ed3620072983da6ed95e86cc0)

Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/tg3.c
drivers/net/tg3.h

index a942ff53bd33245df4228c469f1ce9f19beb861a..df7a6fde6806a94c43628ea119dd8cb4889cd7a9 100644 (file)
@@ -1169,7 +1169,7 @@ static int tg3_mdio_init(struct tg3 *tp)
        if (tg3_flag(tp, 5717_PLUS)) {
                u32 is_serdes;
 
-               tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1;
+               tp->phy_addr = tp->pci_fn + 1;
 
                if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0)
                        is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
@@ -13907,6 +13907,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        val = tr32(MEMARB_MODE);
        tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
 
+       if (tg3_flag(tp, PCIX_MODE)) {
+               pci_read_config_dword(tp->pdev,
+                                     tp->pcix_cap + PCI_X_STATUS, &val);
+               tp->pci_fn = val & 0x7;
+       } else {
+               tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3;
+       }
+
        /* Get eeprom hw config before calling tg3_set_power_state().
         * In particular, the TG3_FLAG_IS_NIC flag must be
         * determined before calling tg3_set_power_state() so that
@@ -14272,9 +14280,9 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
                else
                        tg3_nvram_unlock(tp);
        } else if (tg3_flag(tp, 5717_PLUS)) {
-               if (PCI_FUNC(tp->pdev->devfn) & 1)
+               if (tp->pci_fn & 1)
                        mac_offset = 0xcc;
-               if (PCI_FUNC(tp->pdev->devfn) > 1)
+               if (tp->pci_fn > 1)
                        mac_offset += 0x18c;
        } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                mac_offset = 0x10;
index 2077d52141f5524c1dfaec03f98e04a197f480d2..06e70523762b06afb9b184c50a1cc02f2e674c0a 100644 (file)
@@ -3017,6 +3017,7 @@ struct tg3 {
        u8                              pci_cacheline_sz;
        u8                              pci_lat_timer;
 
+       int                             pci_fn;
        int                             pm_cap;
        int                             msi_cap;
        int                             pcix_cap;