Skip to content

Commit 940c9c4

Browse files
chelsiocudbgdavem330
authored andcommitted
cxgb4: collect vpd info directly from hardware
Collect vpd information directly from hardware instead of software adapter context. Move EEPROM physical address to virtual address translation logic to t4_hw.c and update relevant files. Fixes: 6f92a65 ("cxgb4: collect hardware misc dumps") Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 40cff8f commit 940c9c4

File tree

5 files changed

+104
-42
lines changed

5 files changed

+104
-42
lines changed

drivers/net/ethernet/chelsio/cxgb4/cudbg_entity.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ struct cudbg_mps_tcam {
166166
u8 reserved[2];
167167
};
168168

169+
#define CUDBG_VPD_PF_SIZE 0x800
170+
#define CUDBG_SCFG_VER_ADDR 0x06
171+
#define CUDBG_SCFG_VER_LEN 4
172+
#define CUDBG_VPD_VER_ADDR 0x18c7
173+
#define CUDBG_VPD_VER_LEN 2
174+
169175
struct cudbg_vpd_data {
170176
u8 sn[SERNUM_LEN + 1];
171177
u8 bn[PN_LEN + 1];

drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ struct cudbg_entity_hdr *cudbg_get_entity_hdr(void *outbuf, int i)
6868
(sizeof(struct cudbg_entity_hdr) * (i - 1)));
6969
}
7070

71+
static int cudbg_read_vpd_reg(struct adapter *padap, u32 addr, u32 len,
72+
void *dest)
73+
{
74+
int vaddr, rc;
75+
76+
vaddr = t4_eeprom_ptov(addr, padap->pf, EEPROMPFSIZE);
77+
if (vaddr < 0)
78+
return vaddr;
79+
80+
rc = pci_read_vpd(padap->pdev, vaddr, len, dest);
81+
if (rc < 0)
82+
return rc;
83+
84+
return 0;
85+
}
86+
7187
int cudbg_collect_reg_dump(struct cudbg_init *pdbg_init,
7288
struct cudbg_buffer *dbg_buff,
7389
struct cudbg_error *cudbg_err)
@@ -1289,25 +1305,64 @@ int cudbg_collect_vpd_data(struct cudbg_init *pdbg_init,
12891305
{
12901306
struct adapter *padap = pdbg_init->adap;
12911307
struct cudbg_buffer temp_buff = { 0 };
1308+
char vpd_str[CUDBG_VPD_VER_LEN + 1];
1309+
u32 scfg_vers, vpd_vers, fw_vers;
12921310
struct cudbg_vpd_data *vpd_data;
1293-
int rc;
1311+
struct vpd_params vpd = { 0 };
1312+
int rc, ret;
1313+
1314+
rc = t4_get_raw_vpd_params(padap, &vpd);
1315+
if (rc)
1316+
return rc;
1317+
1318+
rc = t4_get_fw_version(padap, &fw_vers);
1319+
if (rc)
1320+
return rc;
1321+
1322+
/* Serial Configuration Version is located beyond the PF's vpd size.
1323+
* Temporarily give access to entire EEPROM to get it.
1324+
*/
1325+
rc = pci_set_vpd_size(padap->pdev, EEPROMVSIZE);
1326+
if (rc < 0)
1327+
return rc;
1328+
1329+
ret = cudbg_read_vpd_reg(padap, CUDBG_SCFG_VER_ADDR, CUDBG_SCFG_VER_LEN,
1330+
&scfg_vers);
1331+
1332+
/* Restore back to original PF's vpd size */
1333+
rc = pci_set_vpd_size(padap->pdev, CUDBG_VPD_PF_SIZE);
1334+
if (rc < 0)
1335+
return rc;
1336+
1337+
if (ret)
1338+
return ret;
1339+
1340+
rc = cudbg_read_vpd_reg(padap, CUDBG_VPD_VER_ADDR, CUDBG_VPD_VER_LEN,
1341+
vpd_str);
1342+
if (rc)
1343+
return rc;
1344+
1345+
vpd_str[CUDBG_VPD_VER_LEN] = '\0';
1346+
rc = kstrtouint(vpd_str, 0, &vpd_vers);
1347+
if (rc)
1348+
return rc;
12941349

12951350
rc = cudbg_get_buff(dbg_buff, sizeof(struct cudbg_vpd_data),
12961351
&temp_buff);
12971352
if (rc)
12981353
return rc;
12991354

13001355
vpd_data = (struct cudbg_vpd_data *)temp_buff.data;
1301-
memcpy(vpd_data->sn, padap->params.vpd.sn, SERNUM_LEN + 1);
1302-
memcpy(vpd_data->bn, padap->params.vpd.pn, PN_LEN + 1);
1303-
memcpy(vpd_data->na, padap->params.vpd.na, MACADDR_LEN + 1);
1304-
memcpy(vpd_data->mn, padap->params.vpd.id, ID_LEN + 1);
1305-
vpd_data->scfg_vers = padap->params.scfg_vers;
1306-
vpd_data->vpd_vers = padap->params.vpd_vers;
1307-
vpd_data->fw_major = FW_HDR_FW_VER_MAJOR_G(padap->params.fw_vers);
1308-
vpd_data->fw_minor = FW_HDR_FW_VER_MINOR_G(padap->params.fw_vers);
1309-
vpd_data->fw_micro = FW_HDR_FW_VER_MICRO_G(padap->params.fw_vers);
1310-
vpd_data->fw_build = FW_HDR_FW_VER_BUILD_G(padap->params.fw_vers);
1356+
memcpy(vpd_data->sn, vpd.sn, SERNUM_LEN + 1);
1357+
memcpy(vpd_data->bn, vpd.pn, PN_LEN + 1);
1358+
memcpy(vpd_data->na, vpd.na, MACADDR_LEN + 1);
1359+
memcpy(vpd_data->mn, vpd.id, ID_LEN + 1);
1360+
vpd_data->scfg_vers = scfg_vers;
1361+
vpd_data->vpd_vers = vpd_vers;
1362+
vpd_data->fw_major = FW_HDR_FW_VER_MAJOR_G(fw_vers);
1363+
vpd_data->fw_minor = FW_HDR_FW_VER_MINOR_G(fw_vers);
1364+
vpd_data->fw_micro = FW_HDR_FW_VER_MICRO_G(fw_vers);
1365+
vpd_data->fw_build = FW_HDR_FW_VER_BUILD_G(fw_vers);
13111366
cudbg_write_and_release_buff(&temp_buff, dbg_buff);
13121367
return rc;
13131368
}

drivers/net/ethernet/chelsio/cxgb4/cxgb4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,7 @@ static inline int t4_memory_write(struct adapter *adap, int mtype, u32 addr,
14591459
unsigned int t4_get_regs_len(struct adapter *adapter);
14601460
void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size);
14611461

1462+
int t4_eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz);
14621463
int t4_seeprom_wp(struct adapter *adapter, bool enable);
14631464
int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p);
14641465
int t4_get_vpd_params(struct adapter *adapter, struct vpd_params *p);

drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,40 +1064,11 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
10641064
return 0;
10651065
}
10661066

1067-
/**
1068-
* eeprom_ptov - translate a physical EEPROM address to virtual
1069-
* @phys_addr: the physical EEPROM address
1070-
* @fn: the PCI function number
1071-
* @sz: size of function-specific area
1072-
*
1073-
* Translate a physical EEPROM address to virtual. The first 1K is
1074-
* accessed through virtual addresses starting at 31K, the rest is
1075-
* accessed through virtual addresses starting at 0.
1076-
*
1077-
* The mapping is as follows:
1078-
* [0..1K) -> [31K..32K)
1079-
* [1K..1K+A) -> [31K-A..31K)
1080-
* [1K+A..ES) -> [0..ES-A-1K)
1081-
*
1082-
* where A = @fn * @sz, and ES = EEPROM size.
1083-
*/
1084-
static int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz)
1085-
{
1086-
fn *= sz;
1087-
if (phys_addr < 1024)
1088-
return phys_addr + (31 << 10);
1089-
if (phys_addr < 1024 + fn)
1090-
return 31744 - fn + phys_addr - 1024;
1091-
if (phys_addr < EEPROMSIZE)
1092-
return phys_addr - 1024 - fn;
1093-
return -EINVAL;
1094-
}
1095-
10961067
/* The next two routines implement eeprom read/write from physical addresses.
10971068
*/
10981069
static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
10991070
{
1100-
int vaddr = eeprom_ptov(phys_addr, adap->pf, EEPROMPFSIZE);
1071+
int vaddr = t4_eeprom_ptov(phys_addr, adap->pf, EEPROMPFSIZE);
11011072

11021073
if (vaddr >= 0)
11031074
vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v);
@@ -1106,7 +1077,7 @@ static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v)
11061077

11071078
static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v)
11081079
{
1109-
int vaddr = eeprom_ptov(phys_addr, adap->pf, EEPROMPFSIZE);
1080+
int vaddr = t4_eeprom_ptov(phys_addr, adap->pf, EEPROMPFSIZE);
11101081

11111082
if (vaddr >= 0)
11121083
vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v);

drivers/net/ethernet/chelsio/cxgb4/t4_hw.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,6 +2638,35 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
26382638
#define VPD_LEN 1024
26392639
#define CHELSIO_VPD_UNIQUE_ID 0x82
26402640

2641+
/**
2642+
* t4_eeprom_ptov - translate a physical EEPROM address to virtual
2643+
* @phys_addr: the physical EEPROM address
2644+
* @fn: the PCI function number
2645+
* @sz: size of function-specific area
2646+
*
2647+
* Translate a physical EEPROM address to virtual. The first 1K is
2648+
* accessed through virtual addresses starting at 31K, the rest is
2649+
* accessed through virtual addresses starting at 0.
2650+
*
2651+
* The mapping is as follows:
2652+
* [0..1K) -> [31K..32K)
2653+
* [1K..1K+A) -> [31K-A..31K)
2654+
* [1K+A..ES) -> [0..ES-A-1K)
2655+
*
2656+
* where A = @fn * @sz, and ES = EEPROM size.
2657+
*/
2658+
int t4_eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz)
2659+
{
2660+
fn *= sz;
2661+
if (phys_addr < 1024)
2662+
return phys_addr + (31 << 10);
2663+
if (phys_addr < 1024 + fn)
2664+
return 31744 - fn + phys_addr - 1024;
2665+
if (phys_addr < EEPROMSIZE)
2666+
return phys_addr - 1024 - fn;
2667+
return -EINVAL;
2668+
}
2669+
26412670
/**
26422671
* t4_seeprom_wp - enable/disable EEPROM write protection
26432672
* @adapter: the adapter

0 commit comments

Comments
 (0)