aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2011-03-09 16:58:21 +0000
committerDavid S. Miller <davem@davemloft.net>2011-03-10 01:56:12 -0800
commitd4894f3ea7375dd9492b5d3d2ecb0b6e4bdb604e (patch)
treea538179ac50d080a4240f7f9da77655d4b40160c
parenttg3: Fix NVRAM selftest (diff)
downloadlinux-dev-d4894f3ea7375dd9492b5d3d2ecb0b6e4bdb604e.tar.xz
linux-dev-d4894f3ea7375dd9492b5d3d2ecb0b6e4bdb604e.zip
tg3: Add code to verify RODATA checksum of VPD
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>
-rw-r--r--drivers/net/tg3.c35
-rw-r--r--include/linux/pci.h1
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8f7160812e06..ffb09795101e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -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:
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 559d02897075..ff5bccb87136 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -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