Skip to content

Commit 098ef6c

Browse files
Hariprasad Shenaidavem330
authored andcommitted
cxgb4: Set mac addr from vpd, when we can't contact firmware
Grab the Adapter MAC Address out of the VPD and use it for the "debug" network interface when either we can't contact the firmware Signed-off-by: Hariprasad Shenai <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4036da9 commit 098ef6c

File tree

3 files changed

+81
-19
lines changed

3 files changed

+81
-19
lines changed

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,19 @@
4646
#include <linux/spinlock.h>
4747
#include <linux/timer.h>
4848
#include <linux/vmalloc.h>
49+
#include <linux/etherdevice.h>
4950
#include <asm/io.h>
5051
#include "cxgb4_uld.h"
5152

5253
#define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__)
5354

5455
enum {
55-
MAX_NPORTS = 4, /* max # of ports */
56-
SERNUM_LEN = 24, /* Serial # length */
57-
EC_LEN = 16, /* E/C length */
58-
ID_LEN = 16, /* ID length */
59-
PN_LEN = 16, /* Part Number length */
56+
MAX_NPORTS = 4, /* max # of ports */
57+
SERNUM_LEN = 24, /* Serial # length */
58+
EC_LEN = 16, /* E/C length */
59+
ID_LEN = 16, /* ID length */
60+
PN_LEN = 16, /* Part Number length */
61+
MACADDR_LEN = 12, /* MAC Address length */
6062
};
6163

6264
enum {
@@ -280,6 +282,7 @@ struct vpd_params {
280282
u8 sn[SERNUM_LEN + 1];
281283
u8 id[ID_LEN + 1];
282284
u8 pn[PN_LEN + 1];
285+
u8 na[MACADDR_LEN + 1];
283286
};
284287

285288
struct pci_params {
@@ -945,6 +948,22 @@ static inline void t4_write_reg64(struct adapter *adap, u32 reg_addr, u64 val)
945948
writeq(val, adap->regs + reg_addr);
946949
}
947950

951+
/**
952+
* t4_set_hw_addr - store a port's MAC address in SW
953+
* @adapter: the adapter
954+
* @port_idx: the port index
955+
* @hw_addr: the Ethernet address
956+
*
957+
* Store the Ethernet address of the given port in SW. Called by the common
958+
* code when it retrieves a port's Ethernet address from EEPROM.
959+
*/
960+
static inline void t4_set_hw_addr(struct adapter *adapter, int port_idx,
961+
u8 hw_addr[])
962+
{
963+
ether_addr_copy(adapter->port[port_idx]->dev_addr, hw_addr);
964+
ether_addr_copy(adapter->port[port_idx]->perm_addr, hw_addr);
965+
}
966+
948967
/**
949968
* netdev2pinfo - return the port_info structure associated with a net_device
950969
* @dev: the netdev
@@ -1251,7 +1270,8 @@ unsigned int t4_get_regs_len(struct adapter *adapter);
12511270
void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size);
12521271

12531272
int t4_seeprom_wp(struct adapter *adapter, bool enable);
1254-
int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
1273+
int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p);
1274+
int t4_get_vpd_params(struct adapter *adapter, struct vpd_params *p);
12551275
int t4_read_flash(struct adapter *adapter, unsigned int addr,
12561276
unsigned int nwords, u32 *data, int byte_oriented);
12571277
int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3712,7 +3712,7 @@ static int adap_init0(struct adapter *adap)
37123712
* the firmware. On the other hand, we need these fairly early on
37133713
* so we do this right after getting ahold of the firmware.
37143714
*/
3715-
ret = get_vpd_params(adap, &adap->params.vpd);
3715+
ret = t4_get_vpd_params(adap, &adap->params.vpd);
37163716
if (ret < 0)
37173717
goto bye;
37183718

@@ -4735,10 +4735,25 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
47354735
err = t4_port_init(adapter, func, func, 0);
47364736
if (err)
47374737
goto out_free_dev;
4738+
} else if (adapter->params.nports == 1) {
4739+
/* If we don't have a connection to the firmware -- possibly
4740+
* because of an error -- grab the raw VPD parameters so we
4741+
* can set the proper MAC Address on the debug network
4742+
* interface that we've created.
4743+
*/
4744+
u8 hw_addr[ETH_ALEN];
4745+
u8 *na = adapter->params.vpd.na;
4746+
4747+
err = t4_get_raw_vpd_params(adapter, &adapter->params.vpd);
4748+
if (!err) {
4749+
for (i = 0; i < ETH_ALEN; i++)
4750+
hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 +
4751+
hex2val(na[2 * i + 1]));
4752+
t4_set_hw_addr(adapter, 0, hw_addr);
4753+
}
47384754
}
47394755

4740-
/*
4741-
* Configure queues and allocate tables now, they can be needed as
4756+
/* Configure queues and allocate tables now, they can be needed as
47424757
* soon as the first register_netdev completes.
47434758
*/
47444759
cfg_queues(adapter);

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

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,24 +1729,26 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable)
17291729
}
17301730

17311731
/**
1732-
* get_vpd_params - read VPD parameters from VPD EEPROM
1732+
* t4_get_raw_vpd_params - read VPD parameters from VPD EEPROM
17331733
* @adapter: adapter to read
17341734
* @p: where to store the parameters
17351735
*
17361736
* Reads card parameters stored in VPD EEPROM.
17371737
*/
1738-
int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
1738+
int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
17391739
{
1740-
u32 cclk_param, cclk_val;
1741-
int i, ret, addr;
1742-
int ec, sn, pn;
1740+
int i, ret = 0, addr;
1741+
int ec, sn, pn, na;
17431742
u8 *vpd, csum;
17441743
unsigned int vpdr_len, kw_offset, id_len;
17451744

17461745
vpd = vmalloc(VPD_LEN);
17471746
if (!vpd)
17481747
return -ENOMEM;
17491748

1749+
/* Card information normally starts at VPD_BASE but early cards had
1750+
* it at 0.
1751+
*/
17501752
ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd);
17511753
if (ret < 0)
17521754
goto out;
@@ -1812,6 +1814,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
18121814
FIND_VPD_KW(ec, "EC");
18131815
FIND_VPD_KW(sn, "SN");
18141816
FIND_VPD_KW(pn, "PN");
1817+
FIND_VPD_KW(na, "NA");
18151818
#undef FIND_VPD_KW
18161819

18171820
memcpy(p->id, vpd + PCI_VPD_LRDT_TAG_SIZE, id_len);
@@ -1824,18 +1827,42 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
18241827
i = pci_vpd_info_field_size(vpd + pn - PCI_VPD_INFO_FLD_HDR_SIZE);
18251828
memcpy(p->pn, vpd + pn, min(i, PN_LEN));
18261829
strim(p->pn);
1830+
memcpy(p->na, vpd + na, min(i, MACADDR_LEN));
1831+
strim((char *)p->na);
18271832

1828-
/*
1829-
* Ask firmware for the Core Clock since it knows how to translate the
1833+
out:
1834+
vfree(vpd);
1835+
return ret;
1836+
}
1837+
1838+
/**
1839+
* t4_get_vpd_params - read VPD parameters & retrieve Core Clock
1840+
* @adapter: adapter to read
1841+
* @p: where to store the parameters
1842+
*
1843+
* Reads card parameters stored in VPD EEPROM and retrieves the Core
1844+
* Clock. This can only be called after a connection to the firmware
1845+
* is established.
1846+
*/
1847+
int t4_get_vpd_params(struct adapter *adapter, struct vpd_params *p)
1848+
{
1849+
u32 cclk_param, cclk_val;
1850+
int ret;
1851+
1852+
/* Grab the raw VPD parameters.
1853+
*/
1854+
ret = t4_get_raw_vpd_params(adapter, p);
1855+
if (ret)
1856+
return ret;
1857+
1858+
/* Ask firmware for the Core Clock since it knows how to translate the
18301859
* Reference Clock ('V2') VPD field into a Core Clock value ...
18311860
*/
18321861
cclk_param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
18331862
FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CCLK));
1834-
ret = t4_query_params(adapter, adapter->mbox, 0, 0,
1863+
ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
18351864
1, &cclk_param, &cclk_val);
18361865

1837-
out:
1838-
vfree(vpd);
18391866
if (ret)
18401867
return ret;
18411868
p->cclk = cclk_val;

0 commit comments

Comments
 (0)