@@ -7762,15 +7762,26 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
unsigned char val = data[i];
unsigned int block_end;
- if (val == 0x82 || val == 0x91) {
- i += PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&data[i]);
+ if (val & PCI_VPD_LRDT) {
+ if (i + PCI_VPD_LRDT_TAG_SIZE > BNX2_VPD_LEN)
+ break;
+
+ if (val != PCI_VPD_LRDT_RO_DATA) {
+ i += PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&data[i]);
+
+ continue;
+ }
+ } else {
+ if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END)
+ break;
+
+ i += PCI_VPD_SRDT_TAG_SIZE +
+ pci_vpd_srdt_size(&data[i]);
+
continue;
}
- if (val != 0x90)
- goto vpd_done;
-
block_end = (i + PCI_VPD_LRDT_TAG_SIZE +
pci_vpd_lrdt_size(&data[i]));
i += PCI_VPD_LRDT_TAG_SIZE;
@@ -12482,15 +12482,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
unsigned char val = vpd_data[i];
unsigned int block_end;
- if (val == 0x82 || val == 0x91) {
- i += PCI_VPD_LRDT_TAG_SIZE +
- pci_vpd_lrdt_size(&vpd_data[i]);
+ if (val & PCI_VPD_LRDT) {
+ if (i + PCI_VPD_LRDT_TAG_SIZE > TG3_NVM_VPD_LEN)
+ break;
+
+ if (val != PCI_VPD_LRDT_RO_DATA) {
+ i += PCI_VPD_LRDT_TAG_SIZE +
+ pci_vpd_lrdt_size(&vpd_data[i]);
+
+ continue;
+ }
+ } else {
+ if ((val & PCI_VPD_SRDT_TIN_MASK) == PCI_VPD_STIN_END)
+ break;
+
+ i += PCI_VPD_SRDT_TAG_SIZE +
+ pci_vpd_srdt_size(&vpd_data[i]);
+
continue;
}
- if (val != 0x90)
- goto out_not_found;
-
block_end = i + PCI_VPD_LRDT_TAG_SIZE +
pci_vpd_lrdt_size(&vpd_data[i]);
@@ -1339,7 +1339,28 @@ static inline bool pci_is_pcie(struct pci_dev *dev)
void pci_request_acs(void);
-#define PCI_VPD_LRDT_TAG_SIZE 3
+#define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */
+#define PCI_VPD_LRDT_ID(x) (x | PCI_VPD_LRDT)
+
+/* Large Resource Data Type Tag Item Names */
+#define PCI_VPD_LTIN_ID_STRING 0x02 /* Identifier String */
+#define PCI_VPD_LTIN_RO_DATA 0x10 /* Read-Only Data */
+#define PCI_VPD_LTIN_RW_DATA 0x11 /* Read-Write Data */
+
+#define PCI_VPD_LRDT_ID_STRING PCI_VPD_LRDT_ID(PCI_VPD_LTIN_ID_STRING)
+#define PCI_VPD_LRDT_RO_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RO_DATA)
+#define PCI_VPD_LRDT_RW_DATA PCI_VPD_LRDT_ID(PCI_VPD_LTIN_RW_DATA)
+
+/* Small Resource Data Type Tag Item Names */
+#define PCI_VPD_STIN_END 0x78 /* End */
+
+#define PCI_VPD_SRDT_END PCI_VPD_STIN_END
+
+#define PCI_VPD_SRDT_TIN_MASK 0x78
+#define PCI_VPD_SRDT_LEN_MASK 0x07
+
+#define PCI_VPD_LRDT_TAG_SIZE 3
+#define PCI_VPD_SRDT_TAG_SIZE 1
/**
* pci_vpd_lrdt_size - Extracts the Large Resource Data Type length
@@ -1352,5 +1373,16 @@ static inline u16 pci_vpd_lrdt_size(const u8 *lrdt)
return (u16)lrdt[1] + ((u16)lrdt[2] << 8);
}
+/**
+ * pci_vpd_srdt_size - Extracts the Small Resource Data Type length
+ * @lrdt: Pointer to the beginning of the Small Resource Data Type tag
+ *
+ * Returns the extracted Small Resource Data Type length.
+ */
+static inline u8 pci_vpd_srdt_size(const u8 *srdt)
+{
+ return (*srdt) & PCI_VPD_SRDT_LEN_MASK;
+}
+
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */