Skip to content

Commit 23d88e1

Browse files
Dimitris Michailidisdavem330
authored andcommitted
cxgb4: extend VPD parsing
Current code parses the VPD RO section for keywords but makes static assumptions about the location of the section. Remove them and parse the VPD to find it. Signed-off-by: Dimitris Michailidis <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 005b571 commit 23d88e1

File tree

1 file changed

+21
-20
lines changed

1 file changed

+21
-20
lines changed

drivers/net/cxgb4/t4_hw.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -330,18 +330,6 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
330330
return 0;
331331
}
332332

333-
/*
334-
* Partial EEPROM Vital Product Data structure. Includes only the ID and
335-
* VPD-R header.
336-
*/
337-
struct t4_vpd_hdr {
338-
u8 id_tag;
339-
u8 id_len[2];
340-
u8 id_data[ID_LEN];
341-
u8 vpdr_tag;
342-
u8 vpdr_len[2];
343-
};
344-
345333
#define EEPROM_STAT_ADDR 0x7bfc
346334
#define VPD_BASE 0
347335
#define VPD_LEN 512
@@ -372,23 +360,36 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
372360
int i, ret;
373361
int ec, sn;
374362
u8 vpd[VPD_LEN], csum;
375-
unsigned int vpdr_len;
376-
const struct t4_vpd_hdr *v;
363+
unsigned int vpdr_len, kw_offset, id_len;
377364

378365
ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), vpd);
379366
if (ret < 0)
380367
return ret;
381368

382-
v = (const struct t4_vpd_hdr *)vpd;
383-
vpdr_len = pci_vpd_lrdt_size(&v->vpdr_tag);
384-
if (vpdr_len + sizeof(struct t4_vpd_hdr) > VPD_LEN) {
369+
if (vpd[0] != PCI_VPD_LRDT_ID_STRING) {
370+
dev_err(adapter->pdev_dev, "missing VPD ID string\n");
371+
return -EINVAL;
372+
}
373+
374+
id_len = pci_vpd_lrdt_size(vpd);
375+
if (id_len > ID_LEN)
376+
id_len = ID_LEN;
377+
378+
i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA);
379+
if (i < 0) {
380+
dev_err(adapter->pdev_dev, "missing VPD-R section\n");
381+
return -EINVAL;
382+
}
383+
384+
vpdr_len = pci_vpd_lrdt_size(&vpd[i]);
385+
kw_offset = i + PCI_VPD_LRDT_TAG_SIZE;
386+
if (vpdr_len + kw_offset > VPD_LEN) {
385387
dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len);
386388
return -EINVAL;
387389
}
388390

389391
#define FIND_VPD_KW(var, name) do { \
390-
var = pci_vpd_find_info_keyword(&v->id_tag, sizeof(struct t4_vpd_hdr), \
391-
vpdr_len, name); \
392+
var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \
392393
if (var < 0) { \
393394
dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \
394395
return -EINVAL; \
@@ -410,7 +411,7 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
410411
FIND_VPD_KW(sn, "SN");
411412
#undef FIND_VPD_KW
412413

413-
memcpy(p->id, v->id_data, ID_LEN);
414+
memcpy(p->id, vpd + PCI_VPD_LRDT_TAG_SIZE, id_len);
414415
strim(p->id);
415416
memcpy(p->ec, vpd + ec, EC_LEN);
416417
strim(p->ec);

0 commit comments

Comments
 (0)