Skip to content

Commit

Permalink
cxgb4: Initialize T5
Browse files Browse the repository at this point in the history
Signed-off-by: Santosh Rastapur <santosh@chelsio.com>
Signed-off-by: Vipul Pandya <vipul@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Santosh Rastapur authored and David S. Miller committed Mar 14, 2013
1 parent 2422d9a commit 0a57a53
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 48 deletions.
85 changes: 65 additions & 20 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,17 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = {
};

#define FW_FNAME "cxgb4/t4fw.bin"
#define FW5_FNAME "cxgb4/t5fw.bin"
#define FW_CFNAME "cxgb4/t4-config.txt"
#define FW5_CFNAME "cxgb4/t5-config.txt"

MODULE_DESCRIPTION(DRV_DESC);
MODULE_AUTHOR("Chelsio Communications");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl);
MODULE_FIRMWARE(FW_FNAME);
MODULE_FIRMWARE(FW5_FNAME);

/*
* Normally we're willing to become the firmware's Master PF but will be happy
Expand Down Expand Up @@ -319,10 +322,14 @@ static bool vf_acls;
module_param(vf_acls, bool, 0644);
MODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement");

static unsigned int num_vf[4];
/* Since T5 has more num of PFs, using NUM_OF_PF_WITH_SRIOV_T5
* macro as num_vf array size
*/
static unsigned int num_vf[NUM_OF_PF_WITH_SRIOV_T5];

module_param_array(num_vf, uint, NULL, 0644);
MODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3");
MODULE_PARM_DESC(num_vf,
"number of VFs for each of PFs 0-3 for T4 and PFs 0-7 for T5");
#endif

/*
Expand Down Expand Up @@ -1002,40 +1009,52 @@ freeout: t4_free_sge_resources(adap);
static int upgrade_fw(struct adapter *adap)
{
int ret;
u32 vers;
u32 vers, exp_major;
const struct fw_hdr *hdr;
const struct firmware *fw;
struct device *dev = adap->pdev_dev;
char *fw_file_name;

ret = request_firmware(&fw, FW_FNAME, dev);
switch (CHELSIO_CHIP_VERSION(adap->chip)) {
case CHELSIO_T4:
fw_file_name = FW_FNAME;
exp_major = FW_VERSION_MAJOR;
break;
case CHELSIO_T5:
fw_file_name = FW5_FNAME;
exp_major = FW_VERSION_MAJOR_T5;
break;
default:
dev_err(dev, "Unsupported chip type, %x\n", adap->chip);
return -EINVAL;
}

ret = request_firmware(&fw, fw_file_name, dev);
if (ret < 0) {
dev_err(dev, "unable to load firmware image " FW_FNAME
", error %d\n", ret);
dev_err(dev, "unable to load firmware image %s, error %d\n",
fw_file_name, ret);
return ret;
}

hdr = (const struct fw_hdr *)fw->data;
vers = ntohl(hdr->fw_ver);
if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) {
if (FW_HDR_FW_VER_MAJOR_GET(vers) != exp_major) {
ret = -EINVAL; /* wrong major version, won't do */
goto out;
}

/*
* If the flash FW is unusable or we found something newer, load it.
*/
if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR ||
if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != exp_major ||
vers > adap->params.fw_vers) {
dev_info(dev, "upgrading firmware ...\n");
ret = t4_fw_upgrade(adap, adap->mbox, fw->data, fw->size,
/*force=*/false);
if (!ret)
dev_info(dev, "firmware successfully upgraded to "
FW_FNAME " (%d.%d.%d.%d)\n",
FW_HDR_FW_VER_MAJOR_GET(vers),
FW_HDR_FW_VER_MINOR_GET(vers),
FW_HDR_FW_VER_MICRO_GET(vers),
FW_HDR_FW_VER_BUILD_GET(vers));
dev_info(dev,
"firmware upgraded to version %pI4 from %s\n",
&hdr->fw_ver, fw_file_name);
else
dev_err(dev, "firmware upgrade failed! err=%d\n", -ret);
} else {
Expand Down Expand Up @@ -1413,7 +1432,8 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*/
static inline unsigned int mk_adap_vers(const struct adapter *ap)
{
return 4 | (ap->params.rev << 10) | (1 << 16);
return CHELSIO_CHIP_VERSION(ap->chip) |
(CHELSIO_CHIP_RELEASE(ap->chip) << 10) | (1 << 16);
}

static void reg_block_dump(struct adapter *ap, void *buf, unsigned int start,
Expand Down Expand Up @@ -3745,6 +3765,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
unsigned long mtype = 0, maddr = 0;
u32 finiver, finicsum, cfcsum;
int ret, using_flash;
char *fw_config_file, fw_config_file_path[256];

/*
* Reset device if necessary.
Expand All @@ -3761,7 +3782,21 @@ static int adap_init0_config(struct adapter *adapter, int reset)
* then use that. Otherwise, use the configuration file stored
* in the adapter flash ...
*/
ret = request_firmware(&cf, FW_CFNAME, adapter->pdev_dev);
switch (CHELSIO_CHIP_VERSION(adapter->chip)) {
case CHELSIO_T4:
fw_config_file = FW_CFNAME;
break;
case CHELSIO_T5:
fw_config_file = FW5_CFNAME;
break;
default:
dev_err(adapter->pdev_dev, "Device %d is not supported\n",
adapter->pdev->device);
ret = -EINVAL;
goto bye;
}

ret = request_firmware(&cf, fw_config_file, adapter->pdev_dev);
if (ret < 0) {
using_flash = 1;
mtype = FW_MEMTYPE_CF_FLASH;
Expand Down Expand Up @@ -3877,6 +3912,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
if (ret < 0)
goto bye;

sprintf(fw_config_file_path, "/lib/firmware/%s", fw_config_file);
/*
* Return successfully and note that we're operating with parameters
* not supplied by the driver, rather than from hard-wired
Expand All @@ -3887,7 +3923,7 @@ static int adap_init0_config(struct adapter *adapter, int reset)
"Configuration File %s, version %#x, computed checksum %#x\n",
(using_flash
? "in device FLASH"
: "/lib/firmware/" FW_CFNAME),
: fw_config_file_path),
finiver, cfcsum);
return 0;

Expand Down Expand Up @@ -4015,8 +4051,10 @@ static int adap_init0_no_config(struct adapter *adapter, int reset)
*/
{
int pf, vf;
int max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 :
NUM_OF_PF_WITH_SRIOV_T5;

for (pf = 0; pf < ARRAY_SIZE(num_vf); pf++) {
for (pf = 0; pf < max_no_pf; pf++) {
if (num_vf[pf] <= 0)
continue;

Expand Down Expand Up @@ -4814,7 +4852,8 @@ static void print_port_info(const struct net_device *dev)
sprintf(bufp, "BASE-%s", base[pi->port_type]);

netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n",
adap->params.vpd.id, adap->params.rev, buf,
adap->params.vpd.id,
CHELSIO_CHIP_RELEASE(adap->params.rev), buf,
is_offload(adap) ? "R" : "", adap->params.pci.width, spd,
(adap->flags & USING_MSIX) ? " MSI-X" :
(adap->flags & USING_MSI) ? " MSI" : "");
Expand Down Expand Up @@ -4861,6 +4900,9 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
struct port_info *pi;
bool highdma = false;
struct adapter *adapter = NULL;
#ifdef CONFIG_PCI_IOV
int max_no_pf;
#endif

printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION);

Expand Down Expand Up @@ -5052,7 +5094,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

sriov:
#ifdef CONFIG_PCI_IOV
if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0)
max_no_pf = is_t4(adapter->chip) ? NUM_OF_PF_WITH_SRIOV_T4 :
NUM_OF_PF_WITH_SRIOV_T5;

if (func < max_no_pf && num_vf[func] > 0)
if (pci_enable_sriov(pdev, num_vf[func]) == 0)
dev_info(&pdev->dev,
"instantiated %u virtual functions\n",
Expand Down
37 changes: 27 additions & 10 deletions drivers/net/ethernet/chelsio/cxgb4/sge.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,10 +506,14 @@ static void unmap_rx_buf(struct adapter *adap, struct sge_fl *q)

static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
{
u32 val;
if (q->pend_cred >= 8) {
val = PIDX(q->pend_cred / 8);
if (!is_t4(adap->chip))
val |= DBTYPE(1);
wmb();
t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL), DBPRIO(1) |
QID(q->cntxt_id) | PIDX(q->pend_cred / 8));
QID(q->cntxt_id) | val);
q->pend_cred &= 7;
}
}
Expand Down Expand Up @@ -1555,16 +1559,18 @@ static noinline int handle_trace_pkt(struct adapter *adap,
const struct pkt_gl *gl)
{
struct sk_buff *skb;
struct cpl_trace_pkt *p;

skb = cxgb4_pktgl_to_skb(gl, RX_PULL_LEN, RX_PULL_LEN);
if (unlikely(!skb)) {
t4_pktgl_free(gl);
return 0;
}

p = (struct cpl_trace_pkt *)skb->data;
__skb_pull(skb, sizeof(*p));
if (is_t4(adap->chip))
__skb_pull(skb, sizeof(struct cpl_trace_pkt));
else
__skb_pull(skb, sizeof(struct cpl_t5_trace_pkt));

skb_reset_mac_header(skb);
skb->protocol = htons(0xffff);
skb->dev = adap->port[0];
Expand Down Expand Up @@ -1625,8 +1631,10 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
const struct cpl_rx_pkt *pkt;
struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
struct sge *s = &q->adap->sge;
int cpl_trace_pkt = is_t4(q->adap->chip) ?
CPL_TRACE_PKT : CPL_TRACE_PKT_T5;

if (unlikely(*(u8 *)rsp == CPL_TRACE_PKT))
if (unlikely(*(u8 *)rsp == cpl_trace_pkt))
return handle_trace_pkt(q->adap, si);

pkt = (const struct cpl_rx_pkt *)rsp;
Expand Down Expand Up @@ -2587,11 +2595,20 @@ static int t4_sge_init_hard(struct adapter *adap)
* Set up to drop DOORBELL writes when the DOORBELL FIFO overflows
* and generate an interrupt when this occurs so we can recover.
*/
t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS,
V_HP_INT_THRESH(M_HP_INT_THRESH) |
V_LP_INT_THRESH(M_LP_INT_THRESH),
V_HP_INT_THRESH(dbfifo_int_thresh) |
V_LP_INT_THRESH(dbfifo_int_thresh));
if (is_t4(adap->chip)) {
t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS,
V_HP_INT_THRESH(M_HP_INT_THRESH) |
V_LP_INT_THRESH(M_LP_INT_THRESH),
V_HP_INT_THRESH(dbfifo_int_thresh) |
V_LP_INT_THRESH(dbfifo_int_thresh));
} else {
t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS,
V_LP_INT_THRESH_T5(M_LP_INT_THRESH_T5),
V_LP_INT_THRESH_T5(dbfifo_int_thresh));
t4_set_reg_field(adap, SGE_DBFIFO_STATUS2,
V_HP_INT_THRESH_T5(M_HP_INT_THRESH_T5),
V_HP_INT_THRESH_T5(dbfifo_int_thresh));
}
t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_ENABLE_DROP,
F_ENABLE_DROP);

Expand Down
Loading

0 comments on commit 0a57a53

Please sign in to comment.