tg3: Add code to verify RODATA checksum of VPD
authorMatt Carlson <mcarlson@broadcom.com>
Wed, 9 Mar 2011 16:58:21 +0000 (16:58 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 10 Mar 2011 09:56:12 +0000 (01:56 -0800)
This patch adds code to verify the checksum stored in the "RV" info
keyword of the RODATA VPD section.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/tg3.c
include/linux/pci.h

index 8f71608..ffb0979 100644 (file)
@@ -10499,6 +10499,41 @@ static int tg3_test_nvram(struct tg3 *tp)
        if (csum != le32_to_cpu(buf[0xfc/4]))
                goto out;
 
+       for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
+               /* The data is in little-endian format in NVRAM.
+                * Use the big-endian read routines to preserve
+                * the byte order as it exists in NVRAM.
+                */
+               if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &buf[i/4]))
+                       goto out;
+       }
+
+       i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN,
+                            PCI_VPD_LRDT_RO_DATA);
+       if (i > 0) {
+               j = pci_vpd_lrdt_size(&((u8 *)buf)[i]);
+               if (j < 0)
+                       goto out;
+
+               if (i + PCI_VPD_LRDT_TAG_SIZE + j > TG3_NVM_VPD_LEN)
+                       goto out;
+
+               i += PCI_VPD_LRDT_TAG_SIZE;
+               j = pci_vpd_find_info_keyword((u8 *)buf, i, j,
+                                             PCI_VPD_RO_KEYWORD_CHKSUM);
+               if (j > 0) {
+                       u8 csum8 = 0;
+
+                       j += PCI_VPD_INFO_FLD_HDR_SIZE;
+
+                       for (i = 0; i <= j; i++)
+                               csum8 += ((u8 *)buf)[i];
+
+                       if (csum8)
+                               goto out;
+               }
+       }
+
        err = 0;
 
 out:
index 559d028..ff5bccb 100644 (file)
@@ -1479,6 +1479,7 @@ void pci_request_acs(void);
 #define PCI_VPD_RO_KEYWORD_PARTNO      "PN"
 #define PCI_VPD_RO_KEYWORD_MFR_ID      "MN"
 #define PCI_VPD_RO_KEYWORD_VENDOR0     "V0"
+#define PCI_VPD_RO_KEYWORD_CHKSUM      "RV"
 
 /**
  * pci_vpd_lrdt_size - Extracts the Large Resource Data Type length