From 7207c0d1540b679993d1f0bb9c1ff8e068958c75 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Thu, 9 Oct 2014 05:48:45 +0530 Subject: [PATCH 1/3] cxgb4/cxgb4vf: Updated the LSO transfer length in CPL_TX_PKT_LSO for T5 Update the lso length for T5 adapter and fix PIDX_T5 macro Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 5 ++++- drivers/net/ethernet/chelsio/cxgb4/t4_msg.h | 1 + drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 5 ++--- drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 5 ++++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index fab4c84a1da4..5e1b314e11af 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -1123,7 +1123,10 @@ out_free: dev_kfree_skb_any(skb); lso->c.ipid_ofst = htons(0); lso->c.mss = htons(ssi->gso_size); lso->c.seqno_offset = htonl(0); - lso->c.len = htonl(skb->len); + if (is_t4(adap->params.chip)) + lso->c.len = htonl(skb->len); + else + lso->c.len = htonl(LSO_T5_XFER_SIZE(skb->len)); cpl = (void *)(lso + 1); cntrl = TXPKT_CSUM_TYPE(v6 ? TX_CSUM_TCPIP6 : TX_CSUM_TCPIP) | TXPKT_IPHDR_LEN(l3hdr_len) | diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h index 52e08103f221..5f4db2398c71 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_msg.h @@ -527,6 +527,7 @@ struct cpl_tx_pkt_lso_core { #define LSO_LAST_SLICE (1 << 22) #define LSO_FIRST_SLICE (1 << 23) #define LSO_OPCODE(x) ((x) << 24) +#define LSO_T5_XFER_SIZE(x) ((x) << 0) __be16 ipid_ofst; __be16 mss; __be32 seqno_offset; diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h index eee272883027..a1024db5dc13 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -72,9 +72,8 @@ #define PIDX_MASK 0x00003fffU #define PIDX_SHIFT 0 #define PIDX(x) ((x) << PIDX_SHIFT) -#define S_PIDX_T5 0 -#define M_PIDX_T5 0x1fffU -#define PIDX_T5(x) (((x) >> S_PIDX_T5) & M_PIDX_T5) +#define PIDX_SHIFT_T5 0 +#define PIDX_T5(x) ((x) << PIDX_SHIFT_T5) #define SGE_TIMERREGS 6 diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index a5fb9493dee8..85036e6b42c4 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c @@ -1208,7 +1208,10 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) lso->ipid_ofst = cpu_to_be16(0); lso->mss = cpu_to_be16(ssi->gso_size); lso->seqno_offset = cpu_to_be32(0); - lso->len = cpu_to_be32(skb->len); + if (is_t4(adapter->params.chip)) + lso->len = cpu_to_be32(skb->len); + else + lso->len = cpu_to_be32(LSO_T5_XFER_SIZE(skb->len)); /* * Set up TX Packet CPL pointer, control word and perform From 897d55df3ca794ad4522472d46aa2dbbface8c37 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Thu, 9 Oct 2014 05:48:46 +0530 Subject: [PATCH 2/3] cxgb4vf: Add 40G support for cxgb4vf driver Add 40G support for cxgb4vf driver. ethtool speed values are just numbers of megabits and there is no SPEED_40000 in ethtool speed values. To be consistent, use integer constants directly for all speeds. Use is_x_10g_port()("is 10Gb/s or higher") in cfg_queues() instead of is_10g_port() ("is exactly 10Gb/s"). Else we will end up using a single "Queue Set" on 40Gb/s adapters. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 12 ++++++++---- drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 6 ++++++ drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 10 +++++++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 8498a641b2e3..bfa398d91826 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -163,15 +163,19 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) netif_carrier_on(dev); switch (pi->link_cfg.speed) { - case SPEED_10000: + case 40000: + s = "40Gbps"; + break; + + case 10000: s = "10Gbps"; break; - case SPEED_1000: + case 1000: s = "1000Mbps"; break; - case SPEED_100: + case 100: s = "100Mbps"; break; @@ -2351,7 +2355,7 @@ static void cfg_queues(struct adapter *adapter) struct port_info *pi = adap2pinfo(adapter, pidx); pi->first_qset = qidx; - pi->nqsets = is_10g_port(&pi->link_cfg) ? q10g : 1; + pi->nqsets = is_x_10g_port(&pi->link_cfg) ? q10g : 1; qidx += pi->nqsets; } s->ethqsets = qidx; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index f412d0fa0850..95df61dcb4ce 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h @@ -228,6 +228,12 @@ static inline bool is_10g_port(const struct link_config *lc) return (lc->supported & SUPPORTED_10000baseT_Full) != 0; } +static inline bool is_x_10g_port(const struct link_config *lc) +{ + return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0 || + (lc->supported & FW_PORT_CAP_SPEED_40G) != 0; +} + static inline unsigned int core_ticks_per_usec(const struct adapter *adapter) { return adapter->params.vpd.cclk / 1000; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 25dfeb8f28ed..e984fdc48ba2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -327,6 +327,8 @@ int t4vf_port_init(struct adapter *adapter, int pidx) v |= SUPPORTED_1000baseT_Full; if (word & FW_PORT_CAP_SPEED_10G) v |= SUPPORTED_10000baseT_Full; + if (word & FW_PORT_CAP_SPEED_40G) + v |= SUPPORTED_40000baseSR4_Full; if (word & FW_PORT_CAP_ANEG) v |= SUPPORTED_Autoneg; init_link_config(&pi->link_cfg, v); @@ -1352,11 +1354,13 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) if (word & FW_PORT_CMD_TXPAUSE) fc |= PAUSE_TX; if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) - speed = SPEED_100; + speed = 100; else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) - speed = SPEED_1000; + speed = 1000; else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) - speed = SPEED_10000; + speed = 10000; + else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + speed = 40000; /* * Scan all of our "ports" (Virtual Interfaces) looking for From 8203b509c5b7aab7a8170626ce02372c61da2cdd Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Thu, 9 Oct 2014 05:48:47 +0530 Subject: [PATCH 3/3] cxgb4: Wait for device to get ready before reading any register Call t4_wait_dev_ready() before attempting to read the PL_WHOAMI register (to determine which function we have been attached to). This prevents us from failing on that read if it comes right after a RESET. Signed-off-by: Hariprasad Shenai Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 6 +++++- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 17 ++++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h index 9b2c669b6522..410ed5805a9a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -968,7 +968,7 @@ void t4_intr_enable(struct adapter *adapter); void t4_intr_disable(struct adapter *adapter); int t4_slow_intr_handler(struct adapter *adapter); -int t4_wait_dev_ready(struct adapter *adap); +int t4_wait_dev_ready(void __iomem *regs); int t4_link_start(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); diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 321f3d9385c9..5b38e955af6e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -6137,7 +6137,7 @@ static pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev) pci_save_state(pdev); pci_cleanup_aer_uncorrect_error_status(pdev); - if (t4_wait_dev_ready(adap) < 0) + if (t4_wait_dev_ready(adap->regs) < 0) return PCI_ERS_RESULT_DISCONNECT; if (t4_fw_hello(adap, adap->fn, adap->fn, MASTER_MUST, NULL) < 0) return PCI_ERS_RESULT_DISCONNECT; @@ -6530,6 +6530,10 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_disable_device; } + err = t4_wait_dev_ready(regs); + if (err < 0) + goto out_unmap_bar0; + /* We control everything through one PF */ func = SOURCEPF_GET(readl(regs + PL_WHOAMI)); if (func != ent->driver_data) { diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 22d7581341a9..1fff1495fe31 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -3845,12 +3845,19 @@ static void init_link_config(struct link_config *lc, unsigned int caps) } } -int t4_wait_dev_ready(struct adapter *adap) +#define CIM_PF_NOACCESS 0xeeeeeeee + +int t4_wait_dev_ready(void __iomem *regs) { - if (t4_read_reg(adap, PL_WHOAMI) != 0xffffffff) + u32 whoami; + + whoami = readl(regs + PL_WHOAMI); + if (whoami != 0xffffffff && whoami != CIM_PF_NOACCESS) return 0; + msleep(500); - return t4_read_reg(adap, PL_WHOAMI) != 0xffffffff ? 0 : -EIO; + whoami = readl(regs + PL_WHOAMI); + return (whoami != 0xffffffff && whoami != CIM_PF_NOACCESS ? 0 : -EIO); } struct flash_desc { @@ -3919,10 +3926,6 @@ int t4_prep_adapter(struct adapter *adapter) uint16_t device_id; u32 pl_rev; - ret = t4_wait_dev_ready(adapter); - if (ret < 0) - return ret; - get_pci_mode(adapter, &adapter->params.pci); pl_rev = G_REV(t4_read_reg(adapter, PL_REV));