Commit 4da44fdf authored by David S. Miller's avatar David S. Miller

Merge branch 'cxgb4-next'

Hariprasad Shenai says:

====================
Free VI, flush sge ec and some other misc. fixes

This patch series adds the following.
Free VI interface during remove, flush SGE ec routine, rename
t4_link_start to t4_link_l1cfg since it only does l1 configuration, set
mac addr from when we can't contact firmware for debug purpose, set pcie
completion timeout and use fw interface to access TP_PIO_XXX registers

This patch series has been created against net-next tree and includes
patches on cxgb4 driver.

We have included all the maintainers of respective drivers. Kindly review
the change and let us know in case of any review comments.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bb62f791 c1e9af0c
......@@ -46,6 +46,7 @@
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
#include <linux/etherdevice.h>
#include <asm/io.h>
#include "cxgb4_uld.h"
......@@ -57,6 +58,7 @@ enum {
EC_LEN = 16, /* E/C length */
ID_LEN = 16, /* ID length */
PN_LEN = 16, /* Part Number length */
MACADDR_LEN = 12, /* MAC Address length */
};
enum {
......@@ -280,6 +282,7 @@ struct vpd_params {
u8 sn[SERNUM_LEN + 1];
u8 id[ID_LEN + 1];
u8 pn[PN_LEN + 1];
u8 na[MACADDR_LEN + 1];
};
struct pci_params {
......@@ -945,6 +948,22 @@ static inline void t4_write_reg64(struct adapter *adap, u32 reg_addr, u64 val)
writeq(val, adap->regs + reg_addr);
}
/**
* t4_set_hw_addr - store a port's MAC address in SW
* @adapter: the adapter
* @port_idx: the port index
* @hw_addr: the Ethernet address
*
* Store the Ethernet address of the given port in SW. Called by the common
* code when it retrieves a port's Ethernet address from EEPROM.
*/
static inline void t4_set_hw_addr(struct adapter *adapter, int port_idx,
u8 hw_addr[])
{
ether_addr_copy(adapter->port[port_idx]->dev_addr, hw_addr);
ether_addr_copy(adapter->port[port_idx]->perm_addr, hw_addr);
}
/**
* netdev2pinfo - return the port_info structure associated with a net_device
* @dev: the netdev
......@@ -1229,7 +1248,7 @@ void t4_intr_disable(struct adapter *adapter);
int t4_slow_intr_handler(struct adapter *adapter);
int t4_wait_dev_ready(void __iomem *regs);
int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc);
int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port);
......@@ -1251,7 +1270,8 @@ unsigned int t4_get_regs_len(struct adapter *adapter);
void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size);
int t4_seeprom_wp(struct adapter *adapter, bool enable);
int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p);
int t4_get_vpd_params(struct adapter *adapter, struct vpd_params *p);
int t4_read_flash(struct adapter *adapter, unsigned int addr,
unsigned int nwords, u32 *data, int byte_oriented);
int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
......@@ -1378,6 +1398,9 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
unsigned int *rss_size);
int t4_free_vi(struct adapter *adap, unsigned int mbox,
unsigned int pf, unsigned int vf,
unsigned int viid);
int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
int mtu, int promisc, int all_multi, int bcast, int vlanex,
bool sleep_ok);
......@@ -1407,6 +1430,7 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
unsigned int vf, unsigned int eqid);
int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
unsigned int vf, unsigned int eqid);
int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox);
int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
void t4_db_full(struct adapter *adapter);
void t4_db_dropped(struct adapter *adapter);
......
......@@ -646,7 +646,7 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
lc->autoneg = cmd->autoneg;
if (netif_running(dev))
return t4_link_start(p->adapter, p->adapter->pf, p->tx_chan,
return t4_link_l1cfg(p->adapter, p->adapter->pf, p->tx_chan,
lc);
return 0;
}
......@@ -679,7 +679,7 @@ static int set_pauseparam(struct net_device *dev,
if (epause->tx_pause)
lc->requested_fc |= PAUSE_TX;
if (netif_running(dev))
return t4_link_start(p->adapter, p->adapter->pf, p->tx_chan,
return t4_link_l1cfg(p->adapter, p->adapter->pf, p->tx_chan,
lc);
return 0;
}
......
......@@ -481,7 +481,7 @@ static int link_start(struct net_device *dev)
}
}
if (ret == 0)
ret = t4_link_start(pi->adapter, mb, pi->tx_chan,
ret = t4_link_l1cfg(pi->adapter, mb, pi->tx_chan,
&pi->link_cfg);
if (ret == 0) {
local_bh_disable();
......@@ -2007,11 +2007,8 @@ EXPORT_SYMBOL(cxgb4_iscsi_init);
int cxgb4_flush_eq_cache(struct net_device *dev)
{
struct adapter *adap = netdev2adap(dev);
int ret;
ret = t4_fwaddrspace_write(adap, adap->mbox,
0xe1000000 + SGE_CTXT_CMD_A, 0x20000000);
return ret;
return t4_sge_ctxt_flush(adap, adap->mbox);
}
EXPORT_SYMBOL(cxgb4_flush_eq_cache);
......@@ -3715,7 +3712,7 @@ static int adap_init0(struct adapter *adap)
* the firmware. On the other hand, we need these fairly early on
* so we do this right after getting ahold of the firmware.
*/
ret = get_vpd_params(adap, &adap->params.vpd);
ret = t4_get_vpd_params(adap, &adap->params.vpd);
if (ret < 0)
goto bye;
......@@ -4071,8 +4068,8 @@ static int adap_init0(struct adapter *adap)
adap->params.b_wnd);
}
t4_init_sge_params(adap);
t4_init_tp_params(adap);
adap->flags |= FW_OK;
t4_init_tp_params(adap);
return 0;
/*
......@@ -4538,6 +4535,11 @@ static void free_some_resources(struct adapter *adapter)
for_each_port(adapter, i)
if (adapter->port[i]) {
struct port_info *pi = adap2pinfo(adapter, i);
if (pi->viid != 0)
t4_free_vi(adapter, adapter->mbox, adapter->pf,
0, pi->viid);
kfree(adap2pinfo(adapter, i)->rss);
free_netdev(adapter->port[i]);
}
......@@ -4733,10 +4735,25 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
err = t4_port_init(adapter, func, func, 0);
if (err)
goto out_free_dev;
} else if (adapter->params.nports == 1) {
/* If we don't have a connection to the firmware -- possibly
* because of an error -- grab the raw VPD parameters so we
* can set the proper MAC Address on the debug network
* interface that we've created.
*/
u8 hw_addr[ETH_ALEN];
u8 *na = adapter->params.vpd.na;
err = t4_get_raw_vpd_params(adapter, &adapter->params.vpd);
if (!err) {
for (i = 0; i < ETH_ALEN; i++)
hw_addr[i] = (hex2val(na[2 * i + 0]) * 16 +
hex2val(na[2 * i + 1]));
t4_set_hw_addr(adapter, 0, hw_addr);
}
}
/*
* Configure queues and allocate tables now, they can be needed as
/* Configure queues and allocate tables now, they can be needed as
* soon as the first register_netdev completes.
*/
cfg_queues(adapter);
......
......@@ -1729,17 +1729,16 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable)
}
/**
* get_vpd_params - read VPD parameters from VPD EEPROM
* t4_get_raw_vpd_params - read VPD parameters from VPD EEPROM
* @adapter: adapter to read
* @p: where to store the parameters
*
* Reads card parameters stored in VPD EEPROM.
*/
int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
{
u32 cclk_param, cclk_val;
int i, ret, addr;
int ec, sn, pn;
int i, ret = 0, addr;
int ec, sn, pn, na;
u8 *vpd, csum;
unsigned int vpdr_len, kw_offset, id_len;
......@@ -1747,6 +1746,9 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
if (!vpd)
return -ENOMEM;
/* Card information normally starts at VPD_BASE but early cards had
* it at 0.
*/
ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd);
if (ret < 0)
goto out;
......@@ -1812,6 +1814,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
FIND_VPD_KW(ec, "EC");
FIND_VPD_KW(sn, "SN");
FIND_VPD_KW(pn, "PN");
FIND_VPD_KW(na, "NA");
#undef FIND_VPD_KW
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)
i = pci_vpd_info_field_size(vpd + pn - PCI_VPD_INFO_FLD_HDR_SIZE);
memcpy(p->pn, vpd + pn, min(i, PN_LEN));
strim(p->pn);
memcpy(p->na, vpd + na, min(i, MACADDR_LEN));
strim((char *)p->na);
/*
* Ask firmware for the Core Clock since it knows how to translate the
out:
vfree(vpd);
return ret;
}
/**
* t4_get_vpd_params - read VPD parameters & retrieve Core Clock
* @adapter: adapter to read
* @p: where to store the parameters
*
* Reads card parameters stored in VPD EEPROM and retrieves the Core
* Clock. This can only be called after a connection to the firmware
* is established.
*/
int t4_get_vpd_params(struct adapter *adapter, struct vpd_params *p)
{
u32 cclk_param, cclk_val;
int ret;
/* Grab the raw VPD parameters.
*/
ret = t4_get_raw_vpd_params(adapter, p);
if (ret)
return ret;
/* Ask firmware for the Core Clock since it knows how to translate the
* Reference Clock ('V2') VPD field into a Core Clock value ...
*/
cclk_param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CCLK));
ret = t4_query_params(adapter, adapter->mbox, 0, 0,
ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
1, &cclk_param, &cclk_val);
out:
vfree(vpd);
if (ret)
return ret;
p->cclk = cclk_val;
......@@ -2579,7 +2606,7 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf)
FW_PORT_CAP_ANEG)
/**
* t4_link_start - apply link configuration to MAC/PHY
* t4_link_l1cfg - apply link configuration to MAC/PHY
* @phy: the PHY to setup
* @mac: the MAC to setup
* @lc: the requested link configuration
......@@ -2591,7 +2618,7 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf)
* - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
* otherwise do it later based on the outcome of auto-negotiation.
*/
int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
struct link_config *lc)
{
struct fw_port_cmd c;
......@@ -3605,6 +3632,40 @@ int t4_read_rss(struct adapter *adapter, u16 *map)
return 0;
}
/**
* t4_fw_tp_pio_rw - Access TP PIO through LDST
* @adap: the adapter
* @vals: where the indirect register values are stored/written
* @nregs: how many indirect registers to read/write
* @start_idx: index of first indirect register to read/write
* @rw: Read (1) or Write (0)
*
* Access TP PIO registers through LDST
*/
static void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
unsigned int start_index, unsigned int rw)
{
int ret, i;
int cmd = FW_LDST_ADDRSPC_TP_PIO;
struct fw_ldst_cmd c;
for (i = 0 ; i < nregs; i++) {
memset(&c, 0, sizeof(c));
c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
FW_CMD_REQUEST_F |
(rw ? FW_CMD_READ_F :
FW_CMD_WRITE_F) |
FW_LDST_CMD_ADDRSPACE_V(cmd));
c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
c.u.addrval.addr = cpu_to_be32(start_index + i);
c.u.addrval.val = rw ? 0 : cpu_to_be32(vals[i]);
ret = t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), &c);
if (!ret && rw)
vals[i] = be32_to_cpu(c.u.addrval.val);
}
}
/**
* t4_read_rss_key - read the global RSS key
* @adap: the adapter
......@@ -3614,6 +3675,9 @@ int t4_read_rss(struct adapter *adapter, u16 *map)
*/
void t4_read_rss_key(struct adapter *adap, u32 *key)
{
if (adap->flags & FW_OK)
t4_fw_tp_pio_rw(adap, key, 10, TP_RSS_SECRET_KEY0_A, 1);
else
t4_read_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A, key, 10,
TP_RSS_SECRET_KEY0_A);
}
......@@ -3641,6 +3705,9 @@ void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx)
(vrt & KEYEXTEND_F) && (KEYMODE_G(vrt) == 3))
rss_key_addr_cnt = 32;
if (adap->flags & FW_OK)
t4_fw_tp_pio_rw(adap, (void *)key, 10, TP_RSS_SECRET_KEY0_A, 0);
else
t4_write_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A, key, 10,
TP_RSS_SECRET_KEY0_A);
......@@ -3667,6 +3734,10 @@ void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx)
void t4_read_rss_pf_config(struct adapter *adapter, unsigned int index,
u32 *valp)
{
if (adapter->flags & FW_OK)
t4_fw_tp_pio_rw(adapter, valp, 1,
TP_RSS_PF0_CONFIG_A + index, 1);
else
t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
valp, 1, TP_RSS_PF0_CONFIG_A + index);
}
......@@ -3703,10 +3774,15 @@ void t4_read_rss_vf_config(struct adapter *adapter, unsigned int index,
/* Grab the VFL/VFH values ...
*/
if (adapter->flags & FW_OK) {
t4_fw_tp_pio_rw(adapter, vfl, 1, TP_RSS_VFL_CONFIG_A, 1);
t4_fw_tp_pio_rw(adapter, vfh, 1, TP_RSS_VFH_CONFIG_A, 1);
} else {
t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
vfl, 1, TP_RSS_VFL_CONFIG_A);
t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
vfh, 1, TP_RSS_VFH_CONFIG_A);
}
}
/**
......@@ -3719,6 +3795,9 @@ u32 t4_read_rss_pf_map(struct adapter *adapter)
{
u32 pfmap;
if (adapter->flags & FW_OK)
t4_fw_tp_pio_rw(adapter, &pfmap, 1, TP_RSS_PF_MAP_A, 1);
else
t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
&pfmap, 1, TP_RSS_PF_MAP_A);
return pfmap;
......@@ -3734,6 +3813,9 @@ u32 t4_read_rss_pf_mask(struct adapter *adapter)
{
u32 pfmask;
if (adapter->flags & FW_OK)
t4_fw_tp_pio_rw(adapter, &pfmask, 1, TP_RSS_PF_MSK_A, 1);
else
t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
&pfmask, 1, TP_RSS_PF_MSK_A);
return pfmask;
......@@ -4529,6 +4611,32 @@ void t4_sge_decode_idma_state(struct adapter *adapter, int state)
sge_regs[i], t4_read_reg(adapter, sge_regs[i]));
}
/**
* t4_sge_ctxt_flush - flush the SGE context cache
* @adap: the adapter
* @mbox: mailbox to use for the FW command
*
* Issues a FW command through the given mailbox to flush the
* SGE context cache.
*/
int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox)
{
int ret;
u32 ldst_addrspace;
struct fw_ldst_cmd c;
memset(&c, 0, sizeof(c));
ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_SGE_EGRC);
c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
FW_CMD_REQUEST_F | FW_CMD_READ_F |
ldst_addrspace);
c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
c.u.idctxt.msg_ctxtflush = cpu_to_be32(FW_LDST_CMD_CTXTFLUSH_F);
ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
return ret;
}
/**
* t4_fw_hello - establish communication with FW
* @adap: the adapter
......@@ -5225,6 +5333,33 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
return FW_VI_CMD_VIID_G(be16_to_cpu(c.type_viid));
}
/**
* t4_free_vi - free a virtual interface
* @adap: the adapter
* @mbox: mailbox to use for the FW command
* @pf: the PF owning the VI
* @vf: the VF owning the VI
* @viid: virtual interface identifiler
*
* Free a previously allocated virtual interface.
*/
int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
unsigned int vf, unsigned int viid)
{
struct fw_vi_cmd c;
memset(&c, 0, sizeof(c));
c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) |
FW_CMD_REQUEST_F |
FW_CMD_EXEC_F |
FW_VI_CMD_PFN_V(pf) |
FW_VI_CMD_VFN_V(vf));
c.alloc_to_len16 = cpu_to_be32(FW_VI_CMD_FREE_F | FW_LEN16(c));
c.type_viid = cpu_to_be16(FW_VI_CMD_VIID_V(viid));
return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
}
/**
* t4_set_rxmode - set Rx properties of a virtual interface
* @adap: the adapter
......@@ -5767,6 +5902,22 @@ static int get_flash_params(struct adapter *adap)
return 0;
}
static void set_pcie_completion_timeout(struct adapter *adapter, u8 range)
{
u16 val;
u32 pcie_cap;
pcie_cap = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
if (pcie_cap) {
pci_read_config_word(adapter->pdev,
pcie_cap + PCI_EXP_DEVCTL2, &val);
val &= ~PCI_EXP_DEVCTL2_COMP_TIMEOUT;
val |= range;
pci_write_config_word(adapter->pdev,
pcie_cap + PCI_EXP_DEVCTL2, val);
}
}
/**
* t4_prep_adapter - prepare SW and HW for operation
* @adapter: the adapter
......@@ -5839,6 +5990,9 @@ int t4_prep_adapter(struct adapter *adapter)
adapter->params.nports = 1;
adapter->params.portvec = 1;
adapter->params.vpd.cclk = 50000;
/* Set pci completion timeout value to 4 seconds. */
set_pcie_completion_timeout(adapter, 0xd);
return 0;
}
......@@ -6038,12 +6192,19 @@ int t4_init_tp_params(struct adapter *adap)
/* Cache the adapter's Compressed Filter Mode and global Incress
* Configuration.
*/
if (adap->flags & FW_OK) {
t4_fw_tp_pio_rw(adap, &adap->params.tp.vlan_pri_map, 1,
TP_VLAN_PRI_MAP_A, 1);
t4_fw_tp_pio_rw(adap, &adap->params.tp.ingress_config, 1,
TP_INGRESS_CONFIG_A, 1);
} else {
t4_read_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A,
&adap->params.tp.vlan_pri_map, 1,
TP_VLAN_PRI_MAP_A);
t4_read_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A,
&adap->params.tp.ingress_config, 1,
TP_INGRESS_CONFIG_A);
}
/* Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field
* shift positions of several elements of the Compressed Filter Tuple
......
......@@ -772,7 +772,7 @@ struct fw_ldst_cmd {
} addrval;
struct fw_ldst_idctxt {
__be32 physid;
__be32 msg_pkd;
__be32 msg_ctxtflush;
__be32 ctxt_data7;
__be32 ctxt_data6;
__be32 ctxt_data5;
......@@ -834,6 +834,10 @@ struct fw_ldst_cmd {
#define FW_LDST_CMD_MSG_S 31
#define FW_LDST_CMD_MSG_V(x) ((x) << FW_LDST_CMD_MSG_S)
#define FW_LDST_CMD_CTXTFLUSH_S 30
#define FW_LDST_CMD_CTXTFLUSH_V(x) ((x) << FW_LDST_CMD_CTXTFLUSH_S)
#define FW_LDST_CMD_CTXTFLUSH_F FW_LDST_CMD_CTXTFLUSH_V(1U)
#define FW_LDST_CMD_PADDR_S 8
#define FW_LDST_CMD_PADDR_V(x) ((x) << FW_LDST_CMD_PADDR_S)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment