tg3: improve PCI VPD access
authorHeiner Kallweit <hkallweit1@gmail.com>
Fri, 22 Jan 2021 12:08:22 +0000 (13:08 +0100)
committerJakub Kicinski <kuba@kernel.org>
Mon, 25 Jan 2021 23:24:19 +0000 (15:24 -0800)
When working on the PCI VPD code I also tested with a Broadcom BCM95719
card. tg3 uses internal NVRAM access with this card, so I forced it to
PCI VPD mode for testing. PCI VPD access fails
(i + PCI_VPD_LRDT_TAG_SIZE + j > len) because only TG3_NVM_VPD_LEN (256)
bytes are read, but PCI VPD has 400 bytes on this card.

So add a constant TG3_NVM_PCI_VPD_MAX_LEN that defines the maximum
PCI VPD size. The actual VPD size is returned by pci_read_vpd().
In addition it's not worth looping over pci_read_vpd(). If we miss the
125ms timeout per VPD dword read then definitely something is wrong,
and if the tg3 module loading is killed then there's also not much
benefit in retrying the VPD read.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Link: https://lore.kernel.org/r/cb9e9113-0861-3904-87e0-d4c4ab3c8860@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h

index 5143cdd..8936c2b 100644 (file)
@@ -12826,11 +12826,13 @@ static __be32 *tg3_vpd_readblock(struct tg3 *tp, u32 *vpdlen)
 
                        offset = tg3_nvram_logical_addr(tp, offset);
                }
-       }
 
-       if (!offset || !len) {
-               offset = TG3_NVM_VPD_OFF;
-               len = TG3_NVM_VPD_LEN;
+               if (!offset || !len) {
+                       offset = TG3_NVM_VPD_OFF;
+                       len = TG3_NVM_VPD_LEN;
+               }
+       } else {
+               len = TG3_NVM_PCI_VPD_MAX_LEN;
        }
 
        buf = kmalloc(len, GFP_KERNEL);
@@ -12846,26 +12848,16 @@ static __be32 *tg3_vpd_readblock(struct tg3 *tp, u32 *vpdlen)
                        if (tg3_nvram_read_be32(tp, offset + i, &buf[i/4]))
                                goto error;
                }
+               *vpdlen = len;
        } else {
-               u8 *ptr;
                ssize_t cnt;
-               unsigned int pos = 0;
-
-               ptr = (u8 *)&buf[0];
-               for (i = 0; pos < len && i < 3; i++, pos += cnt, ptr += cnt) {
-                       cnt = pci_read_vpd(tp->pdev, pos,
-                                          len - pos, ptr);
-                       if (cnt == -ETIMEDOUT || cnt == -EINTR)
-                               cnt = 0;
-                       else if (cnt < 0)
-                               goto error;
-               }
-               if (pos != len)
+
+               cnt = pci_read_vpd(tp->pdev, 0, len, (u8 *)buf);
+               if (cnt < 0)
                        goto error;
+               *vpdlen = cnt;
        }
 
-       *vpdlen = len;
-
        return buf;
 
 error:
index 1000c89..46ec4fd 100644 (file)
 /* Hardware Legacy NVRAM layout */
 #define TG3_NVM_VPD_OFF                        0x100
 #define TG3_NVM_VPD_LEN                        256
+#define TG3_NVM_PCI_VPD_MAX_LEN                512
 
 /* Hardware Selfboot NVRAM layout */
 #define TG3_NVM_HWSB_CFG1              0x00000004