All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] cxgbe: bug fixes and updates
@ 2018-02-04  6:06 Rahul Lakkireddy
  2018-02-04  6:06 ` [PATCH 1/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
                   ` (7 more replies)
  0 siblings, 8 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

Patch 1 fixes secondary process initialization failure.

Patch 2 fixes issue where link state is not updated when speed is
changed.

Patches 3 and 4 allow configuring RSS hash and key.

Patch 5 updates link Forward Error Correction (FEC) to support IEEE
802.3 standard based FEC selection.

Patches 6 and 7 update to new firmware 32-bit port capabilities to
support more link speeds and module types.

Thanks,
Rahul

Kumar Sanghvi (5):
  cxgbe: fix secondary process initialization
  cxgbe: update link state when link speed changes
  cxgbe: add support to update RSS hash configuration and key
  cxgbe: add support to get programmed RSS hash configuration and key
  cxgbe: update link Forward Error Correction (FEC)

Rahul Lakkireddy (2):
  cxgbe: update link configuration for 32-bit port capability
  cxgbe: rework and use 32-bit port capability

 doc/guides/nics/cxgbe.rst               |  12 +-
 doc/guides/nics/features/cxgbe.ini      |   2 +
 doc/guides/rel_notes/release_18_02.rst  |   3 +
 drivers/net/cxgbe/base/adapter.h        |   5 +-
 drivers/net/cxgbe/base/common.h         |  57 ++-
 drivers/net/cxgbe/base/t4_hw.c          | 674 ++++++++++++++++++++++++++------
 drivers/net/cxgbe/base/t4_regs.h        |  25 ++
 drivers/net/cxgbe/base/t4fw_interface.h | 172 +++++++-
 drivers/net/cxgbe/cxgbe.h               |   2 +
 drivers/net/cxgbe/cxgbe_ethdev.c        | 118 +++++-
 drivers/net/cxgbe/cxgbe_main.c          | 118 ++++--
 drivers/net/cxgbe/sge.c                 |   5 +-
 12 files changed, 995 insertions(+), 198 deletions(-)

-- 
2.15.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/7] cxgbe: fix secondary process initialization
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
@ 2018-02-04  6:06 ` Rahul Lakkireddy
  2018-02-05 17:23   ` Ferruh Yigit
  2018-02-04  6:06 ` [PATCH 2/7] cxgbe: update link state when link speed changes Rahul Lakkireddy
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

rte_eth_dev_allocate already assigns the eth_dev_data. So,
don't allocate it separately as part of probe function. And we
save this eth_dev_data as part of txq structure.

Attach to rte_eth_dev devices allocated by Primary process for
Ports other than Port-0 in the secondary process.

Fixes: 8318984927ff ("cxgbe: add pmd skeleton")
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 doc/guides/nics/features/cxgbe.ini |  1 +
 drivers/net/cxgbe/base/adapter.h   |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c   | 28 +++++++++++++++++++++++-----
 drivers/net/cxgbe/cxgbe_main.c     | 11 ++---------
 drivers/net/cxgbe/sge.c            |  5 +++--
 5 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/doc/guides/nics/features/cxgbe.ini b/doc/guides/nics/features/cxgbe.ini
index 3d0fde2fd..1b9d81ffb 100644
--- a/doc/guides/nics/features/cxgbe.ini
+++ b/doc/guides/nics/features/cxgbe.ini
@@ -24,6 +24,7 @@ Basic stats          = Y
 Stats per queue      = Y
 EEPROM dump          = Y
 Registers dump       = Y
+Multiprocess aware   = Y
 BSD nic_uio          = Y
 Linux UIO            = Y
 Linux VFIO           = Y
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index f2057af14..0c1a1be25 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -267,6 +267,7 @@ struct sge_eth_tx_stats {	/* Ethernet tx queue statistics */
 struct sge_eth_txq {                   /* state for an SGE Ethernet Tx queue */
 	struct sge_txq q;
 	struct rte_eth_dev *eth_dev;   /* port that this queue belongs to */
+	struct rte_eth_dev_data *data;
 	struct sge_eth_tx_stats stats; /* queue statistics */
 	rte_spinlock_t txq_lock;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 5cd260f48..6d56f3c1b 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1004,14 +1004,32 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->dev_ops = &cxgbe_eth_dev_ops;
 	eth_dev->rx_pkt_burst = &cxgbe_recv_pkts;
 	eth_dev->tx_pkt_burst = &cxgbe_xmit_pkts;
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 
-	/* for secondary processes, we don't initialise any further as primary
-	 * has already done this work.
+	/* for secondary processes, we attach to ethdevs allocated by primary
+	 * and do minimal initialization.
 	 */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+		int i;
+
+		for (i = 1; i < MAX_NPORTS; i++) {
+			struct rte_eth_dev *rest_eth_dev;
+			char namei[RTE_ETH_NAME_MAX_LEN];
+
+			snprintf(namei, sizeof(namei), "cxgbe%d", i);
+			rest_eth_dev = rte_eth_dev_attach_secondary(namei);
+			if (rest_eth_dev) {
+				rest_eth_dev->device = &pci_dev->device;
+				rest_eth_dev->dev_ops =
+					eth_dev->dev_ops;
+				rest_eth_dev->rx_pkt_burst =
+					eth_dev->rx_pkt_burst;
+				rest_eth_dev->tx_pkt_burst =
+					eth_dev->tx_pkt_burst;
+			}
+		}
 		return 0;
-
-	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	}
 
 	snprintf(name, sizeof(name), "cxgbeadapter%d", eth_dev->data->port_id);
 	adapter = rte_zmalloc(name, sizeof(*adapter), 0);
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 28db6c061..c502fadf7 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -1266,8 +1266,6 @@ int cxgbe_probe(struct adapter *adapter)
 
 	for_each_port(adapter, i) {
 		char name[RTE_ETH_NAME_MAX_LEN];
-		struct rte_eth_dev_data *data = NULL;
-		const unsigned int numa_node = rte_socket_id();
 
 		pi = &adapter->port[i];
 		pi->adapter = adapter;
@@ -1293,13 +1291,8 @@ int cxgbe_probe(struct adapter *adapter)
 		if (!pi->eth_dev)
 			goto out_free;
 
-		data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-		if (!data)
-			goto out_free;
-
-		data->port_id = adapter->eth_dev->data->port_id + i;
-
-		pi->eth_dev->data = data;
+		pi->eth_dev->data->port_id =
+			adapter->eth_dev->data->port_id + i;
 
 allocate_mac:
 		pi->eth_dev->device = &adapter->pdev->device;
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 3d5aa596f..6ff8bc46b 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1095,7 +1095,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
 	u32 wr_mid;
 	u64 cntrl, *end;
 	bool v6;
-	u32 max_pkt_len = txq->eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
+	u32 max_pkt_len = txq->data->dev_conf.rxmode.max_rx_pkt_len;
 
 	/* Reject xmit if queue is stopped */
 	if (unlikely(txq->flags & EQ_STOPPED))
@@ -1115,7 +1115,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
 	    (unlikely(m->pkt_len > max_pkt_len)))
 		goto out_free;
 
-	pi = (struct port_info *)txq->eth_dev->data->dev_private;
+	pi = (struct port_info *)txq->data->dev_private;
 	adap = pi->adapter;
 
 	cntrl = F_TXPKT_L4CSUM_DIS | F_TXPKT_IPCSUM_DIS;
@@ -1997,6 +1997,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
 	txq->stats.mapping_err = 0;
 	txq->flags |= EQ_STOPPED;
 	txq->eth_dev = eth_dev;
+	txq->data = eth_dev->data;
 	t4_os_lock_init(&txq->txq_lock);
 	return 0;
 }
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/7] cxgbe: update link state when link speed changes
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
  2018-02-04  6:06 ` [PATCH 1/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
@ 2018-02-04  6:06 ` Rahul Lakkireddy
  2018-02-05 17:05   ` Ferruh Yigit
  2018-02-04  6:06 ` [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Original work by Surendra Mobiya <surendra@chelsio.com>

Fixes: cdac6e2eeafc ("cxgbe: add link related functions")
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 6d56f3c1b..5a25125fe 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -227,7 +227,8 @@ static int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
 	unsigned int work_done, budget = 4;
 
 	cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
-	if (old_link->link_status == pi->link_cfg.link_ok)
+	if (old_link->link_status == pi->link_cfg.link_ok &&
+	    old_link->link_speed == pi->link_cfg.speed)
 		return -1;  /* link not changed */
 
 	eth_dev->data->dev_link.link_status = pi->link_cfg.link_ok;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
  2018-02-04  6:06 ` [PATCH 1/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
  2018-02-04  6:06 ` [PATCH 2/7] cxgbe: update link state when link speed changes Rahul Lakkireddy
@ 2018-02-04  6:06 ` Rahul Lakkireddy
  2018-02-05 17:09   ` Ferruh Yigit
  2018-02-04  6:06 ` [PATCH 4/7] cxgbe: add support to get programmed " Rahul Lakkireddy
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Add firmware API for updating RSS hash configuration and key.  Move
RSS hash configuration from cxgb4_write_rss() to a separate function
cxgbe_write_rss_conf().

Also, rename cxgb4_write_rss() to cxgbe_write_rss() for consistency.

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 doc/guides/nics/cxgbe.rst               |  2 +
 doc/guides/nics/features/cxgbe.ini      |  1 +
 doc/guides/rel_notes/release_18_02.rst  |  3 ++
 drivers/net/cxgbe/base/adapter.h        |  4 +-
 drivers/net/cxgbe/base/common.h         |  3 ++
 drivers/net/cxgbe/base/t4_hw.c          | 73 +++++++++++++++++++++++++++
 drivers/net/cxgbe/base/t4_regs.h        | 25 +++++++++
 drivers/net/cxgbe/base/t4fw_interface.h | 89 +++++++++++++++++++++++++++++++++
 drivers/net/cxgbe/cxgbe.h               |  2 +
 drivers/net/cxgbe/cxgbe_ethdev.c        | 32 ++++++++++++
 drivers/net/cxgbe/cxgbe_main.c          | 79 ++++++++++++++++++++++-------
 11 files changed, 295 insertions(+), 18 deletions(-)

diff --git a/doc/guides/nics/cxgbe.rst b/doc/guides/nics/cxgbe.rst
index 8651a7be6..6126167c5 100644
--- a/doc/guides/nics/cxgbe.rst
+++ b/doc/guides/nics/cxgbe.rst
@@ -45,6 +45,8 @@ CXGBE PMD has support for:
 
 - Multiple queues for TX and RX
 - Receiver Side Steering (RSS)
+  Receiver Side Steering (RSS) on IPv4, IPv6, IPv4-TCP/UDP, IPv6-TCP/UDP.
+  For 4-tuple, enabling 'RSS on TCP' and 'RSS on TCP + UDP' is supported.
 - VLAN filtering
 - Checksum offload
 - Promiscuous mode
diff --git a/doc/guides/nics/features/cxgbe.ini b/doc/guides/nics/features/cxgbe.ini
index 1b9d81ffb..6cf5c13f5 100644
--- a/doc/guides/nics/features/cxgbe.ini
+++ b/doc/guides/nics/features/cxgbe.ini
@@ -14,6 +14,7 @@ TSO                  = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 RSS hash             = Y
+RSS key update       = Y
 Flow control         = Y
 CRC offload          = Y
 VLAN offload         = Y
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
index 689080bed..51a50cf93 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -204,6 +204,9 @@ New Features
     is unaffected by these changes, and can continue to be used for this
     and subsequent releases until such time as it's deprecation is announced.
 
+* **Added RSS hash and key update to CXGBE PMD.**
+
+  Support to update RSS hash and key has been added to CXGBE PMD.
 
 API Changes
 -----------
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 0c1a1be25..4db2951e7 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -77,6 +77,7 @@ struct port_info {
 	u16    *rss;                    /* rss table */
 	u8     rss_mode;                /* rss mode */
 	u16    rss_size;                /* size of VI's RSS table slice */
+	u64    rss_hf;			/* RSS Hash Function */
 };
 
 /* Enable or disable autonegotiation.  If this is set to enable,
@@ -736,6 +737,7 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us,
 			       unsigned int cnt);
 int cxgbe_poll(struct sge_rspq *q, struct rte_mbuf **rx_pkts,
 	       unsigned int budget, unsigned int *work_done);
-int cxgb4_write_rss(const struct port_info *pi, const u16 *queues);
+int cxgbe_write_rss(const struct port_info *pi, const u16 *queues);
+int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t flags);
 
 #endif /* __T4_ADAPTER_H__ */
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 1eda57d09..5301f7474 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -410,6 +410,9 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
 			int start, int n, const u16 *rspq, unsigned int nrspq);
 int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 		     unsigned int flags, unsigned int defq);
+void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
+		     unsigned int start_index, unsigned int rw);
+void t4_write_rss_key(struct adapter *adap, u32 *key, int idx);
 
 enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS };
 int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid,
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 56f38c838..9eb83fd5e 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2166,6 +2166,79 @@ int t4_seeprom_wp(struct adapter *adapter, int enable)
 	return t4_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 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
+ */
+void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
+		     unsigned int start_index, unsigned int rw)
+{
+	int cmd = FW_LDST_ADDRSPC_TP_PIO;
+	struct fw_ldst_cmd c;
+	unsigned int i;
+	int ret;
+
+	for (i = 0 ; i < nregs; i++) {
+		memset(&c, 0, sizeof(c));
+		c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) |
+						F_FW_CMD_REQUEST |
+						(rw ? F_FW_CMD_READ :
+						      F_FW_CMD_WRITE) |
+						V_FW_LDST_CMD_ADDRSPACE(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 == 0) {
+			if (rw)
+				vals[i] = be32_to_cpu(c.u.addrval.val);
+		}
+	}
+}
+
+/**
+ * t4_write_rss_key - program one of the RSS keys
+ * @adap: the adapter
+ * @key: 10-entry array holding the 320-bit RSS key
+ * @idx: which RSS key to write
+ *
+ * Writes one of the RSS keys with the given 320-bit value.  If @idx is
+ * 0..15 the corresponding entry in the RSS key table is written,
+ * otherwise the global RSS key is written.
+ */
+void t4_write_rss_key(struct adapter *adap, u32 *key, int idx)
+{
+	u32 vrt = t4_read_reg(adap, A_TP_RSS_CONFIG_VRT);
+	u8 rss_key_addr_cnt = 16;
+
+	/* T6 and later: for KeyMode 3 (per-vf and per-vf scramble),
+	 * allows access to key addresses 16-63 by using KeyWrAddrX
+	 * as index[5:4](upper 2) into key table
+	 */
+	if ((CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) &&
+	    (vrt & F_KEYEXTEND) && (G_KEYMODE(vrt) == 3))
+		rss_key_addr_cnt = 32;
+
+	t4_fw_tp_pio_rw(adap, key, 10, A_TP_RSS_SECRET_KEY0, 0);
+
+	if (idx >= 0 && idx < rss_key_addr_cnt) {
+		if (rss_key_addr_cnt > 16)
+			t4_write_reg(adap, A_TP_RSS_CONFIG_VRT,
+				     V_KEYWRADDRX(idx >> 4) |
+				     V_T6_VFWRADDR(idx) | F_KEYWREN);
+		else
+			t4_write_reg(adap, A_TP_RSS_CONFIG_VRT,
+				     V_KEYWRADDR(idx) | F_KEYWREN);
+	}
+}
+
 /**
  * t4_config_rss_range - configure a portion of the RSS mapping table
  * @adapter: the adapter
diff --git a/drivers/net/cxgbe/base/t4_regs.h b/drivers/net/cxgbe/base/t4_regs.h
index 1100e16fe..0f0bca910 100644
--- a/drivers/net/cxgbe/base/t4_regs.h
+++ b/drivers/net/cxgbe/base/t4_regs.h
@@ -503,9 +503,34 @@
 #define V_MTUVALUE(x) ((x) << S_MTUVALUE)
 #define G_MTUVALUE(x) (((x) >> S_MTUVALUE) & M_MTUVALUE)
 
+#define A_TP_RSS_CONFIG_VRT 0x7e00
+
+#define S_KEYMODE    6
+#define M_KEYMODE    0x3U
+#define G_KEYMODE(x) (((x) >> S_KEYMODE) & M_KEYMODE)
+
+#define S_KEYWRADDR    0
+#define V_KEYWRADDR(x) ((x) << S_KEYWRADDR)
+
+#define S_KEYWREN    4
+#define V_KEYWREN(x) ((x) << S_KEYWREN)
+#define F_KEYWREN    V_KEYWREN(1U)
+
+#define S_KEYWRADDRX    30
+#define V_KEYWRADDRX(x) ((x) << S_KEYWRADDRX)
+
+#define S_KEYEXTEND    26
+#define V_KEYEXTEND(x) ((x) << S_KEYEXTEND)
+#define F_KEYEXTEND    V_KEYEXTEND(1U)
+
+#define S_T6_VFWRADDR    8
+#define V_T6_VFWRADDR(x) ((x) << S_T6_VFWRADDR)
+
 #define A_TP_PIO_ADDR 0x7e40
 #define A_TP_PIO_DATA 0x7e44
 
+#define A_TP_RSS_SECRET_KEY0 0x40
+
 #define A_TP_VLAN_PRI_MAP 0x140
 
 #define S_FRAGMENTATION    9
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 6ca4f3188..883a1c7f5 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -171,6 +171,7 @@ struct fw_eth_tx_pkts_wr {
 #define FW_CMD_HELLO_RETRIES	3
 
 enum fw_cmd_opcodes {
+	FW_LDST_CMD		       = 0x01,
 	FW_RESET_CMD                   = 0x03,
 	FW_HELLO_CMD                   = 0x04,
 	FW_BYE_CMD                     = 0x05,
@@ -238,6 +239,94 @@ struct fw_cmd_hdr {
 
 #define FW_LEN16(fw_struct) V_FW_CMD_LEN16(sizeof(fw_struct) / 16)
 
+/* address spaces
+ */
+enum fw_ldst_addrspc {
+	FW_LDST_ADDRSPC_TP_PIO    = 0x0010,
+};
+
+struct fw_ldst_cmd {
+	__be32 op_to_addrspace;
+	__be32 cycles_to_len16;
+	union fw_ldst {
+		struct fw_ldst_addrval {
+			__be32 addr;
+			__be32 val;
+		} addrval;
+		struct fw_ldst_idctxt {
+			__be32 physid;
+			__be32 msg_ctxtflush;
+			__be32 ctxt_data7;
+			__be32 ctxt_data6;
+			__be32 ctxt_data5;
+			__be32 ctxt_data4;
+			__be32 ctxt_data3;
+			__be32 ctxt_data2;
+			__be32 ctxt_data1;
+			__be32 ctxt_data0;
+		} idctxt;
+		struct fw_ldst_mdio {
+			__be16 paddr_mmd;
+			__be16 raddr;
+			__be16 vctl;
+			__be16 rval;
+		} mdio;
+		struct fw_ldst_mps {
+			__be16 fid_ctl;
+			__be16 rplcpf_pkd;
+			__be32 rplc127_96;
+			__be32 rplc95_64;
+			__be32 rplc63_32;
+			__be32 rplc31_0;
+			__be32 atrb;
+			__be16 vlan[16];
+		} mps;
+		struct fw_ldst_func {
+			__u8   access_ctl;
+			__u8   mod_index;
+			__be16 ctl_id;
+			__be32 offset;
+			__be64 data0;
+			__be64 data1;
+		} func;
+		struct fw_ldst_pcie {
+			__u8   ctrl_to_fn;
+			__u8   bnum;
+			__u8   r;
+			__u8   ext_r;
+			__u8   select_naccess;
+			__u8   pcie_fn;
+			__be16 nset_pkd;
+			__be32 data[12];
+		} pcie;
+		struct fw_ldst_i2c_deprecated {
+			__u8   pid_pkd;
+			__u8   base;
+			__u8   boffset;
+			__u8   data;
+			__be32 r9;
+		} i2c_deprecated;
+		struct fw_ldst_i2c {
+			__u8   pid;
+			__u8   did;
+			__u8   boffset;
+			__u8   blen;
+			__be32 r9;
+			__u8   data[48];
+		} i2c;
+		struct fw_ldst_le {
+			__be32 index;
+			__be32 r9;
+			__u8   val[33];
+			__u8   r11[7];
+		} le;
+	} u;
+};
+
+#define S_FW_LDST_CMD_ADDRSPACE         0
+#define M_FW_LDST_CMD_ADDRSPACE         0xff
+#define V_FW_LDST_CMD_ADDRSPACE(x)      ((x) << S_FW_LDST_CMD_ADDRSPACE)
+
 struct fw_reset_cmd {
 	__be32 op_to_write;
 	__be32 retval_len16;
diff --git a/drivers/net/cxgbe/cxgbe.h b/drivers/net/cxgbe/cxgbe.h
index f98915455..489e09dda 100644
--- a/drivers/net/cxgbe/cxgbe.h
+++ b/drivers/net/cxgbe/cxgbe.h
@@ -46,6 +46,8 @@
 #define CXGBE_MIN_RX_BUFSIZE ETHER_MIN_MTU /* min buf size */
 #define CXGBE_MAX_RX_PKTLEN (9000 + ETHER_HDR_LEN + ETHER_CRC_LEN) /* max pkt */
 
+#define CXGBE_DEFAULT_RSS_KEY_LEN     40 /* 320-bits */
+
 int cxgbe_probe(struct adapter *adapter);
 void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps);
 int cxgbe_up(struct adapter *adap);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 5a25125fe..7b902763b 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 				       DEV_TX_OFFLOAD_TCP_TSO;
 
 	device_info->reta_size = pi->rss_size;
+	device_info->hash_key_size = CXGBE_DEFAULT_RSS_KEY_LEN;
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
@@ -788,6 +789,36 @@ cxgbe_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev)
 	return NULL;
 }
 
+/* Update RSS hash configuration
+ */
+static int cxgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
+				     struct rte_eth_rss_conf *rss_conf)
+{
+	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
+	struct adapter *adapter = pi->adapter;
+	int err;
+
+	err = cxgbe_write_rss_conf(pi, rss_conf->rss_hf);
+	if (err)
+		return err;
+
+	pi->rss_hf = rss_conf->rss_hf;
+
+	if (rss_conf->rss_key) {
+		u32 key[10], mod_key[10];
+		int i, j;
+
+		memcpy(key, rss_conf->rss_key, CXGBE_DEFAULT_RSS_KEY_LEN);
+
+		for (i = 9, j = 0; i >= 0; i--, j++)
+			mod_key[j] = cpu_to_be32(key[i]);
+
+		t4_write_rss_key(adapter, mod_key, -1);
+	}
+
+	return 0;
+}
+
 static int cxgbe_get_eeprom_length(struct rte_eth_dev *dev)
 {
 	RTE_SET_USED(dev);
@@ -986,6 +1017,7 @@ static const struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.get_eeprom		= cxgbe_get_eeprom,
 	.set_eeprom		= cxgbe_set_eeprom,
 	.get_reg		= cxgbe_get_regs,
+	.rss_hash_update	= cxgbe_dev_rss_hash_update,
 };
 
 /*
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index c502fadf7..930c3dfdf 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -360,6 +360,8 @@ static int init_rss(struct adapter *adap)
 		pi->rss = rte_zmalloc(NULL, pi->rss_size * sizeof(u16), 0);
 		if (!pi->rss)
 			return -ENOMEM;
+
+		pi->rss_hf = ETH_RSS_TCP | ETH_RSS_UDP;
 	}
 	return 0;
 }
@@ -930,14 +932,67 @@ int link_start(struct port_info *pi)
 }
 
 /**
- * cxgb4_write_rss - write the RSS table for a given port
+ * cxgbe_write_rss_conf - flash the RSS configuration for a given port
+ * @pi: the port
+ * @rss_hf: Hash configuration to apply
+ */
+int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t rss_hf)
+{
+	struct adapter *adapter = pi->adapter;
+	const struct sge_eth_rxq *rxq;
+	u64 flags = 0;
+	u16 rss;
+	int err;
+
+	/*  Should never be called before setting up sge eth rx queues */
+	if (!(adapter->flags & FULL_INIT_DONE)) {
+		dev_err(adap, "%s No RXQs available on port %d\n",
+			__func__, pi->port_id);
+		return -EINVAL;
+	}
+
+	if (rss_hf & ETH_RSS_IPV4)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN |
+			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
+
+	if (rss_hf & ETH_RSS_IPV6)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
+			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
+
+	rxq = &adapter->sge.ethrxq[pi->first_qset];
+	rss = rxq[0].rspq.abs_id;
+
+	/* If Tunnel All Lookup isn't specified in the global RSS
+	 * Configuration, then we need to specify a default Ingress
+	 * Queue for any ingress packets which aren't hashed.  We'll
+	 * use our first ingress queue ...
+	 */
+	err = t4_config_vi_rss(adapter, adapter->mbox, pi->viid,
+			       flags, rss);
+	return err;
+}
+
+/**
+ * cxgbe_write_rss - write the RSS table for a given port
  * @pi: the port
  * @queues: array of queue indices for RSS
  *
  * Sets up the portion of the HW RSS table for the port's VI to distribute
  * packets to the Rx queues in @queues.
  */
-int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
+int cxgbe_write_rss(const struct port_info *pi, const u16 *queues)
 {
 	u16 *rss;
 	int i, err;
@@ -958,20 +1013,6 @@ int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
 
 	err = t4_config_rss_range(adapter, adapter->pf, pi->viid, 0,
 				  pi->rss_size, rss, pi->rss_size);
-	/*
-	 * If Tunnel All Lookup isn't specified in the global RSS
-	 * Configuration, then we need to specify a default Ingress
-	 * Queue for any ingress packets which aren't hashed.  We'll
-	 * use our first ingress queue ...
-	 */
-	if (!err)
-		err = t4_config_vi_rss(adapter, adapter->mbox, pi->viid,
-				       F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_UDPEN,
-				       rss[0]);
 	rte_free(rss);
 	return err;
 }
@@ -1001,7 +1042,11 @@ int setup_rss(struct port_info *pi)
 			for (j = 0; j < pi->rss_size; j++)
 				pi->rss[j] = j % pi->n_rx_qsets;
 
-			err = cxgb4_write_rss(pi, pi->rss);
+			err = cxgbe_write_rss(pi, pi->rss);
+			if (err)
+				return err;
+
+			err = cxgbe_write_rss_conf(pi, pi->rss_hf);
 			if (err)
 				return err;
 			pi->flags |= PORT_RSS_DONE;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 4/7] cxgbe: add support to get programmed RSS hash configuration and key
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                   ` (2 preceding siblings ...)
  2018-02-04  6:06 ` [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
@ 2018-02-04  6:06 ` Rahul Lakkireddy
  2018-02-04  6:06 ` [PATCH 5/7] cxgbe: update link Forward Error Correction (FEC) Rahul Lakkireddy
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/base/common.h  |  3 +++
 drivers/net/cxgbe/base/t4_hw.c   | 46 ++++++++++++++++++++++++++++++++++
 drivers/net/cxgbe/cxgbe_ethdev.c | 53 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 5301f7474..dd282a933 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -410,9 +410,12 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
 			int start, int n, const u16 *rspq, unsigned int nrspq);
 int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 		     unsigned int flags, unsigned int defq);
+int t4_read_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
+			  u64 *flags, unsigned int *defq);
 void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
 		     unsigned int start_index, unsigned int rw);
 void t4_write_rss_key(struct adapter *adap, u32 *key, int idx);
+void t4_read_rss_key(struct adapter *adap, u32 *key);
 
 enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS };
 int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid,
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 9eb83fd5e..2d7214622 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2203,6 +2203,18 @@ void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
 	}
 }
 
+/**
+ * t4_read_rss_key - read the global RSS key
+ * @adap: the adapter
+ * @key: 10-entry array holding the 320-bit RSS key
+ *
+ * Reads the global 320-bit RSS key.
+ */
+void t4_read_rss_key(struct adapter *adap, u32 *key)
+{
+	t4_fw_tp_pio_rw(adap, key, 10, A_TP_RSS_SECRET_KEY0, 1);
+}
+
 /**
  * t4_write_rss_key - program one of the RSS keys
  * @adap: the adapter
@@ -2363,6 +2375,40 @@ int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 	return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
 }
 
+/**
+ * t4_read_config_vi_rss - read the configured per VI RSS settings
+ * @adapter: the adapter
+ * @mbox: mbox to use for the FW command
+ * @viid: the VI id
+ * @flags: where to place the configured flags
+ * @defq: where to place the id of the default RSS queue for the VI.
+ *
+ * Read configured VI-specific RSS properties.
+ */
+int t4_read_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
+			  u64 *flags, unsigned int *defq)
+{
+	struct fw_rss_vi_config_cmd c;
+	unsigned int result;
+	int ret;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) |
+				   F_FW_CMD_REQUEST | F_FW_CMD_READ |
+				   V_FW_RSS_VI_CONFIG_CMD_VIID(viid));
+	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
+	ret = t4_wr_mbox(adapter, mbox, &c, sizeof(c), &c);
+	if (!ret) {
+		result = be32_to_cpu(c.u.basicvirtual.defaultq_to_udpen);
+		if (defq)
+			*defq = G_FW_RSS_VI_CONFIG_CMD_DEFAULTQ(result);
+		if (flags)
+			*flags = result & M_FW_RSS_VI_CONFIG_CMD_DEFAULTQ;
+	}
+
+	return ret;
+}
+
 /**
  * init_cong_ctrl - initialize congestion control parameters
  * @a: the alpha values for congestion control
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 7b902763b..1343041ef 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -819,6 +819,58 @@ static int cxgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* Get RSS hash configuration
+ */
+static int cxgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+				       struct rte_eth_rss_conf *rss_conf)
+{
+	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
+	struct adapter *adapter = pi->adapter;
+	u64 rss_hf = 0;
+	u64 flags = 0;
+	int err;
+
+	err = t4_read_config_vi_rss(adapter, adapter->mbox, pi->viid,
+				    &flags, NULL);
+
+	if (err)
+		return err;
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) {
+		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+		if (flags & F_FW_RSS_VI_CONFIG_CMD_UDPEN)
+			rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
+	}
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN)
+		rss_hf |= ETH_RSS_IPV6;
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) {
+		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+		if (flags & F_FW_RSS_VI_CONFIG_CMD_UDPEN)
+			rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
+	}
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN)
+		rss_hf |= ETH_RSS_IPV4;
+
+	rss_conf->rss_hf = rss_hf;
+
+	if (rss_conf->rss_key) {
+		u32 key[10], mod_key[10];
+		int i, j;
+
+		t4_read_rss_key(adapter, key);
+
+		for (i = 9, j = 0; i >= 0; i--, j++)
+			mod_key[j] = be32_to_cpu(key[i]);
+
+		memcpy(rss_conf->rss_key, mod_key, CXGBE_DEFAULT_RSS_KEY_LEN);
+	}
+
+	return 0;
+}
+
 static int cxgbe_get_eeprom_length(struct rte_eth_dev *dev)
 {
 	RTE_SET_USED(dev);
@@ -1018,6 +1070,7 @@ static const struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.set_eeprom		= cxgbe_set_eeprom,
 	.get_reg		= cxgbe_get_regs,
 	.rss_hash_update	= cxgbe_dev_rss_hash_update,
+	.rss_hash_conf_get	= cxgbe_dev_rss_hash_conf_get,
 };
 
 /*
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 5/7] cxgbe: update link Forward Error Correction (FEC)
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                   ` (3 preceding siblings ...)
  2018-02-04  6:06 ` [PATCH 4/7] cxgbe: add support to get programmed " Rahul Lakkireddy
@ 2018-02-04  6:06 ` Rahul Lakkireddy
  2018-02-04  6:06 ` [PATCH 6/7] cxgbe: update link configuration for 32-bit port capability Rahul Lakkireddy
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Normally, firmware reads various Forward Error Correction parameters
from a Transceiver Module i2c EPROM and uses a couple of IEEE Standards
(802.3bj for 100Gb/s and 802.3by for 25Gb/s) to interpret those
parameters and come up with supported and default FEC settings.
Firmware then sends these FEC parameters to the Host Driver which gives
the Host Administrator an opportunity to change them if necessary in
order to establish a Link with a Switch which may have made a
non-standard FEC decision.

This commit recognizes "auto" as a discrete FEC mode which can be
used to explicitly select the IEEE 802.3 standard based FEC selection.

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
 drivers/net/cxgbe/base/common.h |  13 +++--
 drivers/net/cxgbe/base/t4_hw.c  | 123 ++++++++++++++++++++++++++++------------
 2 files changed, 94 insertions(+), 42 deletions(-)

diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index dd282a933..0bd78c1b0 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -69,9 +69,9 @@ enum {
 };
 
 enum {
-	FEC_RS        = 1 << 0,
-	FEC_BASER_RS  = 1 << 1,
-	FEC_RESERVED  = 1 << 2,
+	FEC_AUTO     = 1 << 0,    /* IEEE 802.3 "automatic" */
+	FEC_RS       = 1 << 1,    /* Reed-Solomon */
+	FEC_BASER_RS = 1 << 2,    /* BaseR/Reed-Solomon */
 };
 
 struct port_stats {
@@ -248,8 +248,11 @@ struct link_config {
 	unsigned int   speed;            /* actual link speed */
 	unsigned char  requested_fc;     /* flow control user has requested */
 	unsigned char  fc;               /* actual link flow control */
-	unsigned char  requested_fec;    /* Forward Error Correction user */
-	unsigned char  fec;              /* has requested and actual FEC */
+	unsigned char  auto_fec;         /* Forward Error Correction (FEC)
+					  * "automatic" (IEEE 802.3)
+					  */
+	unsigned char  requested_fec;    /* FEC requested */
+	unsigned char  fec;              /* FEC actual */
 	unsigned char  autoneg;          /* autonegotiating? */
 	unsigned char  link_ok;          /* link up? */
 };
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 2d7214622..e8545ceb0 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2792,6 +2792,58 @@ void t4_dump_version_info(struct adapter *adapter)
 #define ADVERT_MASK (V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED) | \
 		     FW_PORT_CAP_ANEG)
 
+/* Translate Firmware Pause specification to Common Code */
+static inline unsigned int fwcap_to_cc_pause(unsigned int fw_pause)
+{
+	unsigned int cc_pause = 0;
+
+	if (fw_pause & F_FW_PORT_CMD_RXPAUSE)
+		cc_pause |= PAUSE_RX;
+	if (fw_pause & F_FW_PORT_CMD_TXPAUSE)
+		cc_pause |= PAUSE_TX;
+
+	return cc_pause;
+}
+
+/* Translate Common Code Pause Frame specification into Firmware */
+static inline unsigned int cc_to_fwcap_pause(unsigned int cc_pause)
+{
+	unsigned int fw_pause = 0;
+
+	if (cc_pause & PAUSE_RX)
+		fw_pause |= F_FW_PORT_CMD_RXPAUSE;
+	if (cc_pause & PAUSE_TX)
+		fw_pause |= F_FW_PORT_CMD_TXPAUSE;
+
+	return fw_pause;
+}
+
+/* Translate Firmware Forward Error Correction specification to Common Code */
+static inline unsigned int fwcap_to_cc_fec(unsigned int fw_fec)
+{
+	unsigned int cc_fec = 0;
+
+	if (fw_fec & FW_PORT_CAP_FEC_RS)
+		cc_fec |= FEC_RS;
+	if (fw_fec & FW_PORT_CAP_FEC_BASER_RS)
+		cc_fec |= FEC_BASER_RS;
+
+	return cc_fec;
+}
+
+/* Translate Common Code Forward Error Correction specification to Firmware */
+static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
+{
+	unsigned int fw_fec = 0;
+
+	if (cc_fec & FEC_RS)
+		fw_fec |= FW_PORT_CAP_FEC_RS;
+	if (cc_fec & FEC_BASER_RS)
+		fw_fec |= FW_PORT_CAP_FEC_BASER_RS;
+
+	return fw_fec;
+}
+
 /**
  * t4_link_l1cfg - apply link configuration to MAC/PHY
  * @phy: the PHY to setup
@@ -2809,23 +2861,25 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc)
 {
 	struct fw_port_cmd c;
-	unsigned int mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO);
-	unsigned int fc, fec;
+	unsigned int fw_mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO);
+	unsigned int fw_fc, cc_fec, fw_fec;
 
 	lc->link_ok = 0;
-	fc = 0;
-	if (lc->requested_fc & PAUSE_RX)
-		fc |= FW_PORT_CAP_FC_RX;
-	if (lc->requested_fc & PAUSE_TX)
-		fc |= FW_PORT_CAP_FC_TX;
-
-	fec = 0;
-	if (lc->requested_fec & FEC_RS)
-		fec |= FW_PORT_CAP_FEC_RS;
-	if (lc->requested_fec & FEC_BASER_RS)
-		fec |= FW_PORT_CAP_FEC_BASER_RS;
-	if (lc->requested_fec & FEC_RESERVED)
-		fec |= FW_PORT_CAP_FEC_RESERVED;
+
+	fw_fc = cc_to_fwcap_pause(lc->requested_fc);
+
+	/* Convert Common Code Forward Error Control settings into the
+	 * Firmware's API.  If the current Requested FEC has "Automatic"
+	 * (IEEE 802.3) specified, then we use whatever the Firmware
+	 * sent us as part of it's IEEE 802.3-based interpratation of
+	 * the Transceiver Module EPROM FEC parameters.  Otherwise we
+	 * use whatever is in the current Requested FEC settings.
+	 */
+	if (lc->requested_fec & FEC_AUTO)
+		cc_fec = lc->auto_fec;
+	else
+		cc_fec = lc->requested_fec;
+	fw_fec = cc_to_fwcap_fec(cc_fec);
 
 	memset(&c, 0, sizeof(c));
 	c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
@@ -2837,16 +2891,17 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 
 	if (!(lc->supported & FW_PORT_CAP_ANEG)) {
 		c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) |
-					     fc | fec);
+					     fw_fc | fw_fec);
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
-		lc->fec = lc->requested_fec;
+		lc->fec = cc_fec;
 	} else if (lc->autoneg == AUTONEG_DISABLE) {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fc |
-					     fec | mdi);
+		c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fw_fc |
+					     fw_fec | fw_mdi);
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
-		lc->fec = lc->requested_fec;
+		lc->fec = cc_fec;
 	} else {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fc | fec | mdi);
+		c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fw_fc | fw_fec |
+					     fw_mdi);
 	}
 
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
@@ -4212,11 +4267,11 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
 		int link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0;
 		u32 mod = G_FW_PORT_CMD_MODTYPE(stat);
+		unsigned int fec;
+
+		fc = fwcap_to_cc_pause(stat);
+		fec = fwcap_to_cc_fec(stat);
 
-		if (stat & F_FW_PORT_CMD_RXPAUSE)
-			fc |= PAUSE_RX;
-		if (stat & F_FW_PORT_CMD_TXPAUSE)
-			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
 			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
@@ -4238,11 +4293,12 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		lc = &pi->link_cfg;
 
 		if (mod != pi->mod_type) {
+			lc->auto_fec = fec;
 			pi->mod_type = mod;
 			t4_os_portmod_changed(adap, i);
 		}
 		if (link_ok != lc->link_ok || speed != lc->speed ||
-		    fc != lc->fc) {                    /* something changed */
+		    fc != lc->fc || fec != lc->fec) { /* something changed */
 			if (!link_ok && lc->link_ok) {
 				static const char * const reason[] = {
 					"Link Down",
@@ -4262,6 +4318,7 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 			lc->link_ok = link_ok;
 			lc->speed = speed;
 			lc->fc = fc;
+			lc->fec = fec;
 			lc->supported = be16_to_cpu(p->u.info.pcap);
 		}
 	} else {
@@ -4295,8 +4352,6 @@ void t4_reset_link_config(struct adapter *adap, int idx)
 static void init_link_config(struct link_config *lc, unsigned int pcaps,
 			     unsigned int acaps)
 {
-	unsigned int fec;
-
 	lc->supported = pcaps;
 	lc->requested_speed = 0;
 	lc->speed = 0;
@@ -4307,15 +4362,9 @@ static void init_link_config(struct link_config *lc, unsigned int pcaps,
 	 * For Forward Error Control, we default to whatever the Firmware
 	 * tells us the Link is currently advertising.
 	 */
-	fec = 0;
-	if (acaps & FW_PORT_CAP_FEC_RS)
-		fec |= FEC_RS;
-	if (acaps & FW_PORT_CAP_FEC_BASER_RS)
-		fec |= FEC_BASER_RS;
-	if (acaps & FW_PORT_CAP_FEC_RESERVED)
-		fec |= FEC_RESERVED;
-	lc->requested_fec = fec;
-	lc->fec = fec;
+	lc->auto_fec = fwcap_to_cc_fec(acaps);
+	lc->requested_fec = FEC_AUTO;
+	lc->fec = lc->auto_fec;
 
 	if (lc->supported & FW_PORT_CAP_ANEG) {
 		lc->advertising = lc->supported & ADVERT_MASK;
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 6/7] cxgbe: update link configuration for 32-bit port capability
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                   ` (4 preceding siblings ...)
  2018-02-04  6:06 ` [PATCH 5/7] cxgbe: update link Forward Error Correction (FEC) Rahul Lakkireddy
@ 2018-02-04  6:06 ` Rahul Lakkireddy
  2018-02-04  6:06 ` [PATCH 7/7] cxgbe: rework and use " Rahul Lakkireddy
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

Update link configuration API to prepare for 32-bit port capability
support. Continue using 16-bit port capability for older firmware.

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
---
 drivers/net/cxgbe/base/common.h         |  40 +++++---
 drivers/net/cxgbe/base/t4_hw.c          | 168 +++++++++++++++++++++++---------
 drivers/net/cxgbe/base/t4fw_interface.h |  36 ++++++-
 drivers/net/cxgbe/cxgbe_ethdev.c        |   2 +-
 drivers/net/cxgbe/cxgbe_main.c          |  28 +++---
 5 files changed, 200 insertions(+), 74 deletions(-)

diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 0bd78c1b0..98886288c 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -62,13 +62,13 @@ enum dev_master { MASTER_CANT, MASTER_MAY, MASTER_MUST };
 
 enum dev_state { DEV_STATE_UNINIT, DEV_STATE_INIT, DEV_STATE_ERR };
 
-enum {
+enum cc_pause {
 	PAUSE_RX      = 1 << 0,
 	PAUSE_TX      = 1 << 1,
 	PAUSE_AUTONEG = 1 << 2
 };
 
-enum {
+enum cc_fec {
 	FEC_AUTO     = 1 << 0,    /* IEEE 802.3 "automatic" */
 	FEC_RS       = 1 << 1,    /* Reed-Solomon */
 	FEC_BASER_RS = 1 << 2,    /* BaseR/Reed-Solomon */
@@ -241,20 +241,30 @@ struct adapter_params {
 	bool ulptx_memwrite_dsgl;          /* use of T5 DSGL allowed */
 };
 
+/* Firmware Port Capabilities types.
+ */
+typedef u16 fw_port_cap16_t;    /* 16-bit Port Capabilities integral value */
+typedef u32 fw_port_cap32_t;    /* 32-bit Port Capabilities integral value */
+
 struct link_config {
-	unsigned short supported;        /* link capabilities */
-	unsigned short advertising;      /* advertised capabilities */
-	unsigned int   requested_speed;  /* speed user has requested */
-	unsigned int   speed;            /* actual link speed */
-	unsigned char  requested_fc;     /* flow control user has requested */
-	unsigned char  fc;               /* actual link flow control */
-	unsigned char  auto_fec;         /* Forward Error Correction (FEC)
-					  * "automatic" (IEEE 802.3)
-					  */
-	unsigned char  requested_fec;    /* FEC requested */
-	unsigned char  fec;              /* FEC actual */
-	unsigned char  autoneg;          /* autonegotiating? */
-	unsigned char  link_ok;          /* link up? */
+	fw_port_cap32_t pcaps;          /* link capabilities */
+	fw_port_cap32_t acaps;          /* advertised capabilities */
+
+	u32 requested_speed;            /* speed (Mb/s) user has requested */
+	u32 speed;                      /* actual link speed (Mb/s) */
+
+	enum cc_pause requested_fc;     /* flow control user has requested */
+	enum cc_pause fc;               /* actual link flow control */
+
+	enum cc_fec auto_fec;           /* Forward Error Correction
+					 * "automatic" (IEEE 802.3)
+					 */
+	enum cc_fec requested_fec;      /* Forward Error Correction requested */
+	enum cc_fec fec;                /* Forward Error Correction actual */
+
+	unsigned char autoneg;          /* autonegotiating? */
+
+	unsigned char link_ok;          /* link up? */
 };
 
 #include "adapter.h"
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index e8545ceb0..46b296a9d 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2789,66 +2789,105 @@ void t4_dump_version_info(struct adapter *adapter)
 			 G_FW_HDR_FW_VER_BUILD(adapter->params.er_vers));
 }
 
-#define ADVERT_MASK (V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED) | \
-		     FW_PORT_CAP_ANEG)
+#define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \
+		     FW_PORT_CAP32_ANEG)
+/**
+ *     fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
+ *     @caps32: a 32-bit Port Capabilities value
+ *
+ *     Returns the equivalent 16-bit Port Capabilities value.  Note that
+ *     not all 32-bit Port Capabilities can be represented in the 16-bit
+ *     Port Capabilities and some fields/values may not make it.
+ */
+static fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32)
+{
+	fw_port_cap16_t caps16 = 0;
+
+#define CAP32_TO_CAP16(__cap) \
+	do { \
+		if (caps32 & FW_PORT_CAP32_##__cap) \
+			caps16 |= FW_PORT_CAP_##__cap; \
+	} while (0)
+
+	CAP32_TO_CAP16(SPEED_100M);
+	CAP32_TO_CAP16(SPEED_1G);
+	CAP32_TO_CAP16(SPEED_10G);
+	CAP32_TO_CAP16(SPEED_25G);
+	CAP32_TO_CAP16(SPEED_40G);
+	CAP32_TO_CAP16(SPEED_100G);
+	CAP32_TO_CAP16(FC_RX);
+	CAP32_TO_CAP16(FC_TX);
+	CAP32_TO_CAP16(802_3_PAUSE);
+	CAP32_TO_CAP16(802_3_ASM_DIR);
+	CAP32_TO_CAP16(ANEG);
+	CAP32_TO_CAP16(MDIX);
+	CAP32_TO_CAP16(MDIAUTO);
+	CAP32_TO_CAP16(FEC_RS);
+	CAP32_TO_CAP16(FEC_BASER_RS);
+
+#undef CAP32_TO_CAP16
+
+	return caps16;
+}
 
 /* Translate Firmware Pause specification to Common Code */
-static inline unsigned int fwcap_to_cc_pause(unsigned int fw_pause)
+static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
 {
-	unsigned int cc_pause = 0;
+	enum cc_pause cc_pause = 0;
 
-	if (fw_pause & F_FW_PORT_CMD_RXPAUSE)
+	if (fw_pause & FW_PORT_CAP32_FC_RX)
 		cc_pause |= PAUSE_RX;
-	if (fw_pause & F_FW_PORT_CMD_TXPAUSE)
+	if (fw_pause & FW_PORT_CAP32_FC_TX)
 		cc_pause |= PAUSE_TX;
 
 	return cc_pause;
 }
 
 /* Translate Common Code Pause Frame specification into Firmware */
-static inline unsigned int cc_to_fwcap_pause(unsigned int cc_pause)
+static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
 {
-	unsigned int fw_pause = 0;
+	fw_port_cap32_t fw_pause = 0;
 
 	if (cc_pause & PAUSE_RX)
-		fw_pause |= F_FW_PORT_CMD_RXPAUSE;
+		fw_pause |= FW_PORT_CAP32_FC_RX;
 	if (cc_pause & PAUSE_TX)
-		fw_pause |= F_FW_PORT_CMD_TXPAUSE;
+		fw_pause |= FW_PORT_CAP32_FC_TX;
 
 	return fw_pause;
 }
 
 /* Translate Firmware Forward Error Correction specification to Common Code */
-static inline unsigned int fwcap_to_cc_fec(unsigned int fw_fec)
+static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
 {
-	unsigned int cc_fec = 0;
+	enum cc_fec cc_fec = 0;
 
-	if (fw_fec & FW_PORT_CAP_FEC_RS)
+	if (fw_fec & FW_PORT_CAP32_FEC_RS)
 		cc_fec |= FEC_RS;
-	if (fw_fec & FW_PORT_CAP_FEC_BASER_RS)
+	if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
 		cc_fec |= FEC_BASER_RS;
 
 	return cc_fec;
 }
 
 /* Translate Common Code Forward Error Correction specification to Firmware */
-static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
+static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
 {
-	unsigned int fw_fec = 0;
+	fw_port_cap32_t fw_fec = 0;
 
 	if (cc_fec & FEC_RS)
-		fw_fec |= FW_PORT_CAP_FEC_RS;
+		fw_fec |= FW_PORT_CAP32_FEC_RS;
 	if (cc_fec & FEC_BASER_RS)
-		fw_fec |= FW_PORT_CAP_FEC_BASER_RS;
+		fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
 
 	return fw_fec;
 }
 
 /**
  * t4_link_l1cfg - apply link configuration to MAC/PHY
- * @phy: the PHY to setup
- * @mac: the MAC to setup
- * @lc: the requested link configuration
+ * @adapter: the adapter
+ * @mbox: the Firmware Mailbox to use
+ * @port: the Port ID
+ * @lc: the Port's Link Configuration
  *
  * Set up a port's MAC and PHY according to a desired link configuration.
  * - If the PHY can auto-negotiate first decide what to advertise, then
@@ -2860,9 +2899,9 @@ static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
 int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc)
 {
-	struct fw_port_cmd c;
-	unsigned int fw_mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO);
-	unsigned int fw_fc, cc_fec, fw_fec;
+	unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
+	fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
+	struct fw_port_cmd cmd;
 
 	lc->link_ok = 0;
 
@@ -2881,30 +2920,32 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		cc_fec = lc->requested_fec;
 	fw_fec = cc_to_fwcap_fec(cc_fec);
 
-	memset(&c, 0, sizeof(c));
-	c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
-				     F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
-				     V_FW_PORT_CMD_PORTID(port));
-	c.action_to_len16 =
-		cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
-			    FW_LEN16(c));
-
-	if (!(lc->supported & FW_PORT_CAP_ANEG)) {
-		c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) |
-					     fw_fc | fw_fec);
+	/* Figure out what our Requested Port Capabilities are going to be.
+	 */
+	if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
+		rcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec;
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
 		lc->fec = cc_fec;
 	} else if (lc->autoneg == AUTONEG_DISABLE) {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fw_fc |
-					     fw_fec | fw_mdi);
+		rcap = lc->requested_speed | fw_fc | fw_fec | fw_mdi;
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
 		lc->fec = cc_fec;
 	} else {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fw_fc | fw_fec |
-					     fw_mdi);
+		rcap = lc->acaps | fw_fc | fw_fec | fw_mdi;
 	}
 
-	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+	/* And send that on to the Firmware ...
+	 */
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
+				       F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
+				       V_FW_PORT_CMD_PORTID(port));
+	cmd.action_to_len16 =
+		cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+			    FW_LEN16(cmd));
+	cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
+
+	return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL);
 }
 
 /**
@@ -4237,6 +4278,28 @@ int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
 }
 
+/* Return the highest speed set in the port capabilities, in Mb/s. */
+static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
+{
+#define TEST_SPEED_RETURN(__caps_speed, __speed) \
+	do { \
+		if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \
+			return __speed; \
+	} while (0)
+
+	TEST_SPEED_RETURN(100G, 100000);
+	TEST_SPEED_RETURN(50G,   50000);
+	TEST_SPEED_RETURN(40G,   40000);
+	TEST_SPEED_RETURN(25G,   25000);
+	TEST_SPEED_RETURN(10G,   10000);
+	TEST_SPEED_RETURN(1G,     1000);
+	TEST_SPEED_RETURN(100M,    100);
+
+#undef TEST_SPEED_RETURN
+
+	return 0;
+}
+
 /**
  * t4_handle_fw_rpl - process a FW reply message
  * @adap: the adapter
@@ -4319,7 +4382,21 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 			lc->speed = speed;
 			lc->fc = fc;
 			lc->fec = fec;
-			lc->supported = be16_to_cpu(p->u.info.pcap);
+			lc->pcaps = be16_to_cpu(p->u.info.pcap);
+			lc->acaps = be16_to_cpu(p->u.info.acap) & ADVERT_MASK;
+			if (lc->acaps & FW_PORT_CAP32_ANEG) {
+				lc->autoneg = AUTONEG_ENABLE;
+			} else {
+				/* When Autoneg is disabled, user needs to set
+				 * single speed.
+				 */
+				lc->acaps = 0;
+				lc->requested_speed =
+					be16_to_cpu(p->u.info.acap);
+				lc->requested_speed =
+					fwcap_to_speed(lc->requested_speed);
+				lc->autoneg = AUTONEG_DISABLE;
+			}
 		}
 	} else {
 		dev_warn(adap, "Unknown firmware reply %d\n", opcode);
@@ -4352,7 +4429,7 @@ void t4_reset_link_config(struct adapter *adap, int idx)
 static void init_link_config(struct link_config *lc, unsigned int pcaps,
 			     unsigned int acaps)
 {
-	lc->supported = pcaps;
+	lc->pcaps = pcaps;
 	lc->requested_speed = 0;
 	lc->speed = 0;
 	lc->requested_fc = 0;
@@ -4366,11 +4443,12 @@ static void init_link_config(struct link_config *lc, unsigned int pcaps,
 	lc->requested_fec = FEC_AUTO;
 	lc->fec = lc->auto_fec;
 
-	if (lc->supported & FW_PORT_CAP_ANEG) {
-		lc->advertising = lc->supported & ADVERT_MASK;
+	if (lc->pcaps & FW_PORT_CAP32_ANEG) {
+		lc->acaps = lc->pcaps & ADVERT_MASK;
 		lc->autoneg = AUTONEG_ENABLE;
+		lc->requested_fc |= PAUSE_AUTONEG;
 	} else {
-		lc->advertising = 0;
+		lc->acaps = 0;
 		lc->autoneg = AUTONEG_DISABLE;
 	}
 }
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 883a1c7f5..0e139377f 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -1154,7 +1154,7 @@ struct fw_vi_stats_cmd {
 	} u;
 };
 
-/* port capabilities bitmap */
+/* old 16-bit port capabilities bitmap */
 enum fw_port_cap {
 	FW_PORT_CAP_SPEED_100M		= 0x0001,
 	FW_PORT_CAP_SPEED_1G		= 0x0002,
@@ -1189,6 +1189,40 @@ enum fw_port_mdi {
 #define V_FW_PORT_CAP_MDI(x) ((x) << S_FW_PORT_CAP_MDI)
 #define G_FW_PORT_CAP_MDI(x) (((x) >> S_FW_PORT_CAP_MDI) & M_FW_PORT_CAP_MDI)
 
+/* new 32-bit port capabilities bitmap (fw_port_cap32_t) */
+#define FW_PORT_CAP32_SPEED_100M        0x00000001UL
+#define FW_PORT_CAP32_SPEED_1G          0x00000002UL
+#define FW_PORT_CAP32_SPEED_10G         0x00000004UL
+#define FW_PORT_CAP32_SPEED_25G         0x00000008UL
+#define FW_PORT_CAP32_SPEED_40G         0x00000010UL
+#define FW_PORT_CAP32_SPEED_50G         0x00000020UL
+#define FW_PORT_CAP32_SPEED_100G        0x00000040UL
+#define FW_PORT_CAP32_FC_RX             0x00010000UL
+#define FW_PORT_CAP32_FC_TX             0x00020000UL
+#define FW_PORT_CAP32_802_3_PAUSE       0x00040000UL
+#define FW_PORT_CAP32_802_3_ASM_DIR     0x00080000UL
+#define FW_PORT_CAP32_ANEG              0x00100000UL
+#define FW_PORT_CAP32_MDIX              0x00200000UL
+#define FW_PORT_CAP32_MDIAUTO           0x00400000UL
+#define FW_PORT_CAP32_FEC_RS            0x00800000UL
+#define FW_PORT_CAP32_FEC_BASER_RS      0x01000000UL
+
+#define S_FW_PORT_CAP32_SPEED           0
+#define M_FW_PORT_CAP32_SPEED           0xfff
+#define V_FW_PORT_CAP32_SPEED(x)        ((x) << S_FW_PORT_CAP32_SPEED)
+#define G_FW_PORT_CAP32_SPEED(x) \
+	(((x) >> S_FW_PORT_CAP32_SPEED) & M_FW_PORT_CAP32_SPEED)
+
+enum fw_port_mdi32 {
+	FW_PORT_CAP32_MDI_AUTO,
+};
+
+#define S_FW_PORT_CAP32_MDI 21
+#define M_FW_PORT_CAP32_MDI 3
+#define V_FW_PORT_CAP32_MDI(x) ((x) << S_FW_PORT_CAP32_MDI)
+#define G_FW_PORT_CAP32_MDI(x) \
+	(((x) >> S_FW_PORT_CAP32_MDI) & M_FW_PORT_CAP32_MDI)
+
 enum fw_port_action {
 	FW_PORT_ACTION_L1_CFG		= 0x0001,
 	FW_PORT_ACTION_GET_PORT_INFO	= 0x0003,
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 1343041ef..b0d82fc93 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -752,7 +752,7 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 	struct adapter *adapter = pi->adapter;
 	struct link_config *lc = &pi->link_cfg;
 
-	if (lc->supported & FW_PORT_CAP_ANEG) {
+	if (lc->pcaps & FW_PORT_CAP32_ANEG) {
 		if (fc_conf->autoneg)
 			lc->requested_fc |= PAUSE_AUTONEG;
 		else
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 930c3dfdf..eb8213921 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -199,15 +199,16 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us,
 
 static inline bool is_x_1g_port(const struct link_config *lc)
 {
-	return (lc->supported & FW_PORT_CAP_SPEED_1G) != 0;
+	return (lc->pcaps & FW_PORT_CAP32_SPEED_1G) != 0;
 }
 
 static inline bool is_x_10g_port(const struct link_config *lc)
 {
 	unsigned int speeds, high_speeds;
 
-	speeds = V_FW_PORT_CAP_SPEED(G_FW_PORT_CAP_SPEED(lc->supported));
-	high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G);
+	speeds = V_FW_PORT_CAP32_SPEED(G_FW_PORT_CAP32_SPEED(lc->pcaps));
+	high_speeds = speeds &
+		      ~(FW_PORT_CAP32_SPEED_100M | FW_PORT_CAP32_SPEED_1G);
 
 	return high_speeds != 0;
 }
@@ -387,17 +388,19 @@ static void print_port_info(struct adapter *adap)
 		const struct port_info *pi = &adap->port[i];
 		char *bufp = buf;
 
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100M)
 			bufp += sprintf(bufp, "100M/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_1G)
 			bufp += sprintf(bufp, "1G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_10G)
 			bufp += sprintf(bufp, "10G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_25G)
 			bufp += sprintf(bufp, "25G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_40G)
 			bufp += sprintf(bufp, "40G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_50G)
+			bufp += sprintf(bufp, "50G/");
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100G)
 			bufp += sprintf(bufp, "100G/");
 		if (bufp != buf)
 			--bufp;
@@ -1096,7 +1099,7 @@ static void fw_caps_to_speed_caps(enum fw_port_type port_type,
 
 #define FW_CAPS_TO_SPEED(__fw_name) \
 	do { \
-		if (fw_caps & FW_PORT_CAP_ ## __fw_name) \
+		if (fw_caps & FW_PORT_CAP32_ ## __fw_name) \
 			SET_SPEED(__fw_name); \
 	} while (0)
 
@@ -1151,6 +1154,7 @@ static void fw_caps_to_speed_caps(enum fw_port_type port_type,
 	case FW_PORT_TYPE_CR4_QSFP:
 		FW_CAPS_TO_SPEED(SPEED_25G);
 		FW_CAPS_TO_SPEED(SPEED_40G);
+		FW_CAPS_TO_SPEED(SPEED_50G);
 		FW_CAPS_TO_SPEED(SPEED_100G);
 		break;
 
@@ -1173,10 +1177,10 @@ void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps)
 {
 	*speed_caps = 0;
 
-	fw_caps_to_speed_caps(pi->port_type, pi->link_cfg.supported,
+	fw_caps_to_speed_caps(pi->port_type, pi->link_cfg.pcaps,
 			      speed_caps);
 
-	if (!(pi->link_cfg.supported & FW_PORT_CAP_ANEG))
+	if (!(pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG))
 		*speed_caps |= ETH_LINK_SPEED_FIXED;
 }
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 7/7] cxgbe: rework and use 32-bit port capability
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                   ` (5 preceding siblings ...)
  2018-02-04  6:06 ` [PATCH 6/7] cxgbe: update link configuration for 32-bit port capability Rahul Lakkireddy
@ 2018-02-04  6:06 ` Rahul Lakkireddy
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-04  6:06 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

The new code uses the new 32-bit Port Capabilities exclusively and
only translates to/from the old 16-bit Port Capabilities at the last
point possible when talking to older Firmware.

For the old versus new Firmware issue, we use the new FW_PARAMS_CMD[PFVF,
CAPS32] command to tell the Firmware that we want Asynchronous Port Status
updates to use the new 32-bit version of the Port Information message.  If
we get an error, we know we're dealing with older Firmware, and if not,
we'll start getting th new 32-bit Port Capability message formats.

Also, refactor t4_handle_fw_rpl() to handle new 32-bit Port Capability
replies from firmware in t4_handle_get_port_info().

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
---
 doc/guides/nics/cxgbe.rst               |  10 +-
 drivers/net/cxgbe/base/common.h         |   8 +
 drivers/net/cxgbe/base/t4_hw.c          | 356 +++++++++++++++++++++++---------
 drivers/net/cxgbe/base/t4fw_interface.h |  47 ++++-
 4 files changed, 323 insertions(+), 98 deletions(-)

diff --git a/doc/guides/nics/cxgbe.rst b/doc/guides/nics/cxgbe.rst
index 6126167c5..c4afe8678 100644
--- a/doc/guides/nics/cxgbe.rst
+++ b/doc/guides/nics/cxgbe.rst
@@ -82,7 +82,7 @@ Supported Chelsio T6 NICs
 Prerequisites
 -------------
 
-- Requires firmware version **1.16.43.0** and higher. Visit
+- Requires firmware version **1.17.14.0** and higher. Visit
   `Chelsio Download Center <http://service.chelsio.com>`_ to get latest firmware
   bundled with the latest Chelsio Unified Wire package.
 
@@ -210,7 +210,7 @@ Unified Wire package for Linux operating system are as follows:
 
    .. code-block:: console
 
-      firmware-version: 1.16.43.0, TP 0.1.4.9
+      firmware-version: 1.17.14.0, TP 0.1.4.9
 
 Running testpmd
 ~~~~~~~~~~~~~~~
@@ -268,7 +268,7 @@ devices managed by librte_pmd_cxgbe in Linux operating system.
       EAL:   PCI memory mapped at 0x7fd7c0200000
       EAL:   PCI memory mapped at 0x7fd77cdfd000
       EAL:   PCI memory mapped at 0x7fd7c10b7000
-      PMD: rte_cxgbe_pmd: fw: 1.16.43.0, TP: 0.1.4.9
+      PMD: rte_cxgbe_pmd: fw: 1.17.14.0, TP: 0.1.4.9
       PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
       Interactive-mode selected
       Configuring Port 0 (socket 0)
@@ -352,7 +352,7 @@ Unified Wire package for FreeBSD operating system are as follows:
 
    .. code-block:: console
 
-      dev.t5nex.0.firmware_version: 1.16.43.0
+      dev.t5nex.0.firmware_version: 1.17.14.0
 
 Running testpmd
 ~~~~~~~~~~~~~~~
@@ -470,7 +470,7 @@ devices managed by librte_pmd_cxgbe in FreeBSD operating system.
       EAL:   PCI memory mapped at 0x8007ec000
       EAL:   PCI memory mapped at 0x842800000
       EAL:   PCI memory mapped at 0x80086c000
-      PMD: rte_cxgbe_pmd: fw: 1.16.43.0, TP: 0.1.4.9
+      PMD: rte_cxgbe_pmd: fw: 1.17.14.0, TP: 0.1.4.9
       PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
       Interactive-mode selected
       Configuring Port 0 (socket 0)
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 98886288c..365e9e692 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -239,6 +239,7 @@ struct adapter_params {
 	struct arch_specific_params arch; /* chip specific params */
 
 	bool ulptx_memwrite_dsgl;          /* use of T5 DSGL allowed */
+	u8 fw_caps_support;		  /* 32-bit Port Capabilities */
 };
 
 /* Firmware Port Capabilities types.
@@ -246,6 +247,12 @@ struct adapter_params {
 typedef u16 fw_port_cap16_t;    /* 16-bit Port Capabilities integral value */
 typedef u32 fw_port_cap32_t;    /* 32-bit Port Capabilities integral value */
 
+enum fw_caps {
+	FW_CAPS_UNKNOWN = 0,    /* 0'ed out initial state */
+	FW_CAPS16       = 1,    /* old Firmware: 16-bit Port Capabilities */
+	FW_CAPS32       = 2,    /* new Firmware: 32-bit Port Capabilities */
+};
+
 struct link_config {
 	fw_port_cap32_t pcaps;          /* link capabilities */
 	fw_port_cap32_t acaps;          /* advertised capabilities */
@@ -265,6 +272,7 @@ struct link_config {
 	unsigned char autoneg;          /* autonegotiating? */
 
 	unsigned char link_ok;          /* link up? */
+	unsigned char link_down_rc;     /* link down reason */
 };
 
 #include "adapter.h"
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 46b296a9d..c66e2a6f7 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2791,6 +2791,43 @@ void t4_dump_version_info(struct adapter *adapter)
 
 #define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \
 		     FW_PORT_CAP32_ANEG)
+/**
+ *     fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
+ *     @caps16: a 16-bit Port Capabilities value
+ *
+ *     Returns the equivalent 32-bit Port Capabilities value.
+ */
+static fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
+{
+	fw_port_cap32_t caps32 = 0;
+
+#define CAP16_TO_CAP32(__cap) \
+	do { \
+		if (caps16 & FW_PORT_CAP_##__cap) \
+			caps32 |= FW_PORT_CAP32_##__cap; \
+	} while (0)
+
+	CAP16_TO_CAP32(SPEED_100M);
+	CAP16_TO_CAP32(SPEED_1G);
+	CAP16_TO_CAP32(SPEED_25G);
+	CAP16_TO_CAP32(SPEED_10G);
+	CAP16_TO_CAP32(SPEED_40G);
+	CAP16_TO_CAP32(SPEED_100G);
+	CAP16_TO_CAP32(FC_RX);
+	CAP16_TO_CAP32(FC_TX);
+	CAP16_TO_CAP32(ANEG);
+	CAP16_TO_CAP32(MDIX);
+	CAP16_TO_CAP32(MDIAUTO);
+	CAP16_TO_CAP32(FEC_RS);
+	CAP16_TO_CAP32(FEC_BASER_RS);
+	CAP16_TO_CAP32(802_3_PAUSE);
+	CAP16_TO_CAP32(802_3_ASM_DIR);
+
+#undef CAP16_TO_CAP32
+
+	return caps32;
+}
+
 /**
  *     fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
  *     @caps32: a 32-bit Port Capabilities value
@@ -2900,6 +2937,7 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc)
 {
 	unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
+	unsigned int fw_caps = adap->params.fw_caps_support;
 	fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
 	struct fw_port_cmd cmd;
 
@@ -2941,9 +2979,15 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 				       F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
 				       V_FW_PORT_CMD_PORTID(port));
 	cmd.action_to_len16 =
-		cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+		cpu_to_be32(V_FW_PORT_CMD_ACTION(fw_caps == FW_CAPS16 ?
+						 FW_PORT_ACTION_L1_CFG :
+						 FW_PORT_ACTION_L1_CFG32) |
 			    FW_LEN16(cmd));
-	cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
+
+	if (fw_caps == FW_CAPS16)
+		cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
+	else
+		cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
 
 	return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL);
 }
@@ -4278,6 +4322,31 @@ int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
 }
 
+/**
+ * t4_link_down_rc_str - return a string for a Link Down Reason Code
+ * @link_down_rc: Link Down Reason Code
+ *
+ * Returns a string representation of the Link Down Reason Code.
+ */
+static const char *t4_link_down_rc_str(unsigned char link_down_rc)
+{
+	static const char * const reason[] = {
+		"Link Down",
+		"Remote Fault",
+		"Auto-negotiation Failure",
+		"Reserved",
+		"Insufficient Airflow",
+		"Unable To Determine Reason",
+		"No RX Signal Detected",
+		"Reserved",
+	};
+
+	if (link_down_rc >= ARRAY_SIZE(reason))
+		return "Bad Reason Code";
+
+	return reason[link_down_rc];
+}
+
 /* Return the highest speed set in the port capabilities, in Mb/s. */
 static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
 {
@@ -4300,6 +4369,122 @@ static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
 	return 0;
 }
 
+/**
+ * t4_handle_get_port_info - process a FW reply message
+ * @pi: the port info
+ * @rpl: start of the FW message
+ *
+ * Processes a GET_PORT_INFO FW reply message.
+ */
+static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
+{
+	const struct fw_port_cmd *cmd = (const void *)rpl;
+	int action = G_FW_PORT_CMD_ACTION(be32_to_cpu(cmd->action_to_len16));
+	fw_port_cap32_t pcaps, acaps, linkattr;
+	struct link_config *lc = &pi->link_cfg;
+	struct adapter *adapter = pi->adapter;
+	enum fw_port_module_type mod_type;
+	enum fw_port_type port_type;
+	unsigned int speed, fc, fec;
+	int link_ok, linkdnrc;
+
+	/* Extract the various fields from the Port Information message.
+	 */
+	switch (action) {
+	case FW_PORT_ACTION_GET_PORT_INFO: {
+		u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype);
+
+		link_ok = (lstatus & F_FW_PORT_CMD_LSTATUS) != 0;
+		linkdnrc = G_FW_PORT_CMD_LINKDNRC(lstatus);
+		port_type = G_FW_PORT_CMD_PTYPE(lstatus);
+		mod_type = G_FW_PORT_CMD_MODTYPE(lstatus);
+		pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap));
+		acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap));
+
+		/* Unfortunately the format of the Link Status in the old
+		 * 16-bit Port Information message isn't the same as the
+		 * 16-bit Port Capabilities bitfield used everywhere else ...
+		 */
+		linkattr = 0;
+		if (lstatus & F_FW_PORT_CMD_RXPAUSE)
+			linkattr |= FW_PORT_CAP32_FC_RX;
+		if (lstatus & F_FW_PORT_CMD_TXPAUSE)
+			linkattr |= FW_PORT_CAP32_FC_TX;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
+			linkattr |= FW_PORT_CAP32_SPEED_100M;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
+			linkattr |= FW_PORT_CAP32_SPEED_1G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
+			linkattr |= FW_PORT_CAP32_SPEED_10G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G))
+			linkattr |= FW_PORT_CAP32_SPEED_25G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
+			linkattr |= FW_PORT_CAP32_SPEED_40G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G))
+			linkattr |= FW_PORT_CAP32_SPEED_100G;
+
+		break;
+		}
+
+	case FW_PORT_ACTION_GET_PORT_INFO32: {
+		u32 lstatus32 =
+			be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
+
+		link_ok = (lstatus32 & F_FW_PORT_CMD_LSTATUS32) != 0;
+		linkdnrc = G_FW_PORT_CMD_LINKDNRC32(lstatus32);
+		port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
+		mod_type = G_FW_PORT_CMD_MODTYPE32(lstatus32);
+		pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
+		acaps = be32_to_cpu(cmd->u.info32.acaps32);
+		linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
+		break;
+		}
+
+	default:
+		dev_warn(adapter, "Handle Port Information: Bad Command/Action %#x\n",
+			 be32_to_cpu(cmd->action_to_len16));
+		return;
+	}
+
+	fec = fwcap_to_cc_fec(acaps);
+
+	fc = fwcap_to_cc_pause(linkattr);
+	speed = fwcap_to_speed(linkattr);
+
+	if (mod_type != pi->mod_type) {
+		lc->auto_fec = fec;
+		pi->port_type = port_type;
+		pi->mod_type = mod_type;
+		t4_os_portmod_changed(adapter, pi->port_id);
+	}
+	if (link_ok != lc->link_ok || speed != lc->speed ||
+	    fc != lc->fc || fec != lc->fec) { /* something changed */
+		if (!link_ok && lc->link_ok) {
+			lc->link_down_rc = linkdnrc;
+			dev_warn(adap, "Port %d link down, reason: %s\n",
+				 pi->tx_chan, t4_link_down_rc_str(linkdnrc));
+		}
+		lc->link_ok = link_ok;
+		lc->speed = speed;
+		lc->fc = fc;
+		lc->fec = fec;
+		lc->pcaps = pcaps;
+		lc->acaps = acaps & ADVERT_MASK;
+
+		if (lc->acaps & FW_PORT_CAP32_ANEG) {
+			lc->autoneg = AUTONEG_ENABLE;
+		} else {
+			/* When Autoneg is disabled, user needs to set
+			 * single speed.
+			 * Similar to cxgb4_ethtool.c: set_link_ksettings
+			 */
+			lc->acaps = 0;
+			lc->requested_speed = fwcap_to_speed(acaps);
+			lc->autoneg = AUTONEG_DISABLE;
+		}
+	}
+}
+
 /**
  * t4_handle_fw_rpl - process a FW reply message
  * @adap: the adapter
@@ -4321,83 +4506,21 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 	unsigned int action =
 		G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16));
 
-	if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) {
+	if (opcode == FW_PORT_CMD &&
+	    (action == FW_PORT_ACTION_GET_PORT_INFO ||
+	     action == FW_PORT_ACTION_GET_PORT_INFO32)) {
 		/* link/module state change message */
-		unsigned int speed = 0, fc = 0, i;
 		int chan = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid));
 		struct port_info *pi = NULL;
-		struct link_config *lc;
-		u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
-		int link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0;
-		u32 mod = G_FW_PORT_CMD_MODTYPE(stat);
-		unsigned int fec;
-
-		fc = fwcap_to_cc_pause(stat);
-		fec = fwcap_to_cc_fec(stat);
-
-		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_SPEED_NUM_100M;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_SPEED_NUM_1G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_SPEED_NUM_10G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G))
-			speed = ETH_SPEED_NUM_25G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_SPEED_NUM_40G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G))
-			speed = ETH_SPEED_NUM_100G;
+		int i;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
 			if (pi->tx_chan == chan)
 				break;
 		}
-		lc = &pi->link_cfg;
 
-		if (mod != pi->mod_type) {
-			lc->auto_fec = fec;
-			pi->mod_type = mod;
-			t4_os_portmod_changed(adap, i);
-		}
-		if (link_ok != lc->link_ok || speed != lc->speed ||
-		    fc != lc->fc || fec != lc->fec) { /* something changed */
-			if (!link_ok && lc->link_ok) {
-				static const char * const reason[] = {
-					"Link Down",
-					"Remote Fault",
-					"Auto-negotiation Failure",
-					"Reserved",
-					"Insufficient Airflow",
-					"Unable To Determine Reason",
-					"No RX Signal Detected",
-					"Reserved",
-				};
-				unsigned int rc = G_FW_PORT_CMD_LINKDNRC(stat);
-
-				dev_warn(adap, "Port %d link down, reason: %s\n",
-					 chan, reason[rc]);
-			}
-			lc->link_ok = link_ok;
-			lc->speed = speed;
-			lc->fc = fc;
-			lc->fec = fec;
-			lc->pcaps = be16_to_cpu(p->u.info.pcap);
-			lc->acaps = be16_to_cpu(p->u.info.acap) & ADVERT_MASK;
-			if (lc->acaps & FW_PORT_CAP32_ANEG) {
-				lc->autoneg = AUTONEG_ENABLE;
-			} else {
-				/* When Autoneg is disabled, user needs to set
-				 * single speed.
-				 */
-				lc->acaps = 0;
-				lc->requested_speed =
-					be16_to_cpu(p->u.info.acap);
-				lc->requested_speed =
-					fwcap_to_speed(lc->requested_speed);
-				lc->autoneg = AUTONEG_DISABLE;
-			}
-		}
+		t4_handle_get_port_info(pi, rpl);
 	} else {
 		dev_warn(adap, "Unknown firmware reply %d\n", opcode);
 		return -EINVAL;
@@ -4426,8 +4549,8 @@ void t4_reset_link_config(struct adapter *adap, int idx)
  * Initializes the SW state maintained for each link, including the link's
  * capabilities and default speed/flow-control/autonegotiation settings.
  */
-static void init_link_config(struct link_config *lc, unsigned int pcaps,
-			     unsigned int acaps)
+static void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
+			     fw_port_cap32_t acaps)
 {
 	lc->pcaps = pcaps;
 	lc->requested_speed = 0;
@@ -4969,46 +5092,95 @@ int t4_init_rss_mode(struct adapter *adap, int mbox)
 
 int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
 {
-	u8 addr[6];
+	unsigned int fw_caps = adap->params.fw_caps_support;
+	fw_port_cap32_t pcaps, acaps;
+	enum fw_port_type port_type;
+	struct fw_port_cmd cmd;
 	int ret, i, j = 0;
-	struct fw_port_cmd c;
+	int mdio_addr;
+	u32 action;
+	u8 addr[6];
 
-	memset(&c, 0, sizeof(c));
+	memset(&cmd, 0, sizeof(cmd));
 
 	for_each_port(adap, i) {
+		struct port_info *pi = adap2pinfo(adap, i);
 		unsigned int rss_size = 0;
-		struct port_info *p = adap2pinfo(adap, i);
 
 		while ((adap->params.portvec & (1 << j)) == 0)
 			j++;
 
-		c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
-					     F_FW_CMD_REQUEST | F_FW_CMD_READ |
-					     V_FW_PORT_CMD_PORTID(j));
-		c.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(
-						FW_PORT_ACTION_GET_PORT_INFO) |
-						FW_LEN16(c));
-		ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+		/* If we haven't yet determined whether we're talking to
+		 * Firmware which knows the new 32-bit Port Capabilities, it's
+		 * time to find out now.  This will also tell new Firmware to
+		 * send us Port Status Updates using the new 32-bit Port
+		 * Capabilities version of the Port Information message.
+		 */
+		if (fw_caps == FW_CAPS_UNKNOWN) {
+			u32 param, val, caps;
+
+			caps = FW_PARAMS_PARAM_PFVF_PORT_CAPS32;
+			param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) |
+				 V_FW_PARAMS_PARAM_X(caps));
+			val = 1;
+			ret = t4_set_params(adap, mbox, pf, vf, 1, &param,
+					    &val);
+			fw_caps = ret == 0 ? FW_CAPS32 : FW_CAPS16;
+			adap->params.fw_caps_support = fw_caps;
+		}
+
+		memset(&cmd, 0, sizeof(cmd));
+		cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
+					       F_FW_CMD_REQUEST |
+					       F_FW_CMD_READ |
+					       V_FW_PORT_CMD_PORTID(j));
+		action = fw_caps == FW_CAPS16 ? FW_PORT_ACTION_GET_PORT_INFO :
+						FW_PORT_ACTION_GET_PORT_INFO32;
+		cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) |
+						  FW_LEN16(cmd));
+		ret = t4_wr_mbox(pi->adapter, mbox, &cmd, sizeof(cmd), &cmd);
 		if (ret)
 			return ret;
 
+		/* Extract the various fields from the Port Information message.
+		 */
+		if (fw_caps == FW_CAPS16) {
+			u32 lstatus =
+				be32_to_cpu(cmd.u.info.lstatus_to_modtype);
+
+			port_type = G_FW_PORT_CMD_PTYPE(lstatus);
+			mdio_addr = (lstatus & F_FW_PORT_CMD_MDIOCAP) ?
+				    (int)G_FW_PORT_CMD_MDIOADDR(lstatus) : -1;
+			pcaps = be16_to_cpu(cmd.u.info.pcap);
+			acaps = be16_to_cpu(cmd.u.info.acap);
+			pcaps = fwcaps16_to_caps32(pcaps);
+			acaps = fwcaps16_to_caps32(acaps);
+		} else {
+			u32 lstatus32 =
+				be32_to_cpu(cmd.u.info32.lstatus32_to_cbllen32);
+
+			port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
+			mdio_addr = (lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ?
+				    (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) :
+				    -1;
+			pcaps = be32_to_cpu(cmd.u.info32.pcaps32);
+			acaps = be32_to_cpu(cmd.u.info32.acaps32);
+		}
+
 		ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
 		if (ret < 0)
 			return ret;
 
-		p->viid = ret;
-		p->tx_chan = j;
-		p->rss_size = rss_size;
+		pi->viid = ret;
+		pi->tx_chan = j;
+		pi->rss_size = rss_size;
 		t4_os_set_hw_addr(adap, i, addr);
 
-		ret = be32_to_cpu(c.u.info.lstatus_to_modtype);
-		p->mdio_addr = (ret & F_FW_PORT_CMD_MDIOCAP) ?
-				G_FW_PORT_CMD_MDIOADDR(ret) : -1;
-		p->port_type = G_FW_PORT_CMD_PTYPE(ret);
-		p->mod_type = FW_PORT_MOD_TYPE_NA;
+		pi->port_type = port_type;
+		pi->mdio_addr = mdio_addr;
+		pi->mod_type = FW_PORT_MOD_TYPE_NA;
 
-		init_link_config(&p->link_cfg, be16_to_cpu(c.u.info.pcap),
-				 be16_to_cpu(c.u.info.acap));
+		init_link_config(&pi->link_cfg, pcaps, acaps);
 		j++;
 	}
 	return 0;
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 0e139377f..d71c5a4af 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -491,7 +491,8 @@ enum fw_params_param_dev {
  * physical and virtual function parameters
  */
 enum fw_params_param_pfvf {
-	FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31
+	FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31,
+	FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A
 };
 
 /*
@@ -1226,6 +1227,8 @@ enum fw_port_mdi32 {
 enum fw_port_action {
 	FW_PORT_ACTION_L1_CFG		= 0x0001,
 	FW_PORT_ACTION_GET_PORT_INFO	= 0x0003,
+	FW_PORT_ACTION_L1_CFG32         = 0x0009,
+	FW_PORT_ACTION_GET_PORT_INFO32  = 0x000a,
 };
 
 struct fw_port_cmd {
@@ -1314,6 +1317,18 @@ struct fw_port_cmd {
 				__be64 r12;
 			} control;
 		} dcb;
+		struct fw_port_l1cfg32 {
+			__be32 rcap32;
+			__be32 r;
+		} l1cfg32;
+		struct fw_port_info32 {
+			__be32 lstatus32_to_cbllen32;
+			__be32 auxlinfo32_mtu32;
+			__be32 linkattr32;
+			__be32 pcaps32;
+			__be32 acaps32;
+			__be32 lpacaps32;
+		} info32;
 	} u;
 };
 
@@ -1387,6 +1402,36 @@ struct fw_port_cmd {
 #define G_FW_PORT_CMD_MODTYPE(x)	\
 	(((x) >> S_FW_PORT_CMD_MODTYPE) & M_FW_PORT_CMD_MODTYPE)
 
+#define S_FW_PORT_CMD_LSTATUS32                31
+#define M_FW_PORT_CMD_LSTATUS32                0x1
+#define V_FW_PORT_CMD_LSTATUS32(x)     ((x) << S_FW_PORT_CMD_LSTATUS32)
+#define F_FW_PORT_CMD_LSTATUS32        V_FW_PORT_CMD_LSTATUS32(1U)
+
+#define S_FW_PORT_CMD_LINKDNRC32       28
+#define M_FW_PORT_CMD_LINKDNRC32       0x7
+#define G_FW_PORT_CMD_LINKDNRC32(x)    \
+	(((x) >> S_FW_PORT_CMD_LINKDNRC32) & M_FW_PORT_CMD_LINKDNRC32)
+
+#define S_FW_PORT_CMD_MDIOCAP32                26
+#define M_FW_PORT_CMD_MDIOCAP32                0x1
+#define V_FW_PORT_CMD_MDIOCAP32(x)     ((x) << S_FW_PORT_CMD_MDIOCAP32)
+#define F_FW_PORT_CMD_MDIOCAP32        V_FW_PORT_CMD_MDIOCAP32(1U)
+
+#define S_FW_PORT_CMD_MDIOADDR32       21
+#define M_FW_PORT_CMD_MDIOADDR32       0x1f
+#define G_FW_PORT_CMD_MDIOADDR32(x)    \
+	(((x) >> S_FW_PORT_CMD_MDIOADDR32) & M_FW_PORT_CMD_MDIOADDR32)
+
+#define S_FW_PORT_CMD_PORTTYPE32        13
+#define M_FW_PORT_CMD_PORTTYPE32        0xff
+#define G_FW_PORT_CMD_PORTTYPE32(x)     \
+	(((x) >> S_FW_PORT_CMD_PORTTYPE32) & M_FW_PORT_CMD_PORTTYPE32)
+
+#define S_FW_PORT_CMD_MODTYPE32                8
+#define M_FW_PORT_CMD_MODTYPE32                0x1f
+#define G_FW_PORT_CMD_MODTYPE32(x)     \
+	(((x) >> S_FW_PORT_CMD_MODTYPE32) & M_FW_PORT_CMD_MODTYPE32)
+
 /*
  * These are configured into the VPD and hence tools that generate
  * VPD may use this enumeration.
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/7] cxgbe: update link state when link speed changes
  2018-02-04  6:06 ` [PATCH 2/7] cxgbe: update link state when link speed changes Rahul Lakkireddy
@ 2018-02-05 17:05   ` Ferruh Yigit
  0 siblings, 0 replies; 29+ messages in thread
From: Ferruh Yigit @ 2018-02-05 17:05 UTC (permalink / raw)
  To: Rahul Lakkireddy, dev; +Cc: kumaras, surendra, nirranjan, indranil

On 2/4/2018 6:06 AM, Rahul Lakkireddy wrote:
> From: Kumar Sanghvi <kumaras@chelsio.com>
> 
> Original work by Surendra Mobiya <surendra@chelsio.com>
> 
> Fixes: cdac6e2eeafc ("cxgbe: add link related functions")
> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> ---
>  drivers/net/cxgbe/cxgbe_ethdev.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
> index 6d56f3c1b..5a25125fe 100644
> --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> @@ -227,7 +227,8 @@ static int cxgbe_dev_link_update(struct rte_eth_dev *eth_dev,
>  	unsigned int work_done, budget = 4;
>  
>  	cxgbe_poll(&s->fw_evtq, NULL, budget, &work_done);
> -	if (old_link->link_status == pi->link_cfg.link_ok)
> +	if (old_link->link_status == pi->link_cfg.link_ok &&
> +	    old_link->link_speed == pi->link_cfg.speed)

As Stephen's patch tried to clean this up, link_update dev_ops return value is
not very clear now and this return value not used at all in ethdev layer. And as
far as I can see you are also not using this locally in driver, so there is no
effect of updating this code, good or bad, I suggest postponing this update
until return value cleared more.

>  		return -1;  /* link not changed */
>  
>  	eth_dev->data->dev_link.link_status = pi->link_cfg.link_ok;
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-04  6:06 ` [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
@ 2018-02-05 17:09   ` Ferruh Yigit
  2018-02-06  9:22     ` Rahul Lakkireddy
  0 siblings, 1 reply; 29+ messages in thread
From: Ferruh Yigit @ 2018-02-05 17:09 UTC (permalink / raw)
  To: Rahul Lakkireddy, dev; +Cc: kumaras, surendra, nirranjan, indranil

On 2/4/2018 6:06 AM, Rahul Lakkireddy wrote:
> From: Kumar Sanghvi <kumaras@chelsio.com>
> 
> Add firmware API for updating RSS hash configuration and key.  Move
> RSS hash configuration from cxgb4_write_rss() to a separate function
> cxgbe_write_rss_conf().
> 
> Also, rename cxgb4_write_rss() to cxgbe_write_rss() for consistency.
> 
> Original work by Surendra Mobiya <surendra@chelsio.com>
> 
> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> ---
>  doc/guides/nics/cxgbe.rst               |  2 +
>  doc/guides/nics/features/cxgbe.ini      |  1 +
>  doc/guides/rel_notes/release_18_02.rst  |  3 ++
>  drivers/net/cxgbe/base/adapter.h        |  4 +-
>  drivers/net/cxgbe/base/common.h         |  3 ++
>  drivers/net/cxgbe/base/t4_hw.c          | 73 +++++++++++++++++++++++++++
>  drivers/net/cxgbe/base/t4_regs.h        | 25 +++++++++
>  drivers/net/cxgbe/base/t4fw_interface.h | 89 +++++++++++++++++++++++++++++++++
>  drivers/net/cxgbe/cxgbe.h               |  2 +
>  drivers/net/cxgbe/cxgbe_ethdev.c        | 32 ++++++++++++
>  drivers/net/cxgbe/cxgbe_main.c          | 79 ++++++++++++++++++++++-------
>  11 files changed, 295 insertions(+), 18 deletions(-)

I tend to get driver patches even after integration deadline, mainly because of
their limited scope.
But since these are new features, submitted just before rc3, adding with
questions in first patch, I am for postponing this patchset to next release and
do more review, what do you think?

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/7] cxgbe: fix secondary process initialization
  2018-02-04  6:06 ` [PATCH 1/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
@ 2018-02-05 17:23   ` Ferruh Yigit
  2018-02-06  9:20     ` Rahul Lakkireddy
  0 siblings, 1 reply; 29+ messages in thread
From: Ferruh Yigit @ 2018-02-05 17:23 UTC (permalink / raw)
  To: Rahul Lakkireddy, dev; +Cc: kumaras, surendra, nirranjan, indranil

On 2/4/2018 6:06 AM, Rahul Lakkireddy wrote:
> From: Kumar Sanghvi <kumaras@chelsio.com>
> 
> rte_eth_dev_allocate already assigns the eth_dev_data. So,
> don't allocate it separately as part of probe function. And we
> save this eth_dev_data as part of txq structure.
> 
> Attach to rte_eth_dev devices allocated by Primary process for
> Ports other than Port-0 in the secondary process.
> 
> Fixes: 8318984927ff ("cxgbe: add pmd skeleton")
> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> ---
>  doc/guides/nics/features/cxgbe.ini |  1 +
>  drivers/net/cxgbe/base/adapter.h   |  1 +
>  drivers/net/cxgbe/cxgbe_ethdev.c   | 28 +++++++++++++++++++++++-----
>  drivers/net/cxgbe/cxgbe_main.c     | 11 ++---------
>  drivers/net/cxgbe/sge.c            |  5 +++--
>  5 files changed, 30 insertions(+), 16 deletions(-)
> 
> diff --git a/doc/guides/nics/features/cxgbe.ini b/doc/guides/nics/features/cxgbe.ini
> index 3d0fde2fd..1b9d81ffb 100644
> --- a/doc/guides/nics/features/cxgbe.ini
> +++ b/doc/guides/nics/features/cxgbe.ini
> @@ -24,6 +24,7 @@ Basic stats          = Y
>  Stats per queue      = Y
>  EEPROM dump          = Y
>  Registers dump       = Y
> +Multiprocess aware   = Y
>  BSD nic_uio          = Y
>  Linux UIO            = Y
>  Linux VFIO           = Y
> diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
> index f2057af14..0c1a1be25 100644
> --- a/drivers/net/cxgbe/base/adapter.h
> +++ b/drivers/net/cxgbe/base/adapter.h
> @@ -267,6 +267,7 @@ struct sge_eth_tx_stats {	/* Ethernet tx queue statistics */
>  struct sge_eth_txq {                   /* state for an SGE Ethernet Tx queue */
>  	struct sge_txq q;
>  	struct rte_eth_dev *eth_dev;   /* port that this queue belongs to */
> +	struct rte_eth_dev_data *data;

Why you need to store a local copy of data? You have to store/know eth_dev, and
I believe it is always better idea to access data through eth_dev. Perhaps we
even should hide this access with macro etc. Not sure about motivation of this.

>  	struct sge_eth_tx_stats stats; /* queue statistics */
>  	rte_spinlock_t txq_lock;
>  
> diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
> index 5cd260f48..6d56f3c1b 100644
> --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> @@ -1004,14 +1004,32 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
>  	eth_dev->dev_ops = &cxgbe_eth_dev_ops;
>  	eth_dev->rx_pkt_burst = &cxgbe_recv_pkts;
>  	eth_dev->tx_pkt_burst = &cxgbe_xmit_pkts;
> +	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
>  
> -	/* for secondary processes, we don't initialise any further as primary
> -	 * has already done this work.
> +	/* for secondary processes, we attach to ethdevs allocated by primary
> +	 * and do minimal initialization.
>  	 */
> -	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> +	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> +		int i;
> +
> +		for (i = 1; i < MAX_NPORTS; i++) {
> +			struct rte_eth_dev *rest_eth_dev;
> +			char namei[RTE_ETH_NAME_MAX_LEN];
> +
> +			snprintf(namei, sizeof(namei), "cxgbe%d", i);
> +			rest_eth_dev = rte_eth_dev_attach_secondary(namei);
> +			if (rest_eth_dev) {
> +				rest_eth_dev->device = &pci_dev->device;
> +				rest_eth_dev->dev_ops =
> +					eth_dev->dev_ops;
> +				rest_eth_dev->rx_pkt_burst =
> +					eth_dev->rx_pkt_burst;
> +				rest_eth_dev->tx_pkt_burst =
> +					eth_dev->tx_pkt_burst;
> +			}
> +		}

You shouldn't need this update, old version seems better.

If a secondary process is running call stack is like:
eth_cxgbe_pci_probe
  rte_eth_dev_pci_generic_probe
    rte_eth_dev_pci_allocate
      rte_eth_dev_attach_secondary
    eth_cxgbe_dev_init

rte_eth_dev_attach_secondary() already called in the patch, all need to be done
in eth_cxgbe_dev_init() which already does.

Unless I am missing something this update shouldn't happen.


>  		return 0;
> -
> -	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
> +	}
>  
>  	snprintf(name, sizeof(name), "cxgbeadapter%d", eth_dev->data->port_id);
>  	adapter = rte_zmalloc(name, sizeof(*adapter), 0);
> diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
> index 28db6c061..c502fadf7 100644
> --- a/drivers/net/cxgbe/cxgbe_main.c
> +++ b/drivers/net/cxgbe/cxgbe_main.c
> @@ -1266,8 +1266,6 @@ int cxgbe_probe(struct adapter *adapter)
>  
>  	for_each_port(adapter, i) {
>  		char name[RTE_ETH_NAME_MAX_LEN];
> -		struct rte_eth_dev_data *data = NULL;
> -		const unsigned int numa_node = rte_socket_id();
>  
>  		pi = &adapter->port[i];
>  		pi->adapter = adapter;
> @@ -1293,13 +1291,8 @@ int cxgbe_probe(struct adapter *adapter)
>  		if (!pi->eth_dev)
>  			goto out_free;
>  
> -		data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
> -		if (!data)
> -			goto out_free;
> -
> -		data->port_id = adapter->eth_dev->data->port_id + i;
> -
> -		pi->eth_dev->data = data;

+1 to remove allocating "data" which is already comes with eth_dev.

We allocate them for virtual PMDs because they are local to the process, not
shared between DPDK processes.

Overall I am not sure about cxgbe_probe(), which has been called by
eth_cxgbe_dev_init() and eth_cxgbe_dev_init() already knows the allocated
eth_dev, but cxgbe_probe() ignores it and allocates a new one, I am not able to
understand why.

> +		pi->eth_dev->data->port_id =
> +			adapter->eth_dev->data->port_id + i;

And this one, why updating internal port_id value, this looks wrong, how
multi-process works with this and if there is another nic in the system now
port_id is no more unique.

Perhaps you have a unique hardware/use case, it helps a lot if you can describe
it a little.

>  
>  allocate_mac:
>  		pi->eth_dev->device = &adapter->pdev->device;
> diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
> index 3d5aa596f..6ff8bc46b 100644
> --- a/drivers/net/cxgbe/sge.c
> +++ b/drivers/net/cxgbe/sge.c
> @@ -1095,7 +1095,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
>  	u32 wr_mid;
>  	u64 cntrl, *end;
>  	bool v6;
> -	u32 max_pkt_len = txq->eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
> +	u32 max_pkt_len = txq->data->dev_conf.rxmode.max_rx_pkt_len;
>  
>  	/* Reject xmit if queue is stopped */
>  	if (unlikely(txq->flags & EQ_STOPPED))
> @@ -1115,7 +1115,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
>  	    (unlikely(m->pkt_len > max_pkt_len)))
>  		goto out_free;
>  
> -	pi = (struct port_info *)txq->eth_dev->data->dev_private;
> +	pi = (struct port_info *)txq->data->dev_private;
>  	adap = pi->adapter;
>  
>  	cntrl = F_TXPKT_L4CSUM_DIS | F_TXPKT_IPCSUM_DIS;
> @@ -1997,6 +1997,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
>  	txq->stats.mapping_err = 0;
>  	txq->flags |= EQ_STOPPED;
>  	txq->eth_dev = eth_dev;
> +	txq->data = eth_dev->data;
>  	t4_os_lock_init(&txq->txq_lock);
>  	return 0;
>  }
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 1/7] cxgbe: fix secondary process initialization
  2018-02-05 17:23   ` Ferruh Yigit
@ 2018-02-06  9:20     ` Rahul Lakkireddy
  0 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-06  9:20 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, Kumar A S, Surendra Mobiya, Nirranjan Kirubaharan,
	Indranil Choudhury

On Monday, February 02/05/18, 2018 at 22:53:36 +0530, Ferruh Yigit wrote:
> On 2/4/2018 6:06 AM, Rahul Lakkireddy wrote:
> > From: Kumar Sanghvi <kumaras@chelsio.com>
> > 
> > rte_eth_dev_allocate already assigns the eth_dev_data. So,
> > don't allocate it separately as part of probe function. And we
> > save this eth_dev_data as part of txq structure.
> > 
> > Attach to rte_eth_dev devices allocated by Primary process for
> > Ports other than Port-0 in the secondary process.
> > 
> > Fixes: 8318984927ff ("cxgbe: add pmd skeleton")
> > Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> > Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> > ---
> >  doc/guides/nics/features/cxgbe.ini |  1 +
> >  drivers/net/cxgbe/base/adapter.h   |  1 +
> >  drivers/net/cxgbe/cxgbe_ethdev.c   | 28 +++++++++++++++++++++++-----
> >  drivers/net/cxgbe/cxgbe_main.c     | 11 ++---------
> >  drivers/net/cxgbe/sge.c            |  5 +++--
> >  5 files changed, 30 insertions(+), 16 deletions(-)
> > 
> > diff --git a/doc/guides/nics/features/cxgbe.ini b/doc/guides/nics/features/cxgbe.ini
> > index 3d0fde2fd..1b9d81ffb 100644
> > --- a/doc/guides/nics/features/cxgbe.ini
> > +++ b/doc/guides/nics/features/cxgbe.ini
> > @@ -24,6 +24,7 @@ Basic stats          = Y
> >  Stats per queue      = Y
> >  EEPROM dump          = Y
> >  Registers dump       = Y
> > +Multiprocess aware   = Y
> >  BSD nic_uio          = Y
> >  Linux UIO            = Y
> >  Linux VFIO           = Y
> > diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
> > index f2057af14..0c1a1be25 100644
> > --- a/drivers/net/cxgbe/base/adapter.h
> > +++ b/drivers/net/cxgbe/base/adapter.h
> > @@ -267,6 +267,7 @@ struct sge_eth_tx_stats {	/* Ethernet tx queue statistics */
> >  struct sge_eth_txq {                   /* state for an SGE Ethernet Tx queue */
> >  	struct sge_txq q;
> >  	struct rte_eth_dev *eth_dev;   /* port that this queue belongs to */
> > +	struct rte_eth_dev_data *data;
> 
> Why you need to store a local copy of data? You have to store/know eth_dev, and
> I believe it is always better idea to access data through eth_dev. Perhaps we
> even should hide this access with macro etc. Not sure about motivation of this.
> 

Considering an example of Multiprocess Server and Client app, with
command-line like:
# mp_server -l 1-2 -n 4 -- -p 3 -n 2
# mp_client -l 3 -n 4 --proc-type=auto -- -n 0
# mp_client -l 4 -n 4 --proc-type=auto -- -n 1

Below is the flow...

For Primary process:
- For Port-0, eth_dev comes from stack.
- For Port-1 and onwards, we allocate eth_dev via
  rte_eth_dev_allocate().
Both will have its own eth_dev_data.
Also, in primary, we allocate TxQ, RxQ and associate them with
respective eth_dev available in Primary.

   
For Secondary process:
New Port-0 ethdev would be allocated. However, it will attach to
eth_dev_data of Primary's Port-0.
New Port-1 ethdev would be allocated. However, it will now attach
to eth_dev_data of Primary's Port-1.
    
When Secondary process transmits on Port-1, it transmits over Port-1
ethdev allocated in Secondary process.
Since this ethdev has same eth_dev_data of Primary's Port-1 - it
transmits over TxQ allocated in Primary process.
     
Now, when we are in t4_eth_xmit (via cxgbe_xmit_pkts), all we have is a
TxQ. And in Primary process, we always associate TxQ with respective
ethdev i.e. in this case, it would be Port-1 ethdev of Primary. So, for
retrieving max_rx_pkt_len in t4_eth_xmit, when we access txq->eth_dev -
it is NULL ---> because secondary process can't access eth_dev of
Primary.

And thats why, we need a pointer for directly accessing the eth_dev_data
from t4_eth_xmit.

> >  	struct sge_eth_tx_stats stats; /* queue statistics */
> >  	rte_spinlock_t txq_lock;
> >  
> > diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
> > index 5cd260f48..6d56f3c1b 100644
> > --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> > +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> > @@ -1004,14 +1004,32 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
> >  	eth_dev->dev_ops = &cxgbe_eth_dev_ops;
> >  	eth_dev->rx_pkt_burst = &cxgbe_recv_pkts;
> >  	eth_dev->tx_pkt_burst = &cxgbe_xmit_pkts;
> > +	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
> >  
> > -	/* for secondary processes, we don't initialise any further as primary
> > -	 * has already done this work.
> > +	/* for secondary processes, we attach to ethdevs allocated by primary
> > +	 * and do minimal initialization.
> >  	 */
> > -	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
> > +	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> > +		int i;
> > +
> > +		for (i = 1; i < MAX_NPORTS; i++) {
> > +			struct rte_eth_dev *rest_eth_dev;
> > +			char namei[RTE_ETH_NAME_MAX_LEN];
> > +
> > +			snprintf(namei, sizeof(namei), "cxgbe%d", i);
> > +			rest_eth_dev = rte_eth_dev_attach_secondary(namei);
> > +			if (rest_eth_dev) {
> > +				rest_eth_dev->device = &pci_dev->device;
> > +				rest_eth_dev->dev_ops =
> > +					eth_dev->dev_ops;
> > +				rest_eth_dev->rx_pkt_burst =
> > +					eth_dev->rx_pkt_burst;
> > +				rest_eth_dev->tx_pkt_burst =
> > +					eth_dev->tx_pkt_burst;
> > +			}
> > +		}
> 
> You shouldn't need this update, old version seems better.
> 
> If a secondary process is running call stack is like:
> eth_cxgbe_pci_probe
>   rte_eth_dev_pci_generic_probe
>     rte_eth_dev_pci_allocate
>       rte_eth_dev_attach_secondary
>     eth_cxgbe_dev_init
> 
> rte_eth_dev_attach_secondary() already called in the patch, all need to be done
> in eth_cxgbe_dev_init() which already does.
> 
> Unless I am missing something this update shouldn't happen.
> 
> 

All physical ports on the device are exposed to DPDK via a single
physical function (PF).  We only bind our PF4 to DPDK stack.
Thus, eth_cxgbe_pci_probe() is called only for port 0, and we have
to handle the remaining ports manually.

> >  		return 0;
> > -
> > -	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
> > +	}
> >  
> >  	snprintf(name, sizeof(name), "cxgbeadapter%d", eth_dev->data->port_id);
> >  	adapter = rte_zmalloc(name, sizeof(*adapter), 0);
> > diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
> > index 28db6c061..c502fadf7 100644
> > --- a/drivers/net/cxgbe/cxgbe_main.c
> > +++ b/drivers/net/cxgbe/cxgbe_main.c
> > @@ -1266,8 +1266,6 @@ int cxgbe_probe(struct adapter *adapter)
> >  
> >  	for_each_port(adapter, i) {
> >  		char name[RTE_ETH_NAME_MAX_LEN];
> > -		struct rte_eth_dev_data *data = NULL;
> > -		const unsigned int numa_node = rte_socket_id();
> >  
> >  		pi = &adapter->port[i];
> >  		pi->adapter = adapter;
> > @@ -1293,13 +1291,8 @@ int cxgbe_probe(struct adapter *adapter)
> >  		if (!pi->eth_dev)
> >  			goto out_free;
> >  
> > -		data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
> > -		if (!data)
> > -			goto out_free;
> > -
> > -		data->port_id = adapter->eth_dev->data->port_id + i;
> > -
> > -		pi->eth_dev->data = data;
> 
> +1 to remove allocating "data" which is already comes with eth_dev.
> 
> We allocate them for virtual PMDs because they are local to the process, not
> shared between DPDK processes.
> 
> Overall I am not sure about cxgbe_probe(), which has been called by
> eth_cxgbe_dev_init() and eth_cxgbe_dev_init() already knows the allocated
> eth_dev, but cxgbe_probe() ignores it and allocates a new one, I am not able to
> understand why.
> 

Like I said, we only bind a single PF to DPDK.  Port 0 is already
handled by DPDK stack, but we need to handle exposing the remaining
ports on the device manually and hence the call to
rte_eth_dev_allocate() for remaining ports in cxgbe_probe().

> > +		pi->eth_dev->data->port_id =
> > +			adapter->eth_dev->data->port_id + i;
> 
> And this one, why updating internal port_id value, this looks wrong, how
> multi-process works with this and if there is another nic in the system now
> port_id is no more unique.
> 

Good catch!  I see that rte_eth_dev_allocate() already assigns unique
port_id and this seems unnecessary.  Will fix this.

> Perhaps you have a unique hardware/use case, it helps a lot if you can describe
> it a little.
> 

I hope my explanation above about multiple ports on single PF makes
sense. Let us know if unclear or more info is needed.

> >  
> >  allocate_mac:
> >  		pi->eth_dev->device = &adapter->pdev->device;
> > diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
> > index 3d5aa596f..6ff8bc46b 100644
> > --- a/drivers/net/cxgbe/sge.c
> > +++ b/drivers/net/cxgbe/sge.c
> > @@ -1095,7 +1095,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
> >  	u32 wr_mid;
> >  	u64 cntrl, *end;
> >  	bool v6;
> > -	u32 max_pkt_len = txq->eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
> > +	u32 max_pkt_len = txq->data->dev_conf.rxmode.max_rx_pkt_len;
> >  
> >  	/* Reject xmit if queue is stopped */
> >  	if (unlikely(txq->flags & EQ_STOPPED))
> > @@ -1115,7 +1115,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
> >  	    (unlikely(m->pkt_len > max_pkt_len)))
> >  		goto out_free;
> >  
> > -	pi = (struct port_info *)txq->eth_dev->data->dev_private;
> > +	pi = (struct port_info *)txq->data->dev_private;
> >  	adap = pi->adapter;
> >  
> >  	cntrl = F_TXPKT_L4CSUM_DIS | F_TXPKT_IPCSUM_DIS;
> > @@ -1997,6 +1997,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
> >  	txq->stats.mapping_err = 0;
> >  	txq->flags |= EQ_STOPPED;
> >  	txq->eth_dev = eth_dev;
> > +	txq->data = eth_dev->data;
> >  	t4_os_lock_init(&txq->txq_lock);
> >  	return 0;
> >  }
> > 
> 

Thanks,
Rahul

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-05 17:09   ` Ferruh Yigit
@ 2018-02-06  9:22     ` Rahul Lakkireddy
  2018-02-06 10:11       ` Ferruh Yigit
  0 siblings, 1 reply; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-06  9:22 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, Kumar A S, Surendra Mobiya, Nirranjan Kirubaharan,
	Indranil Choudhury

On Monday, February 02/05/18, 2018 at 22:39:55 +0530, Ferruh Yigit wrote:
> On 2/4/2018 6:06 AM, Rahul Lakkireddy wrote:
> > From: Kumar Sanghvi <kumaras@chelsio.com>
> > 
> > Add firmware API for updating RSS hash configuration and key.  Move
> > RSS hash configuration from cxgb4_write_rss() to a separate function
> > cxgbe_write_rss_conf().
> > 
> > Also, rename cxgb4_write_rss() to cxgbe_write_rss() for consistency.
> > 
> > Original work by Surendra Mobiya <surendra@chelsio.com>
> > 
> > Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> > Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> > ---
> >  doc/guides/nics/cxgbe.rst               |  2 +
> >  doc/guides/nics/features/cxgbe.ini      |  1 +
> >  doc/guides/rel_notes/release_18_02.rst  |  3 ++
> >  drivers/net/cxgbe/base/adapter.h        |  4 +-
> >  drivers/net/cxgbe/base/common.h         |  3 ++
> >  drivers/net/cxgbe/base/t4_hw.c          | 73 +++++++++++++++++++++++++++
> >  drivers/net/cxgbe/base/t4_regs.h        | 25 +++++++++
> >  drivers/net/cxgbe/base/t4fw_interface.h | 89 +++++++++++++++++++++++++++++++++
> >  drivers/net/cxgbe/cxgbe.h               |  2 +
> >  drivers/net/cxgbe/cxgbe_ethdev.c        | 32 ++++++++++++
> >  drivers/net/cxgbe/cxgbe_main.c          | 79 ++++++++++++++++++++++-------
> >  11 files changed, 295 insertions(+), 18 deletions(-)
> 
> I tend to get driver patches even after integration deadline, mainly because of
> their limited scope.
> But since these are new features, submitted just before rc3, adding with
> questions in first patch, I am for postponing this patchset to next release and
> do more review, what do you think?

Does dpdk-next-net tree work similar to linux "next" trees?  I mean does
it represent the next release (DPDK 18.05-rc1) merge window?  Can we
explicitly mention in Patch title which tree it is targeted for viz.
dpdk or dpdk-next-net?

Thanks,
Rahul

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-06  9:22     ` Rahul Lakkireddy
@ 2018-02-06 10:11       ` Ferruh Yigit
  2018-02-06 10:38         ` Thomas Monjalon
  0 siblings, 1 reply; 29+ messages in thread
From: Ferruh Yigit @ 2018-02-06 10:11 UTC (permalink / raw)
  To: Rahul Lakkireddy
  Cc: dev, Kumar A S, Surendra Mobiya, Nirranjan Kirubaharan,
	Indranil Choudhury, Thomas Monjalon

On 2/6/2018 9:22 AM, Rahul Lakkireddy wrote:
> On Monday, February 02/05/18, 2018 at 22:39:55 +0530, Ferruh Yigit wrote:
>> On 2/4/2018 6:06 AM, Rahul Lakkireddy wrote:
>>> From: Kumar Sanghvi <kumaras@chelsio.com>
>>>
>>> Add firmware API for updating RSS hash configuration and key.  Move
>>> RSS hash configuration from cxgb4_write_rss() to a separate function
>>> cxgbe_write_rss_conf().
>>>
>>> Also, rename cxgb4_write_rss() to cxgbe_write_rss() for consistency.
>>>
>>> Original work by Surendra Mobiya <surendra@chelsio.com>
>>>
>>> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
>>> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
>>> ---
>>>  doc/guides/nics/cxgbe.rst               |  2 +
>>>  doc/guides/nics/features/cxgbe.ini      |  1 +
>>>  doc/guides/rel_notes/release_18_02.rst  |  3 ++
>>>  drivers/net/cxgbe/base/adapter.h        |  4 +-
>>>  drivers/net/cxgbe/base/common.h         |  3 ++
>>>  drivers/net/cxgbe/base/t4_hw.c          | 73 +++++++++++++++++++++++++++
>>>  drivers/net/cxgbe/base/t4_regs.h        | 25 +++++++++
>>>  drivers/net/cxgbe/base/t4fw_interface.h | 89 +++++++++++++++++++++++++++++++++
>>>  drivers/net/cxgbe/cxgbe.h               |  2 +
>>>  drivers/net/cxgbe/cxgbe_ethdev.c        | 32 ++++++++++++
>>>  drivers/net/cxgbe/cxgbe_main.c          | 79 ++++++++++++++++++++++-------
>>>  11 files changed, 295 insertions(+), 18 deletions(-)
>>
>> I tend to get driver patches even after integration deadline, mainly because of
>> their limited scope.
>> But since these are new features, submitted just before rc3, adding with
>> questions in first patch, I am for postponing this patchset to next release and
>> do more review, what do you think?
> 
> Does dpdk-next-net tree work similar to linux "next" trees?  I mean does
> it represent the next release (DPDK 18.05-rc1) merge window?  Can we
> explicitly mention in Patch title which tree it is targeted for viz.
> dpdk or dpdk-next-net?

Hi Rahul,

It is not like Linux next trees, this is more like Dave's net tree.
In dpdk responsibilities split into sub-trees, and all target current release,
patches merged into sub-trees and pulled by main tree in integration deadline.

All network drivers and ethdev abstraction layer patches goes into next-net
sub-tree.


Briefly overall process is [1]:
- A new feature needs to be sent before proposal deadline, this can be a full
version of the set or RFC. Proposal deadline for the release announced in
https://dpdk.org/dev/roadmap

- After that point code reviews done and new versions sent till integration
deadline. Accepted patches are integrated to release candidate 1 (rc1).
Of course patch can be reviewed and merged without waiting integration deadline.
If a patch not get an approval and merge into tree in integration deadline,
most probably it won't go into release.

- Fixes can be sent from beginning of release to rcX. Only latest rcX mostly for
the fixes on features introduced in that release.

- After rc1, code tested and fixes sent for found defects. No new feature
expected after rc1.

- We go mostly to rc3 or rc4 before release.


[1]
Thomas, please correct me if I missed something. And this needs to be documented
indeed.

> 
> Thanks,
> Rahul
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-06 10:11       ` Ferruh Yigit
@ 2018-02-06 10:38         ` Thomas Monjalon
  2018-02-07  7:01           ` Rahul Lakkireddy
  0 siblings, 1 reply; 29+ messages in thread
From: Thomas Monjalon @ 2018-02-06 10:38 UTC (permalink / raw)
  To: Ferruh Yigit, Rahul Lakkireddy
  Cc: dev, Kumar A S, Surendra Mobiya, Nirranjan Kirubaharan,
	Indranil Choudhury

06/02/2018 11:11, Ferruh Yigit:
> On 2/6/2018 9:22 AM, Rahul Lakkireddy wrote:
> > On Monday, February 02/05/18, 2018 at 22:39:55 +0530, Ferruh Yigit wrote:
> >> I tend to get driver patches even after integration deadline, mainly because of
> >> their limited scope.
> >> But since these are new features, submitted just before rc3, adding with
> >> questions in first patch, I am for postponing this patchset to next release and
> >> do more review, what do you think?
> > 
> > Does dpdk-next-net tree work similar to linux "next" trees?  I mean does
> > it represent the next release (DPDK 18.05-rc1) merge window?  Can we
> > explicitly mention in Patch title which tree it is targeted for viz.
> > dpdk or dpdk-next-net?
> 
> Hi Rahul,
> 
> It is not like Linux next trees, this is more like Dave's net tree.
> In dpdk responsibilities split into sub-trees, and all target current release,
> patches merged into sub-trees and pulled by main tree in integration deadline.
> 
> All network drivers and ethdev abstraction layer patches goes into next-net
> sub-tree.
> 
> 
> Briefly overall process is [1]:
> - A new feature needs to be sent before proposal deadline, this can be a full
> version of the set or RFC. Proposal deadline for the release announced in
> https://dpdk.org/dev/roadmap
> 
> - After that point code reviews done and new versions sent till integration
> deadline. Accepted patches are integrated to release candidate 1 (rc1).
> Of course patch can be reviewed and merged without waiting integration deadline.
> If a patch not get an approval and merge into tree in integration deadline,
> most probably it won't go into release.
> 
> - Fixes can be sent from beginning of release to rcX. Only latest rcX mostly for
> the fixes on features introduced in that release.
> 
> - After rc1, code tested and fixes sent for found defects. No new feature
> expected after rc1.
> 
> - We go mostly to rc3 or rc4 before release.
> 
> 
> [1]
> Thomas, please correct me if I missed something. And this needs to be documented
> indeed.

If the patchset targets 18.05, it should be notified.
I suggest --subject-prefix='PATCH 18.05'.
Then it will be marked as Deferred in patchwork until the start of
the 18.05 release cycle.
We can review it but we do not apply it before the start of the cycle,
because we don't see a real need for such "in advance" branch.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-06 10:38         ` Thomas Monjalon
@ 2018-02-07  7:01           ` Rahul Lakkireddy
  0 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-07  7:01 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Ferruh Yigit, dev, Kumar A S, Surendra Mobiya,
	Nirranjan Kirubaharan, Indranil Choudhury

On Tuesday, February 02/06/18, 2018 at 16:08:35 +0530, Thomas Monjalon wrote:
> 06/02/2018 11:11, Ferruh Yigit:
> > On 2/6/2018 9:22 AM, Rahul Lakkireddy wrote:
> > > On Monday, February 02/05/18, 2018 at 22:39:55 +0530, Ferruh Yigit wrote:
> > >> I tend to get driver patches even after integration deadline, mainly because of
> > >> their limited scope.
> > >> But since these are new features, submitted just before rc3, adding with
> > >> questions in first patch, I am for postponing this patchset to next release and
> > >> do more review, what do you think?
> > > 
> > > Does dpdk-next-net tree work similar to linux "next" trees?  I mean does
> > > it represent the next release (DPDK 18.05-rc1) merge window?  Can we
> > > explicitly mention in Patch title which tree it is targeted for viz.
> > > dpdk or dpdk-next-net?
> > 
> > Hi Rahul,
> > 
> > It is not like Linux next trees, this is more like Dave's net tree.
> > In dpdk responsibilities split into sub-trees, and all target current release,
> > patches merged into sub-trees and pulled by main tree in integration deadline.
> > 
> > All network drivers and ethdev abstraction layer patches goes into next-net
> > sub-tree.
> > 
> > 
> > Briefly overall process is [1]:
> > - A new feature needs to be sent before proposal deadline, this can be a full
> > version of the set or RFC. Proposal deadline for the release announced in
> > https://dpdk.org/dev/roadmap
> > 
> > - After that point code reviews done and new versions sent till integration
> > deadline. Accepted patches are integrated to release candidate 1 (rc1).
> > Of course patch can be reviewed and merged without waiting integration deadline.
> > If a patch not get an approval and merge into tree in integration deadline,
> > most probably it won't go into release.
> > 
> > - Fixes can be sent from beginning of release to rcX. Only latest rcX mostly for
> > the fixes on features introduced in that release.
> > 
> > - After rc1, code tested and fixes sent for found defects. No new feature
> > expected after rc1.
> > 
> > - We go mostly to rc3 or rc4 before release.
> > 
> > 
> > [1]
> > Thomas, please correct me if I missed something. And this needs to be documented
> > indeed.
> 
> If the patchset targets 18.05, it should be notified.
> I suggest --subject-prefix='PATCH 18.05'.
> Then it will be marked as Deferred in patchwork until the start of
> the 18.05 release cycle.
> We can review it but we do not apply it before the start of the cycle,
> because we don't see a real need for such "in advance" branch.
> 

Thank you Ferruh and Thomas for explaining workings/role of
dpdk-next-net tree.

I will wait for few more days to get reviews on patch related to
multiprocess.  And then, will re-submit the series as v2 once
dpdk-18.02 gets released.

Thanks,
Rahul

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 0/7] cxgbe: bug fixes and updates
  2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                   ` (6 preceding siblings ...)
  2018-02-04  6:06 ` [PATCH 7/7] cxgbe: rework and use " Rahul Lakkireddy
@ 2018-02-28 18:04 ` Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 1/7] cxgbe: rework rte_eth_dev allocation Rahul Lakkireddy
                     ` (7 more replies)
  7 siblings, 8 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

Patch 1 reworks rte_eth_dev allocation for other ports under same PF.

Patch 2 fixes secondary process initialization failure.

Patches 3 and 4 allow configuring RSS hash and key.

Patch 5 updates link Forward Error Correction (FEC) to support IEEE
802.3 standard based FEC selection.

Patches 6 and 7 update to new firmware 32-bit port capabilities to
support more link speeds and module types.

Thanks,
Rahul

---
v2:
- Patch 2 regarding link update from v1 has been dropped.
- Split rte_eth_dev allocation rework for other ports under same PF
to patch 1.
- Split secondary process fix to patch 2.

Kumar Sanghvi (4):
  cxgbe: fix secondary process initialization
  cxgbe: add support to update RSS hash configuration and key
  cxgbe: add support to get programmed RSS hash configuration and key
  cxgbe: update link Forward Error Correction (FEC)

Rahul Lakkireddy (3):
  cxgbe: rework rte_eth_dev allocation
  cxgbe: update link configuration for 32-bit port capability
  cxgbe: rework and use 32-bit port capability

 doc/guides/nics/cxgbe.rst               |  12 +-
 doc/guides/nics/features/cxgbe.ini      |   2 +
 doc/guides/rel_notes/release_18_05.rst  |   4 +
 drivers/net/cxgbe/base/adapter.h        |  33 +-
 drivers/net/cxgbe/base/common.h         |  57 ++-
 drivers/net/cxgbe/base/t4_hw.c          | 674 ++++++++++++++++++++++++++------
 drivers/net/cxgbe/base/t4_regs.h        |  25 ++
 drivers/net/cxgbe/base/t4fw_interface.h | 172 +++++++-
 drivers/net/cxgbe/cxgbe.h               |   2 +
 drivers/net/cxgbe/cxgbe_ethdev.c        | 116 +++++-
 drivers/net/cxgbe/cxgbe_main.c          | 160 +++++---
 drivers/net/cxgbe/sge.c                 |   5 +-
 12 files changed, 1037 insertions(+), 225 deletions(-)

-- 
2.14.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 1/7] cxgbe: rework rte_eth_dev allocation
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
@ 2018-02-28 18:04   ` Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 2/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

Rework rte_eth_dev allocation for other ports under same PF.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
---
v2:
- Split rte_eth_dev allocation rework from patch 1.

 drivers/net/cxgbe/base/adapter.h | 28 ++++++++++-----------
 drivers/net/cxgbe/cxgbe_main.c   | 53 +++++++++++++++++++++++-----------------
 2 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index f2057af14..d96499987 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -308,7 +308,7 @@ struct adapter {
 	struct rte_pci_device *pdev;       /* associated rte pci device */
 	struct rte_eth_dev *eth_dev;       /* first port's rte eth device */
 	struct adapter_params params;      /* adapter parameters */
-	struct port_info port[MAX_NPORTS]; /* ports belonging to this adapter */
+	struct port_info *port[MAX_NPORTS];/* ports belonging to this adapter */
 	struct sge sge;                    /* associated SGE */
 
 	/* support for single-threading access to adapter mailbox registers */
@@ -327,6 +327,18 @@ struct adapter {
 	int use_unpacked_mode; /* unpacked rx mode state */
 };
 
+/**
+ * adap2pinfo - return the port_info of a port
+ * @adap: the adapter
+ * @idx: the port index
+ *
+ * Return the port_info structure for the port of the given index.
+ */
+static inline struct port_info *adap2pinfo(const struct adapter *adap, int idx)
+{
+	return adap->port[idx];
+}
+
 #define CXGBE_PCI_REG(reg) rte_read32(reg)
 
 static inline uint64_t cxgbe_read_addr64(volatile void *addr)
@@ -602,7 +614,7 @@ static inline int t4_os_find_pci_capability(struct adapter *adapter, int cap)
 static inline void t4_os_set_hw_addr(struct adapter *adapter, int port_idx,
 				     u8 hw_addr[])
 {
-	struct port_info *pi = &adapter->port[port_idx];
+	struct port_info *pi = adap2pinfo(adapter, port_idx);
 
 	ether_addr_copy((struct ether_addr *)hw_addr,
 			&pi->eth_dev->data->mac_addrs[0]);
@@ -687,18 +699,6 @@ static inline void t4_os_atomic_list_del(struct mbox_entry *entry,
 	t4_os_unlock(lock);
 }
 
-/**
- * adap2pinfo - return the port_info of a port
- * @adap: the adapter
- * @idx: the port index
- *
- * Return the port_info structure for the port of the given index.
- */
-static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
-{
-	return &adap->port[idx];
-}
-
 void *t4_alloc_mem(size_t size);
 void t4_free_mem(void *addr);
 #define t4_os_alloc(_size)     t4_alloc_mem((_size))
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 28db6c061..553834749 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -382,7 +382,7 @@ static void print_port_info(struct adapter *adap)
 	struct rte_pci_addr *loc = &adap->pdev->addr;
 
 	for_each_port(adap, i) {
-		const struct port_info *pi = &adap->port[i];
+		const struct port_info *pi = adap2pinfo(adap, i);
 		char *bufp = buf;
 
 		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M)
@@ -860,7 +860,7 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id)
 		NULL, "LR", "SR", "ER", "passive DA", "active DA", "LRM"
 	};
 
-	const struct port_info *pi = &adap->port[port_id];
+	const struct port_info *pi = adap2pinfo(adap, port_id);
 
 	if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
 		dev_info(adap, "Port%d: port module unplugged\n", pi->port_id);
@@ -1190,6 +1190,11 @@ void cxgbe_close(struct adapter *adapter)
 				t4_free_vi(adapter, adapter->mbox,
 					   adapter->pf, 0, pi->viid);
 			rte_free(pi->eth_dev->data->mac_addrs);
+			/* Skip first port since it'll be freed by DPDK stack */
+			if (!i) {
+				rte_free(pi->eth_dev->data->dev_private);
+				rte_eth_dev_release_port(pi->eth_dev);
+			}
 		}
 		adapter->flags &= ~FULL_INIT_DONE;
 	}
@@ -1265,21 +1270,16 @@ int cxgbe_probe(struct adapter *adapter)
 	}
 
 	for_each_port(adapter, i) {
-		char name[RTE_ETH_NAME_MAX_LEN];
-		struct rte_eth_dev_data *data = NULL;
 		const unsigned int numa_node = rte_socket_id();
+		char name[RTE_ETH_NAME_MAX_LEN];
+		struct rte_eth_dev *eth_dev;
 
-		pi = &adapter->port[i];
-		pi->adapter = adapter;
-		pi->xact_addr_filt = -1;
-		pi->port_id = i;
-
-		snprintf(name, sizeof(name), "cxgbe%d",
-			 adapter->eth_dev->data->port_id + i);
+		snprintf(name, sizeof(name), "%s_%d",
+			 adapter->pdev->device.name, i);
 
 		if (i == 0) {
 			/* First port is already allocated by DPDK */
-			pi->eth_dev = adapter->eth_dev;
+			eth_dev = adapter->eth_dev;
 			goto allocate_mac;
 		}
 
@@ -1289,21 +1289,25 @@ int cxgbe_probe(struct adapter *adapter)
 		 */
 
 		/* reserve an ethdev entry */
-		pi->eth_dev = rte_eth_dev_allocate(name);
-		if (!pi->eth_dev)
+		eth_dev = rte_eth_dev_allocate(name);
+		if (!eth_dev)
 			goto out_free;
 
-		data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-		if (!data)
+		eth_dev->data->dev_private =
+			rte_zmalloc_socket(name, sizeof(struct port_info),
+					   RTE_CACHE_LINE_SIZE, numa_node);
+		if (!eth_dev->data->dev_private)
 			goto out_free;
 
-		data->port_id = adapter->eth_dev->data->port_id + i;
-
-		pi->eth_dev->data = data;
-
 allocate_mac:
+		pi = (struct port_info *)eth_dev->data->dev_private;
+		adapter->port[i] = pi;
+		pi->eth_dev = eth_dev;
+		pi->adapter = adapter;
+		pi->xact_addr_filt = -1;
+		pi->port_id = i;
+
 		pi->eth_dev->device = &adapter->pdev->device;
-		pi->eth_dev->data->dev_private = pi;
 		pi->eth_dev->dev_ops = adapter->eth_dev->dev_ops;
 		pi->eth_dev->tx_pkt_burst = adapter->eth_dev->tx_pkt_burst;
 		pi->eth_dev->rx_pkt_burst = adapter->eth_dev->rx_pkt_burst;
@@ -1349,8 +1353,11 @@ int cxgbe_probe(struct adapter *adapter)
 		/* Skip first port since it'll be de-allocated by DPDK */
 		if (i == 0)
 			continue;
-		if (pi->eth_dev->data)
-			rte_free(pi->eth_dev->data);
+		if (pi->eth_dev) {
+			if (pi->eth_dev->data->dev_private)
+				rte_free(pi->eth_dev->data->dev_private);
+			rte_eth_dev_release_port(pi->eth_dev);
+		}
 	}
 
 	if (adapter->flags & FW_OK)
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v2 2/7] cxgbe: fix secondary process initialization
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 1/7] cxgbe: rework rte_eth_dev allocation Rahul Lakkireddy
@ 2018-02-28 18:04   ` Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Attach to rte_eth_dev devices allocated by Primary process for
Ports other than Port-0 in the secondary process.

Save the Primary rte_eth_dev device eth_dev_data as part of txq
structure needed for tx path.

Fixes: 8318984927ff ("cxgbe: add pmd skeleton")
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- Moved rte_eth_dev allocation rework to patch 1.
- Fixed passing wrong device name to rte_eth_dev_attach_secondary().

 doc/guides/nics/features/cxgbe.ini |  1 +
 drivers/net/cxgbe/base/adapter.h   |  1 +
 drivers/net/cxgbe/cxgbe_ethdev.c   | 29 ++++++++++++++++++++++++-----
 drivers/net/cxgbe/sge.c            |  5 +++--
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/doc/guides/nics/features/cxgbe.ini b/doc/guides/nics/features/cxgbe.ini
index 3d0fde2fd..1b9d81ffb 100644
--- a/doc/guides/nics/features/cxgbe.ini
+++ b/doc/guides/nics/features/cxgbe.ini
@@ -24,6 +24,7 @@ Basic stats          = Y
 Stats per queue      = Y
 EEPROM dump          = Y
 Registers dump       = Y
+Multiprocess aware   = Y
 BSD nic_uio          = Y
 Linux UIO            = Y
 Linux VFIO           = Y
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index d96499987..e93c1bf73 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -267,6 +267,7 @@ struct sge_eth_tx_stats {	/* Ethernet tx queue statistics */
 struct sge_eth_txq {                   /* state for an SGE Ethernet Tx queue */
 	struct sge_txq q;
 	struct rte_eth_dev *eth_dev;   /* port that this queue belongs to */
+	struct rte_eth_dev_data *data;
 	struct sge_eth_tx_stats stats; /* queue statistics */
 	rte_spinlock_t txq_lock;
 
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 5cd260f48..423a6957b 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1004,14 +1004,33 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->dev_ops = &cxgbe_eth_dev_ops;
 	eth_dev->rx_pkt_burst = &cxgbe_recv_pkts;
 	eth_dev->tx_pkt_burst = &cxgbe_xmit_pkts;
+	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
 
-	/* for secondary processes, we don't initialise any further as primary
-	 * has already done this work.
+	/* for secondary processes, we attach to ethdevs allocated by primary
+	 * and do minimal initialization.
 	 */
-	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+		int i;
+
+		for (i = 1; i < MAX_NPORTS; i++) {
+			struct rte_eth_dev *rest_eth_dev;
+			char namei[RTE_ETH_NAME_MAX_LEN];
+
+			snprintf(namei, sizeof(namei), "%s_%d",
+				 pci_dev->device.name, i);
+			rest_eth_dev = rte_eth_dev_attach_secondary(namei);
+			if (rest_eth_dev) {
+				rest_eth_dev->device = &pci_dev->device;
+				rest_eth_dev->dev_ops =
+					eth_dev->dev_ops;
+				rest_eth_dev->rx_pkt_burst =
+					eth_dev->rx_pkt_burst;
+				rest_eth_dev->tx_pkt_burst =
+					eth_dev->tx_pkt_burst;
+			}
+		}
 		return 0;
-
-	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	}
 
 	snprintf(name, sizeof(name), "cxgbeadapter%d", eth_dev->data->port_id);
 	adapter = rte_zmalloc(name, sizeof(*adapter), 0);
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 3d5aa596f..6ff8bc46b 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1095,7 +1095,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
 	u32 wr_mid;
 	u64 cntrl, *end;
 	bool v6;
-	u32 max_pkt_len = txq->eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
+	u32 max_pkt_len = txq->data->dev_conf.rxmode.max_rx_pkt_len;
 
 	/* Reject xmit if queue is stopped */
 	if (unlikely(txq->flags & EQ_STOPPED))
@@ -1115,7 +1115,7 @@ int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
 	    (unlikely(m->pkt_len > max_pkt_len)))
 		goto out_free;
 
-	pi = (struct port_info *)txq->eth_dev->data->dev_private;
+	pi = (struct port_info *)txq->data->dev_private;
 	adap = pi->adapter;
 
 	cntrl = F_TXPKT_L4CSUM_DIS | F_TXPKT_IPCSUM_DIS;
@@ -1997,6 +1997,7 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
 	txq->stats.mapping_err = 0;
 	txq->flags |= EQ_STOPPED;
 	txq->eth_dev = eth_dev;
+	txq->data = eth_dev->data;
 	t4_os_lock_init(&txq->txq_lock);
 	return 0;
 }
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v2 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 1/7] cxgbe: rework rte_eth_dev allocation Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 2/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
@ 2018-02-28 18:04   ` Rahul Lakkireddy
  2018-03-08 13:34     ` Ferruh Yigit
  2018-02-28 18:04   ` [PATCH v2 4/7] cxgbe: add support to get programmed " Rahul Lakkireddy
                     ` (4 subsequent siblings)
  7 siblings, 1 reply; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Add firmware API for updating RSS hash configuration and key.  Move
RSS hash configuration from cxgb4_write_rss() to a separate function
cxgbe_write_rss_conf().

Also, rename cxgb4_write_rss() to cxgbe_write_rss() for consistency.

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 doc/guides/nics/cxgbe.rst               |  2 +
 doc/guides/nics/features/cxgbe.ini      |  1 +
 doc/guides/rel_notes/release_18_05.rst  |  4 ++
 drivers/net/cxgbe/base/adapter.h        |  4 +-
 drivers/net/cxgbe/base/common.h         |  3 ++
 drivers/net/cxgbe/base/t4_hw.c          | 73 +++++++++++++++++++++++++++
 drivers/net/cxgbe/base/t4_regs.h        | 25 +++++++++
 drivers/net/cxgbe/base/t4fw_interface.h | 89 +++++++++++++++++++++++++++++++++
 drivers/net/cxgbe/cxgbe.h               |  2 +
 drivers/net/cxgbe/cxgbe_ethdev.c        | 32 ++++++++++++
 drivers/net/cxgbe/cxgbe_main.c          | 79 ++++++++++++++++++++++-------
 11 files changed, 296 insertions(+), 18 deletions(-)

diff --git a/doc/guides/nics/cxgbe.rst b/doc/guides/nics/cxgbe.rst
index 8651a7be6..6126167c5 100644
--- a/doc/guides/nics/cxgbe.rst
+++ b/doc/guides/nics/cxgbe.rst
@@ -45,6 +45,8 @@ CXGBE PMD has support for:
 
 - Multiple queues for TX and RX
 - Receiver Side Steering (RSS)
+  Receiver Side Steering (RSS) on IPv4, IPv6, IPv4-TCP/UDP, IPv6-TCP/UDP.
+  For 4-tuple, enabling 'RSS on TCP' and 'RSS on TCP + UDP' is supported.
 - VLAN filtering
 - Checksum offload
 - Promiscuous mode
diff --git a/doc/guides/nics/features/cxgbe.ini b/doc/guides/nics/features/cxgbe.ini
index 1b9d81ffb..6cf5c13f5 100644
--- a/doc/guides/nics/features/cxgbe.ini
+++ b/doc/guides/nics/features/cxgbe.ini
@@ -14,6 +14,7 @@ TSO                  = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 RSS hash             = Y
+RSS key update       = Y
 Flow control         = Y
 CRC offload          = Y
 VLAN offload         = Y
diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst
index 3923dc253..fcc462349 100644
--- a/doc/guides/rel_notes/release_18_05.rst
+++ b/doc/guides/rel_notes/release_18_05.rst
@@ -41,6 +41,10 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Added RSS hash and key update to CXGBE PMD.**
+
+  Support to update RSS hash and key has been added to CXGBE PMD.
+
 
 API Changes
 -----------
diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index e93c1bf73..169402836 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -77,6 +77,7 @@ struct port_info {
 	u16    *rss;                    /* rss table */
 	u8     rss_mode;                /* rss mode */
 	u16    rss_size;                /* size of VI's RSS table slice */
+	u64    rss_hf;			/* RSS Hash Function */
 };
 
 /* Enable or disable autonegotiation.  If this is set to enable,
@@ -736,6 +737,7 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us,
 			       unsigned int cnt);
 int cxgbe_poll(struct sge_rspq *q, struct rte_mbuf **rx_pkts,
 	       unsigned int budget, unsigned int *work_done);
-int cxgb4_write_rss(const struct port_info *pi, const u16 *queues);
+int cxgbe_write_rss(const struct port_info *pi, const u16 *queues);
+int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t flags);
 
 #endif /* __T4_ADAPTER_H__ */
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 1eda57d09..5301f7474 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -410,6 +410,9 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
 			int start, int n, const u16 *rspq, unsigned int nrspq);
 int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 		     unsigned int flags, unsigned int defq);
+void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
+		     unsigned int start_index, unsigned int rw);
+void t4_write_rss_key(struct adapter *adap, u32 *key, int idx);
 
 enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS };
 int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid,
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 56f38c838..9eb83fd5e 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2166,6 +2166,79 @@ int t4_seeprom_wp(struct adapter *adapter, int enable)
 	return t4_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 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
+ */
+void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
+		     unsigned int start_index, unsigned int rw)
+{
+	int cmd = FW_LDST_ADDRSPC_TP_PIO;
+	struct fw_ldst_cmd c;
+	unsigned int i;
+	int ret;
+
+	for (i = 0 ; i < nregs; i++) {
+		memset(&c, 0, sizeof(c));
+		c.op_to_addrspace = cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) |
+						F_FW_CMD_REQUEST |
+						(rw ? F_FW_CMD_READ :
+						      F_FW_CMD_WRITE) |
+						V_FW_LDST_CMD_ADDRSPACE(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 == 0) {
+			if (rw)
+				vals[i] = be32_to_cpu(c.u.addrval.val);
+		}
+	}
+}
+
+/**
+ * t4_write_rss_key - program one of the RSS keys
+ * @adap: the adapter
+ * @key: 10-entry array holding the 320-bit RSS key
+ * @idx: which RSS key to write
+ *
+ * Writes one of the RSS keys with the given 320-bit value.  If @idx is
+ * 0..15 the corresponding entry in the RSS key table is written,
+ * otherwise the global RSS key is written.
+ */
+void t4_write_rss_key(struct adapter *adap, u32 *key, int idx)
+{
+	u32 vrt = t4_read_reg(adap, A_TP_RSS_CONFIG_VRT);
+	u8 rss_key_addr_cnt = 16;
+
+	/* T6 and later: for KeyMode 3 (per-vf and per-vf scramble),
+	 * allows access to key addresses 16-63 by using KeyWrAddrX
+	 * as index[5:4](upper 2) into key table
+	 */
+	if ((CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) &&
+	    (vrt & F_KEYEXTEND) && (G_KEYMODE(vrt) == 3))
+		rss_key_addr_cnt = 32;
+
+	t4_fw_tp_pio_rw(adap, key, 10, A_TP_RSS_SECRET_KEY0, 0);
+
+	if (idx >= 0 && idx < rss_key_addr_cnt) {
+		if (rss_key_addr_cnt > 16)
+			t4_write_reg(adap, A_TP_RSS_CONFIG_VRT,
+				     V_KEYWRADDRX(idx >> 4) |
+				     V_T6_VFWRADDR(idx) | F_KEYWREN);
+		else
+			t4_write_reg(adap, A_TP_RSS_CONFIG_VRT,
+				     V_KEYWRADDR(idx) | F_KEYWREN);
+	}
+}
+
 /**
  * t4_config_rss_range - configure a portion of the RSS mapping table
  * @adapter: the adapter
diff --git a/drivers/net/cxgbe/base/t4_regs.h b/drivers/net/cxgbe/base/t4_regs.h
index 1100e16fe..0f0bca910 100644
--- a/drivers/net/cxgbe/base/t4_regs.h
+++ b/drivers/net/cxgbe/base/t4_regs.h
@@ -503,9 +503,34 @@
 #define V_MTUVALUE(x) ((x) << S_MTUVALUE)
 #define G_MTUVALUE(x) (((x) >> S_MTUVALUE) & M_MTUVALUE)
 
+#define A_TP_RSS_CONFIG_VRT 0x7e00
+
+#define S_KEYMODE    6
+#define M_KEYMODE    0x3U
+#define G_KEYMODE(x) (((x) >> S_KEYMODE) & M_KEYMODE)
+
+#define S_KEYWRADDR    0
+#define V_KEYWRADDR(x) ((x) << S_KEYWRADDR)
+
+#define S_KEYWREN    4
+#define V_KEYWREN(x) ((x) << S_KEYWREN)
+#define F_KEYWREN    V_KEYWREN(1U)
+
+#define S_KEYWRADDRX    30
+#define V_KEYWRADDRX(x) ((x) << S_KEYWRADDRX)
+
+#define S_KEYEXTEND    26
+#define V_KEYEXTEND(x) ((x) << S_KEYEXTEND)
+#define F_KEYEXTEND    V_KEYEXTEND(1U)
+
+#define S_T6_VFWRADDR    8
+#define V_T6_VFWRADDR(x) ((x) << S_T6_VFWRADDR)
+
 #define A_TP_PIO_ADDR 0x7e40
 #define A_TP_PIO_DATA 0x7e44
 
+#define A_TP_RSS_SECRET_KEY0 0x40
+
 #define A_TP_VLAN_PRI_MAP 0x140
 
 #define S_FRAGMENTATION    9
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 6ca4f3188..883a1c7f5 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -171,6 +171,7 @@ struct fw_eth_tx_pkts_wr {
 #define FW_CMD_HELLO_RETRIES	3
 
 enum fw_cmd_opcodes {
+	FW_LDST_CMD		       = 0x01,
 	FW_RESET_CMD                   = 0x03,
 	FW_HELLO_CMD                   = 0x04,
 	FW_BYE_CMD                     = 0x05,
@@ -238,6 +239,94 @@ struct fw_cmd_hdr {
 
 #define FW_LEN16(fw_struct) V_FW_CMD_LEN16(sizeof(fw_struct) / 16)
 
+/* address spaces
+ */
+enum fw_ldst_addrspc {
+	FW_LDST_ADDRSPC_TP_PIO    = 0x0010,
+};
+
+struct fw_ldst_cmd {
+	__be32 op_to_addrspace;
+	__be32 cycles_to_len16;
+	union fw_ldst {
+		struct fw_ldst_addrval {
+			__be32 addr;
+			__be32 val;
+		} addrval;
+		struct fw_ldst_idctxt {
+			__be32 physid;
+			__be32 msg_ctxtflush;
+			__be32 ctxt_data7;
+			__be32 ctxt_data6;
+			__be32 ctxt_data5;
+			__be32 ctxt_data4;
+			__be32 ctxt_data3;
+			__be32 ctxt_data2;
+			__be32 ctxt_data1;
+			__be32 ctxt_data0;
+		} idctxt;
+		struct fw_ldst_mdio {
+			__be16 paddr_mmd;
+			__be16 raddr;
+			__be16 vctl;
+			__be16 rval;
+		} mdio;
+		struct fw_ldst_mps {
+			__be16 fid_ctl;
+			__be16 rplcpf_pkd;
+			__be32 rplc127_96;
+			__be32 rplc95_64;
+			__be32 rplc63_32;
+			__be32 rplc31_0;
+			__be32 atrb;
+			__be16 vlan[16];
+		} mps;
+		struct fw_ldst_func {
+			__u8   access_ctl;
+			__u8   mod_index;
+			__be16 ctl_id;
+			__be32 offset;
+			__be64 data0;
+			__be64 data1;
+		} func;
+		struct fw_ldst_pcie {
+			__u8   ctrl_to_fn;
+			__u8   bnum;
+			__u8   r;
+			__u8   ext_r;
+			__u8   select_naccess;
+			__u8   pcie_fn;
+			__be16 nset_pkd;
+			__be32 data[12];
+		} pcie;
+		struct fw_ldst_i2c_deprecated {
+			__u8   pid_pkd;
+			__u8   base;
+			__u8   boffset;
+			__u8   data;
+			__be32 r9;
+		} i2c_deprecated;
+		struct fw_ldst_i2c {
+			__u8   pid;
+			__u8   did;
+			__u8   boffset;
+			__u8   blen;
+			__be32 r9;
+			__u8   data[48];
+		} i2c;
+		struct fw_ldst_le {
+			__be32 index;
+			__be32 r9;
+			__u8   val[33];
+			__u8   r11[7];
+		} le;
+	} u;
+};
+
+#define S_FW_LDST_CMD_ADDRSPACE         0
+#define M_FW_LDST_CMD_ADDRSPACE         0xff
+#define V_FW_LDST_CMD_ADDRSPACE(x)      ((x) << S_FW_LDST_CMD_ADDRSPACE)
+
 struct fw_reset_cmd {
 	__be32 op_to_write;
 	__be32 retval_len16;
diff --git a/drivers/net/cxgbe/cxgbe.h b/drivers/net/cxgbe/cxgbe.h
index f98915455..489e09dda 100644
--- a/drivers/net/cxgbe/cxgbe.h
+++ b/drivers/net/cxgbe/cxgbe.h
@@ -46,6 +46,8 @@
 #define CXGBE_MIN_RX_BUFSIZE ETHER_MIN_MTU /* min buf size */
 #define CXGBE_MAX_RX_PKTLEN (9000 + ETHER_HDR_LEN + ETHER_CRC_LEN) /* max pkt */
 
+#define CXGBE_DEFAULT_RSS_KEY_LEN     40 /* 320-bits */
+
 int cxgbe_probe(struct adapter *adapter);
 void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps);
 int cxgbe_up(struct adapter *adap);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 423a6957b..a96ebc5e7 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -171,6 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 				       DEV_TX_OFFLOAD_TCP_TSO;
 
 	device_info->reta_size = pi->rss_size;
+	device_info->hash_key_size = CXGBE_DEFAULT_RSS_KEY_LEN;
 
 	device_info->rx_desc_lim = cxgbe_desc_lim;
 	device_info->tx_desc_lim = cxgbe_desc_lim;
@@ -787,6 +788,36 @@ cxgbe_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev)
 	return NULL;
 }
 
+/* Update RSS hash configuration
+ */
+static int cxgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
+				     struct rte_eth_rss_conf *rss_conf)
+{
+	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
+	struct adapter *adapter = pi->adapter;
+	int err;
+
+	err = cxgbe_write_rss_conf(pi, rss_conf->rss_hf);
+	if (err)
+		return err;
+
+	pi->rss_hf = rss_conf->rss_hf;
+
+	if (rss_conf->rss_key) {
+		u32 key[10], mod_key[10];
+		int i, j;
+
+		memcpy(key, rss_conf->rss_key, CXGBE_DEFAULT_RSS_KEY_LEN);
+
+		for (i = 9, j = 0; i >= 0; i--, j++)
+			mod_key[j] = cpu_to_be32(key[i]);
+
+		t4_write_rss_key(adapter, mod_key, -1);
+	}
+
+	return 0;
+}
+
 static int cxgbe_get_eeprom_length(struct rte_eth_dev *dev)
 {
 	RTE_SET_USED(dev);
@@ -985,6 +1016,7 @@ static const struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.get_eeprom		= cxgbe_get_eeprom,
 	.set_eeprom		= cxgbe_set_eeprom,
 	.get_reg		= cxgbe_get_regs,
+	.rss_hash_update	= cxgbe_dev_rss_hash_update,
 };
 
 /*
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 553834749..2ee0698c3 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -360,6 +360,8 @@ static int init_rss(struct adapter *adap)
 		pi->rss = rte_zmalloc(NULL, pi->rss_size * sizeof(u16), 0);
 		if (!pi->rss)
 			return -ENOMEM;
+
+		pi->rss_hf = ETH_RSS_TCP | ETH_RSS_UDP;
 	}
 	return 0;
 }
@@ -930,14 +932,67 @@ int link_start(struct port_info *pi)
 }
 
 /**
- * cxgb4_write_rss - write the RSS table for a given port
+ * cxgbe_write_rss_conf - flash the RSS configuration for a given port
+ * @pi: the port
+ * @rss_hf: Hash configuration to apply
+ */
+int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t rss_hf)
+{
+	struct adapter *adapter = pi->adapter;
+	const struct sge_eth_rxq *rxq;
+	u64 flags = 0;
+	u16 rss;
+	int err;
+
+	/*  Should never be called before setting up sge eth rx queues */
+	if (!(adapter->flags & FULL_INIT_DONE)) {
+		dev_err(adap, "%s No RXQs available on port %d\n",
+			__func__, pi->port_id);
+		return -EINVAL;
+	}
+
+	if (rss_hf & ETH_RSS_IPV4)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN |
+			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
+
+	if (rss_hf & ETH_RSS_IPV6)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN;
+
+	if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
+		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
+			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
+
+	rxq = &adapter->sge.ethrxq[pi->first_qset];
+	rss = rxq[0].rspq.abs_id;
+
+	/* If Tunnel All Lookup isn't specified in the global RSS
+	 * Configuration, then we need to specify a default Ingress
+	 * Queue for any ingress packets which aren't hashed.  We'll
+	 * use our first ingress queue ...
+	 */
+	err = t4_config_vi_rss(adapter, adapter->mbox, pi->viid,
+			       flags, rss);
+	return err;
+}
+
+/**
+ * cxgbe_write_rss - write the RSS table for a given port
  * @pi: the port
  * @queues: array of queue indices for RSS
  *
  * Sets up the portion of the HW RSS table for the port's VI to distribute
  * packets to the Rx queues in @queues.
  */
-int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
+int cxgbe_write_rss(const struct port_info *pi, const u16 *queues)
 {
 	u16 *rss;
 	int i, err;
@@ -958,20 +1013,6 @@ int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
 
 	err = t4_config_rss_range(adapter, adapter->pf, pi->viid, 0,
 				  pi->rss_size, rss, pi->rss_size);
-	/*
-	 * If Tunnel All Lookup isn't specified in the global RSS
-	 * Configuration, then we need to specify a default Ingress
-	 * Queue for any ingress packets which aren't hashed.  We'll
-	 * use our first ingress queue ...
-	 */
-	if (!err)
-		err = t4_config_vi_rss(adapter, adapter->mbox, pi->viid,
-				       F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN |
-				       F_FW_RSS_VI_CONFIG_CMD_UDPEN,
-				       rss[0]);
 	rte_free(rss);
 	return err;
 }
@@ -1001,7 +1042,11 @@ int setup_rss(struct port_info *pi)
 			for (j = 0; j < pi->rss_size; j++)
 				pi->rss[j] = j % pi->n_rx_qsets;
 
-			err = cxgb4_write_rss(pi, pi->rss);
+			err = cxgbe_write_rss(pi, pi->rss);
+			if (err)
+				return err;
+
+			err = cxgbe_write_rss_conf(pi, pi->rss_hf);
 			if (err)
 				return err;
 			pi->flags |= PORT_RSS_DONE;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v2 4/7] cxgbe: add support to get programmed RSS hash configuration and key
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                     ` (2 preceding siblings ...)
  2018-02-28 18:04   ` [PATCH v2 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
@ 2018-02-28 18:04   ` Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 5/7] cxgbe: update link Forward Error Correction (FEC) Rahul Lakkireddy
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/base/common.h  |  3 +++
 drivers/net/cxgbe/base/t4_hw.c   | 46 ++++++++++++++++++++++++++++++++++
 drivers/net/cxgbe/cxgbe_ethdev.c | 53 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 5301f7474..dd282a933 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -410,9 +410,12 @@ int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
 			int start, int n, const u16 *rspq, unsigned int nrspq);
 int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 		     unsigned int flags, unsigned int defq);
+int t4_read_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
+			  u64 *flags, unsigned int *defq);
 void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
 		     unsigned int start_index, unsigned int rw);
 void t4_write_rss_key(struct adapter *adap, u32 *key, int idx);
+void t4_read_rss_key(struct adapter *adap, u32 *key);
 
 enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS };
 int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid,
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 9eb83fd5e..2d7214622 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2203,6 +2203,18 @@ void t4_fw_tp_pio_rw(struct adapter *adap, u32 *vals, unsigned int nregs,
 	}
 }
 
+/**
+ * t4_read_rss_key - read the global RSS key
+ * @adap: the adapter
+ * @key: 10-entry array holding the 320-bit RSS key
+ *
+ * Reads the global 320-bit RSS key.
+ */
+void t4_read_rss_key(struct adapter *adap, u32 *key)
+{
+	t4_fw_tp_pio_rw(adap, key, 10, A_TP_RSS_SECRET_KEY0, 1);
+}
+
 /**
  * t4_write_rss_key - program one of the RSS keys
  * @adap: the adapter
@@ -2363,6 +2375,40 @@ int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
 	return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
 }
 
+/**
+ * t4_read_config_vi_rss - read the configured per VI RSS settings
+ * @adapter: the adapter
+ * @mbox: mbox to use for the FW command
+ * @viid: the VI id
+ * @flags: where to place the configured flags
+ * @defq: where to place the id of the default RSS queue for the VI.
+ *
+ * Read configured VI-specific RSS properties.
+ */
+int t4_read_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
+			  u64 *flags, unsigned int *defq)
+{
+	struct fw_rss_vi_config_cmd c;
+	unsigned int result;
+	int ret;
+
+	memset(&c, 0, sizeof(c));
+	c.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) |
+				   F_FW_CMD_REQUEST | F_FW_CMD_READ |
+				   V_FW_RSS_VI_CONFIG_CMD_VIID(viid));
+	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
+	ret = t4_wr_mbox(adapter, mbox, &c, sizeof(c), &c);
+	if (!ret) {
+		result = be32_to_cpu(c.u.basicvirtual.defaultq_to_udpen);
+		if (defq)
+			*defq = G_FW_RSS_VI_CONFIG_CMD_DEFAULTQ(result);
+		if (flags)
+			*flags = result & M_FW_RSS_VI_CONFIG_CMD_DEFAULTQ;
+	}
+
+	return ret;
+}
+
 /**
  * init_cong_ctrl - initialize congestion control parameters
  * @a: the alpha values for congestion control
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index a96ebc5e7..769146cdf 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -818,6 +818,58 @@ static int cxgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* Get RSS hash configuration
+ */
+static int cxgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+				       struct rte_eth_rss_conf *rss_conf)
+{
+	struct port_info *pi = (struct port_info *)(dev->data->dev_private);
+	struct adapter *adapter = pi->adapter;
+	u64 rss_hf = 0;
+	u64 flags = 0;
+	int err;
+
+	err = t4_read_config_vi_rss(adapter, adapter->mbox, pi->viid,
+				    &flags, NULL);
+
+	if (err)
+		return err;
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) {
+		rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+		if (flags & F_FW_RSS_VI_CONFIG_CMD_UDPEN)
+			rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
+	}
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN)
+		rss_hf |= ETH_RSS_IPV6;
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) {
+		rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+		if (flags & F_FW_RSS_VI_CONFIG_CMD_UDPEN)
+			rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
+	}
+
+	if (flags & F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN)
+		rss_hf |= ETH_RSS_IPV4;
+
+	rss_conf->rss_hf = rss_hf;
+
+	if (rss_conf->rss_key) {
+		u32 key[10], mod_key[10];
+		int i, j;
+
+		t4_read_rss_key(adapter, key);
+
+		for (i = 9, j = 0; i >= 0; i--, j++)
+			mod_key[j] = be32_to_cpu(key[i]);
+
+		memcpy(rss_conf->rss_key, mod_key, CXGBE_DEFAULT_RSS_KEY_LEN);
+	}
+
+	return 0;
+}
+
 static int cxgbe_get_eeprom_length(struct rte_eth_dev *dev)
 {
 	RTE_SET_USED(dev);
@@ -1017,6 +1069,7 @@ static const struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.set_eeprom		= cxgbe_set_eeprom,
 	.get_reg		= cxgbe_get_regs,
 	.rss_hash_update	= cxgbe_dev_rss_hash_update,
+	.rss_hash_conf_get	= cxgbe_dev_rss_hash_conf_get,
 };
 
 /*
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v2 5/7] cxgbe: update link Forward Error Correction (FEC)
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                     ` (3 preceding siblings ...)
  2018-02-28 18:04   ` [PATCH v2 4/7] cxgbe: add support to get programmed " Rahul Lakkireddy
@ 2018-02-28 18:04   ` Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 6/7] cxgbe: update link configuration for 32-bit port capability Rahul Lakkireddy
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

From: Kumar Sanghvi <kumaras@chelsio.com>

Normally, firmware reads various Forward Error Correction parameters
from a Transceiver Module i2c EPROM and uses a couple of IEEE Standards
(802.3bj for 100Gb/s and 802.3by for 25Gb/s) to interpret those
parameters and come up with supported and default FEC settings.
Firmware then sends these FEC parameters to the Host Driver which gives
the Host Administrator an opportunity to change them if necessary in
order to establish a Link with a Switch which may have made a
non-standard FEC decision.

This commit recognizes "auto" as a discrete FEC mode which can be
used to explicitly select the IEEE 802.3 standard based FEC selection.

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/base/common.h |  13 +++--
 drivers/net/cxgbe/base/t4_hw.c  | 123 ++++++++++++++++++++++++++++------------
 2 files changed, 94 insertions(+), 42 deletions(-)

diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index dd282a933..0bd78c1b0 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -69,9 +69,9 @@ enum {
 };
 
 enum {
-	FEC_RS        = 1 << 0,
-	FEC_BASER_RS  = 1 << 1,
-	FEC_RESERVED  = 1 << 2,
+	FEC_AUTO     = 1 << 0,    /* IEEE 802.3 "automatic" */
+	FEC_RS       = 1 << 1,    /* Reed-Solomon */
+	FEC_BASER_RS = 1 << 2,    /* BaseR/Reed-Solomon */
 };
 
 struct port_stats {
@@ -248,8 +248,11 @@ struct link_config {
 	unsigned int   speed;            /* actual link speed */
 	unsigned char  requested_fc;     /* flow control user has requested */
 	unsigned char  fc;               /* actual link flow control */
-	unsigned char  requested_fec;    /* Forward Error Correction user */
-	unsigned char  fec;              /* has requested and actual FEC */
+	unsigned char  auto_fec;         /* Forward Error Correction (FEC)
+					  * "automatic" (IEEE 802.3)
+					  */
+	unsigned char  requested_fec;    /* FEC requested */
+	unsigned char  fec;              /* FEC actual */
 	unsigned char  autoneg;          /* autonegotiating? */
 	unsigned char  link_ok;          /* link up? */
 };
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 2d7214622..e8545ceb0 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2792,6 +2792,58 @@ void t4_dump_version_info(struct adapter *adapter)
 #define ADVERT_MASK (V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED) | \
 		     FW_PORT_CAP_ANEG)
 
+/* Translate Firmware Pause specification to Common Code */
+static inline unsigned int fwcap_to_cc_pause(unsigned int fw_pause)
+{
+	unsigned int cc_pause = 0;
+
+	if (fw_pause & F_FW_PORT_CMD_RXPAUSE)
+		cc_pause |= PAUSE_RX;
+	if (fw_pause & F_FW_PORT_CMD_TXPAUSE)
+		cc_pause |= PAUSE_TX;
+
+	return cc_pause;
+}
+
+/* Translate Common Code Pause Frame specification into Firmware */
+static inline unsigned int cc_to_fwcap_pause(unsigned int cc_pause)
+{
+	unsigned int fw_pause = 0;
+
+	if (cc_pause & PAUSE_RX)
+		fw_pause |= F_FW_PORT_CMD_RXPAUSE;
+	if (cc_pause & PAUSE_TX)
+		fw_pause |= F_FW_PORT_CMD_TXPAUSE;
+
+	return fw_pause;
+}
+
+/* Translate Firmware Forward Error Correction specification to Common Code */
+static inline unsigned int fwcap_to_cc_fec(unsigned int fw_fec)
+{
+	unsigned int cc_fec = 0;
+
+	if (fw_fec & FW_PORT_CAP_FEC_RS)
+		cc_fec |= FEC_RS;
+	if (fw_fec & FW_PORT_CAP_FEC_BASER_RS)
+		cc_fec |= FEC_BASER_RS;
+
+	return cc_fec;
+}
+
+/* Translate Common Code Forward Error Correction specification to Firmware */
+static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
+{
+	unsigned int fw_fec = 0;
+
+	if (cc_fec & FEC_RS)
+		fw_fec |= FW_PORT_CAP_FEC_RS;
+	if (cc_fec & FEC_BASER_RS)
+		fw_fec |= FW_PORT_CAP_FEC_BASER_RS;
+
+	return fw_fec;
+}
+
 /**
  * t4_link_l1cfg - apply link configuration to MAC/PHY
  * @phy: the PHY to setup
@@ -2809,23 +2861,25 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc)
 {
 	struct fw_port_cmd c;
-	unsigned int mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO);
-	unsigned int fc, fec;
+	unsigned int fw_mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO);
+	unsigned int fw_fc, cc_fec, fw_fec;
 
 	lc->link_ok = 0;
-	fc = 0;
-	if (lc->requested_fc & PAUSE_RX)
-		fc |= FW_PORT_CAP_FC_RX;
-	if (lc->requested_fc & PAUSE_TX)
-		fc |= FW_PORT_CAP_FC_TX;
-
-	fec = 0;
-	if (lc->requested_fec & FEC_RS)
-		fec |= FW_PORT_CAP_FEC_RS;
-	if (lc->requested_fec & FEC_BASER_RS)
-		fec |= FW_PORT_CAP_FEC_BASER_RS;
-	if (lc->requested_fec & FEC_RESERVED)
-		fec |= FW_PORT_CAP_FEC_RESERVED;
+
+	fw_fc = cc_to_fwcap_pause(lc->requested_fc);
+
+	/* Convert Common Code Forward Error Control settings into the
+	 * Firmware's API.  If the current Requested FEC has "Automatic"
+	 * (IEEE 802.3) specified, then we use whatever the Firmware
+	 * sent us as part of it's IEEE 802.3-based interpratation of
+	 * the Transceiver Module EPROM FEC parameters.  Otherwise we
+	 * use whatever is in the current Requested FEC settings.
+	 */
+	if (lc->requested_fec & FEC_AUTO)
+		cc_fec = lc->auto_fec;
+	else
+		cc_fec = lc->requested_fec;
+	fw_fec = cc_to_fwcap_fec(cc_fec);
 
 	memset(&c, 0, sizeof(c));
 	c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
@@ -2837,16 +2891,17 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 
 	if (!(lc->supported & FW_PORT_CAP_ANEG)) {
 		c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) |
-					     fc | fec);
+					     fw_fc | fw_fec);
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
-		lc->fec = lc->requested_fec;
+		lc->fec = cc_fec;
 	} else if (lc->autoneg == AUTONEG_DISABLE) {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fc |
-					     fec | mdi);
+		c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fw_fc |
+					     fw_fec | fw_mdi);
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
-		lc->fec = lc->requested_fec;
+		lc->fec = cc_fec;
 	} else {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fc | fec | mdi);
+		c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fw_fc | fw_fec |
+					     fw_mdi);
 	}
 
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
@@ -4212,11 +4267,11 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
 		int link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0;
 		u32 mod = G_FW_PORT_CMD_MODTYPE(stat);
+		unsigned int fec;
+
+		fc = fwcap_to_cc_pause(stat);
+		fec = fwcap_to_cc_fec(stat);
 
-		if (stat & F_FW_PORT_CMD_RXPAUSE)
-			fc |= PAUSE_RX;
-		if (stat & F_FW_PORT_CMD_TXPAUSE)
-			fc |= PAUSE_TX;
 		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
 			speed = ETH_SPEED_NUM_100M;
 		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
@@ -4238,11 +4293,12 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 		lc = &pi->link_cfg;
 
 		if (mod != pi->mod_type) {
+			lc->auto_fec = fec;
 			pi->mod_type = mod;
 			t4_os_portmod_changed(adap, i);
 		}
 		if (link_ok != lc->link_ok || speed != lc->speed ||
-		    fc != lc->fc) {                    /* something changed */
+		    fc != lc->fc || fec != lc->fec) { /* something changed */
 			if (!link_ok && lc->link_ok) {
 				static const char * const reason[] = {
 					"Link Down",
@@ -4262,6 +4318,7 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 			lc->link_ok = link_ok;
 			lc->speed = speed;
 			lc->fc = fc;
+			lc->fec = fec;
 			lc->supported = be16_to_cpu(p->u.info.pcap);
 		}
 	} else {
@@ -4295,8 +4352,6 @@ void t4_reset_link_config(struct adapter *adap, int idx)
 static void init_link_config(struct link_config *lc, unsigned int pcaps,
 			     unsigned int acaps)
 {
-	unsigned int fec;
-
 	lc->supported = pcaps;
 	lc->requested_speed = 0;
 	lc->speed = 0;
@@ -4307,15 +4362,9 @@ static void init_link_config(struct link_config *lc, unsigned int pcaps,
 	 * For Forward Error Control, we default to whatever the Firmware
 	 * tells us the Link is currently advertising.
 	 */
-	fec = 0;
-	if (acaps & FW_PORT_CAP_FEC_RS)
-		fec |= FEC_RS;
-	if (acaps & FW_PORT_CAP_FEC_BASER_RS)
-		fec |= FEC_BASER_RS;
-	if (acaps & FW_PORT_CAP_FEC_RESERVED)
-		fec |= FEC_RESERVED;
-	lc->requested_fec = fec;
-	lc->fec = fec;
+	lc->auto_fec = fwcap_to_cc_fec(acaps);
+	lc->requested_fec = FEC_AUTO;
+	lc->fec = lc->auto_fec;
 
 	if (lc->supported & FW_PORT_CAP_ANEG) {
 		lc->advertising = lc->supported & ADVERT_MASK;
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v2 6/7] cxgbe: update link configuration for 32-bit port capability
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                     ` (4 preceding siblings ...)
  2018-02-28 18:04   ` [PATCH v2 5/7] cxgbe: update link Forward Error Correction (FEC) Rahul Lakkireddy
@ 2018-02-28 18:04   ` Rahul Lakkireddy
  2018-02-28 18:04   ` [PATCH v2 7/7] cxgbe: rework and use " Rahul Lakkireddy
  2018-03-08 13:44   ` [PATCH v2 0/7] cxgbe: bug fixes and updates Ferruh Yigit
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

Update link configuration API to prepare for 32-bit port capability
support. Continue using 16-bit port capability for older firmware.

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
---
v2:
- No changes.

 drivers/net/cxgbe/base/common.h         |  40 +++++---
 drivers/net/cxgbe/base/t4_hw.c          | 168 +++++++++++++++++++++++---------
 drivers/net/cxgbe/base/t4fw_interface.h |  36 ++++++-
 drivers/net/cxgbe/cxgbe_ethdev.c        |   2 +-
 drivers/net/cxgbe/cxgbe_main.c          |  28 +++---
 5 files changed, 200 insertions(+), 74 deletions(-)

diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 0bd78c1b0..98886288c 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -62,13 +62,13 @@ enum dev_master { MASTER_CANT, MASTER_MAY, MASTER_MUST };
 
 enum dev_state { DEV_STATE_UNINIT, DEV_STATE_INIT, DEV_STATE_ERR };
 
-enum {
+enum cc_pause {
 	PAUSE_RX      = 1 << 0,
 	PAUSE_TX      = 1 << 1,
 	PAUSE_AUTONEG = 1 << 2
 };
 
-enum {
+enum cc_fec {
 	FEC_AUTO     = 1 << 0,    /* IEEE 802.3 "automatic" */
 	FEC_RS       = 1 << 1,    /* Reed-Solomon */
 	FEC_BASER_RS = 1 << 2,    /* BaseR/Reed-Solomon */
@@ -241,20 +241,30 @@ struct adapter_params {
 	bool ulptx_memwrite_dsgl;          /* use of T5 DSGL allowed */
 };
 
+/* Firmware Port Capabilities types.
+ */
+typedef u16 fw_port_cap16_t;    /* 16-bit Port Capabilities integral value */
+typedef u32 fw_port_cap32_t;    /* 32-bit Port Capabilities integral value */
+
 struct link_config {
-	unsigned short supported;        /* link capabilities */
-	unsigned short advertising;      /* advertised capabilities */
-	unsigned int   requested_speed;  /* speed user has requested */
-	unsigned int   speed;            /* actual link speed */
-	unsigned char  requested_fc;     /* flow control user has requested */
-	unsigned char  fc;               /* actual link flow control */
-	unsigned char  auto_fec;         /* Forward Error Correction (FEC)
-					  * "automatic" (IEEE 802.3)
-					  */
-	unsigned char  requested_fec;    /* FEC requested */
-	unsigned char  fec;              /* FEC actual */
-	unsigned char  autoneg;          /* autonegotiating? */
-	unsigned char  link_ok;          /* link up? */
+	fw_port_cap32_t pcaps;          /* link capabilities */
+	fw_port_cap32_t acaps;          /* advertised capabilities */
+
+	u32 requested_speed;            /* speed (Mb/s) user has requested */
+	u32 speed;                      /* actual link speed (Mb/s) */
+
+	enum cc_pause requested_fc;     /* flow control user has requested */
+	enum cc_pause fc;               /* actual link flow control */
+
+	enum cc_fec auto_fec;           /* Forward Error Correction
+					 * "automatic" (IEEE 802.3)
+					 */
+	enum cc_fec requested_fec;      /* Forward Error Correction requested */
+	enum cc_fec fec;                /* Forward Error Correction actual */
+
+	unsigned char autoneg;          /* autonegotiating? */
+
+	unsigned char link_ok;          /* link up? */
 };
 
 #include "adapter.h"
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index e8545ceb0..46b296a9d 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2789,66 +2789,105 @@ void t4_dump_version_info(struct adapter *adapter)
 			 G_FW_HDR_FW_VER_BUILD(adapter->params.er_vers));
 }
 
-#define ADVERT_MASK (V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED) | \
-		     FW_PORT_CAP_ANEG)
+#define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \
+		     FW_PORT_CAP32_ANEG)
+/**
+ *     fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
+ *     @caps32: a 32-bit Port Capabilities value
+ *
+ *     Returns the equivalent 16-bit Port Capabilities value.  Note that
+ *     not all 32-bit Port Capabilities can be represented in the 16-bit
+ *     Port Capabilities and some fields/values may not make it.
+ */
+static fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32)
+{
+	fw_port_cap16_t caps16 = 0;
+
+#define CAP32_TO_CAP16(__cap) \
+	do { \
+		if (caps32 & FW_PORT_CAP32_##__cap) \
+			caps16 |= FW_PORT_CAP_##__cap; \
+	} while (0)
+
+	CAP32_TO_CAP16(SPEED_100M);
+	CAP32_TO_CAP16(SPEED_1G);
+	CAP32_TO_CAP16(SPEED_10G);
+	CAP32_TO_CAP16(SPEED_25G);
+	CAP32_TO_CAP16(SPEED_40G);
+	CAP32_TO_CAP16(SPEED_100G);
+	CAP32_TO_CAP16(FC_RX);
+	CAP32_TO_CAP16(FC_TX);
+	CAP32_TO_CAP16(802_3_PAUSE);
+	CAP32_TO_CAP16(802_3_ASM_DIR);
+	CAP32_TO_CAP16(ANEG);
+	CAP32_TO_CAP16(MDIX);
+	CAP32_TO_CAP16(MDIAUTO);
+	CAP32_TO_CAP16(FEC_RS);
+	CAP32_TO_CAP16(FEC_BASER_RS);
+
+#undef CAP32_TO_CAP16
+
+	return caps16;
+}
 
 /* Translate Firmware Pause specification to Common Code */
-static inline unsigned int fwcap_to_cc_pause(unsigned int fw_pause)
+static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
 {
-	unsigned int cc_pause = 0;
+	enum cc_pause cc_pause = 0;
 
-	if (fw_pause & F_FW_PORT_CMD_RXPAUSE)
+	if (fw_pause & FW_PORT_CAP32_FC_RX)
 		cc_pause |= PAUSE_RX;
-	if (fw_pause & F_FW_PORT_CMD_TXPAUSE)
+	if (fw_pause & FW_PORT_CAP32_FC_TX)
 		cc_pause |= PAUSE_TX;
 
 	return cc_pause;
 }
 
 /* Translate Common Code Pause Frame specification into Firmware */
-static inline unsigned int cc_to_fwcap_pause(unsigned int cc_pause)
+static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
 {
-	unsigned int fw_pause = 0;
+	fw_port_cap32_t fw_pause = 0;
 
 	if (cc_pause & PAUSE_RX)
-		fw_pause |= F_FW_PORT_CMD_RXPAUSE;
+		fw_pause |= FW_PORT_CAP32_FC_RX;
 	if (cc_pause & PAUSE_TX)
-		fw_pause |= F_FW_PORT_CMD_TXPAUSE;
+		fw_pause |= FW_PORT_CAP32_FC_TX;
 
 	return fw_pause;
 }
 
 /* Translate Firmware Forward Error Correction specification to Common Code */
-static inline unsigned int fwcap_to_cc_fec(unsigned int fw_fec)
+static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
 {
-	unsigned int cc_fec = 0;
+	enum cc_fec cc_fec = 0;
 
-	if (fw_fec & FW_PORT_CAP_FEC_RS)
+	if (fw_fec & FW_PORT_CAP32_FEC_RS)
 		cc_fec |= FEC_RS;
-	if (fw_fec & FW_PORT_CAP_FEC_BASER_RS)
+	if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
 		cc_fec |= FEC_BASER_RS;
 
 	return cc_fec;
 }
 
 /* Translate Common Code Forward Error Correction specification to Firmware */
-static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
+static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
 {
-	unsigned int fw_fec = 0;
+	fw_port_cap32_t fw_fec = 0;
 
 	if (cc_fec & FEC_RS)
-		fw_fec |= FW_PORT_CAP_FEC_RS;
+		fw_fec |= FW_PORT_CAP32_FEC_RS;
 	if (cc_fec & FEC_BASER_RS)
-		fw_fec |= FW_PORT_CAP_FEC_BASER_RS;
+		fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
 
 	return fw_fec;
 }
 
 /**
  * t4_link_l1cfg - apply link configuration to MAC/PHY
- * @phy: the PHY to setup
- * @mac: the MAC to setup
- * @lc: the requested link configuration
+ * @adapter: the adapter
+ * @mbox: the Firmware Mailbox to use
+ * @port: the Port ID
+ * @lc: the Port's Link Configuration
  *
  * Set up a port's MAC and PHY according to a desired link configuration.
  * - If the PHY can auto-negotiate first decide what to advertise, then
@@ -2860,9 +2899,9 @@ static inline unsigned int cc_to_fwcap_fec(unsigned int cc_fec)
 int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc)
 {
-	struct fw_port_cmd c;
-	unsigned int fw_mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO);
-	unsigned int fw_fc, cc_fec, fw_fec;
+	unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
+	fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
+	struct fw_port_cmd cmd;
 
 	lc->link_ok = 0;
 
@@ -2881,30 +2920,32 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		cc_fec = lc->requested_fec;
 	fw_fec = cc_to_fwcap_fec(cc_fec);
 
-	memset(&c, 0, sizeof(c));
-	c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
-				     F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
-				     V_FW_PORT_CMD_PORTID(port));
-	c.action_to_len16 =
-		cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
-			    FW_LEN16(c));
-
-	if (!(lc->supported & FW_PORT_CAP_ANEG)) {
-		c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) |
-					     fw_fc | fw_fec);
+	/* Figure out what our Requested Port Capabilities are going to be.
+	 */
+	if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
+		rcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec;
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
 		lc->fec = cc_fec;
 	} else if (lc->autoneg == AUTONEG_DISABLE) {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fw_fc |
-					     fw_fec | fw_mdi);
+		rcap = lc->requested_speed | fw_fc | fw_fec | fw_mdi;
 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
 		lc->fec = cc_fec;
 	} else {
-		c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fw_fc | fw_fec |
-					     fw_mdi);
+		rcap = lc->acaps | fw_fc | fw_fec | fw_mdi;
 	}
 
-	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
+	/* And send that on to the Firmware ...
+	 */
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
+				       F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
+				       V_FW_PORT_CMD_PORTID(port));
+	cmd.action_to_len16 =
+		cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+			    FW_LEN16(cmd));
+	cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
+
+	return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL);
 }
 
 /**
@@ -4237,6 +4278,28 @@ int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
 }
 
+/* Return the highest speed set in the port capabilities, in Mb/s. */
+static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
+{
+#define TEST_SPEED_RETURN(__caps_speed, __speed) \
+	do { \
+		if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \
+			return __speed; \
+	} while (0)
+
+	TEST_SPEED_RETURN(100G, 100000);
+	TEST_SPEED_RETURN(50G,   50000);
+	TEST_SPEED_RETURN(40G,   40000);
+	TEST_SPEED_RETURN(25G,   25000);
+	TEST_SPEED_RETURN(10G,   10000);
+	TEST_SPEED_RETURN(1G,     1000);
+	TEST_SPEED_RETURN(100M,    100);
+
+#undef TEST_SPEED_RETURN
+
+	return 0;
+}
+
 /**
  * t4_handle_fw_rpl - process a FW reply message
  * @adap: the adapter
@@ -4319,7 +4382,21 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 			lc->speed = speed;
 			lc->fc = fc;
 			lc->fec = fec;
-			lc->supported = be16_to_cpu(p->u.info.pcap);
+			lc->pcaps = be16_to_cpu(p->u.info.pcap);
+			lc->acaps = be16_to_cpu(p->u.info.acap) & ADVERT_MASK;
+			if (lc->acaps & FW_PORT_CAP32_ANEG) {
+				lc->autoneg = AUTONEG_ENABLE;
+			} else {
+				/* When Autoneg is disabled, user needs to set
+				 * single speed.
+				 */
+				lc->acaps = 0;
+				lc->requested_speed =
+					be16_to_cpu(p->u.info.acap);
+				lc->requested_speed =
+					fwcap_to_speed(lc->requested_speed);
+				lc->autoneg = AUTONEG_DISABLE;
+			}
 		}
 	} else {
 		dev_warn(adap, "Unknown firmware reply %d\n", opcode);
@@ -4352,7 +4429,7 @@ void t4_reset_link_config(struct adapter *adap, int idx)
 static void init_link_config(struct link_config *lc, unsigned int pcaps,
 			     unsigned int acaps)
 {
-	lc->supported = pcaps;
+	lc->pcaps = pcaps;
 	lc->requested_speed = 0;
 	lc->speed = 0;
 	lc->requested_fc = 0;
@@ -4366,11 +4443,12 @@ static void init_link_config(struct link_config *lc, unsigned int pcaps,
 	lc->requested_fec = FEC_AUTO;
 	lc->fec = lc->auto_fec;
 
-	if (lc->supported & FW_PORT_CAP_ANEG) {
-		lc->advertising = lc->supported & ADVERT_MASK;
+	if (lc->pcaps & FW_PORT_CAP32_ANEG) {
+		lc->acaps = lc->pcaps & ADVERT_MASK;
 		lc->autoneg = AUTONEG_ENABLE;
+		lc->requested_fc |= PAUSE_AUTONEG;
 	} else {
-		lc->advertising = 0;
+		lc->acaps = 0;
 		lc->autoneg = AUTONEG_DISABLE;
 	}
 }
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 883a1c7f5..0e139377f 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -1154,7 +1154,7 @@ struct fw_vi_stats_cmd {
 	} u;
 };
 
-/* port capabilities bitmap */
+/* old 16-bit port capabilities bitmap */
 enum fw_port_cap {
 	FW_PORT_CAP_SPEED_100M		= 0x0001,
 	FW_PORT_CAP_SPEED_1G		= 0x0002,
@@ -1189,6 +1189,40 @@ enum fw_port_mdi {
 #define V_FW_PORT_CAP_MDI(x) ((x) << S_FW_PORT_CAP_MDI)
 #define G_FW_PORT_CAP_MDI(x) (((x) >> S_FW_PORT_CAP_MDI) & M_FW_PORT_CAP_MDI)
 
+/* new 32-bit port capabilities bitmap (fw_port_cap32_t) */
+#define FW_PORT_CAP32_SPEED_100M        0x00000001UL
+#define FW_PORT_CAP32_SPEED_1G          0x00000002UL
+#define FW_PORT_CAP32_SPEED_10G         0x00000004UL
+#define FW_PORT_CAP32_SPEED_25G         0x00000008UL
+#define FW_PORT_CAP32_SPEED_40G         0x00000010UL
+#define FW_PORT_CAP32_SPEED_50G         0x00000020UL
+#define FW_PORT_CAP32_SPEED_100G        0x00000040UL
+#define FW_PORT_CAP32_FC_RX             0x00010000UL
+#define FW_PORT_CAP32_FC_TX             0x00020000UL
+#define FW_PORT_CAP32_802_3_PAUSE       0x00040000UL
+#define FW_PORT_CAP32_802_3_ASM_DIR     0x00080000UL
+#define FW_PORT_CAP32_ANEG              0x00100000UL
+#define FW_PORT_CAP32_MDIX              0x00200000UL
+#define FW_PORT_CAP32_MDIAUTO           0x00400000UL
+#define FW_PORT_CAP32_FEC_RS            0x00800000UL
+#define FW_PORT_CAP32_FEC_BASER_RS      0x01000000UL
+
+#define S_FW_PORT_CAP32_SPEED           0
+#define M_FW_PORT_CAP32_SPEED           0xfff
+#define V_FW_PORT_CAP32_SPEED(x)        ((x) << S_FW_PORT_CAP32_SPEED)
+#define G_FW_PORT_CAP32_SPEED(x) \
+	(((x) >> S_FW_PORT_CAP32_SPEED) & M_FW_PORT_CAP32_SPEED)
+
+enum fw_port_mdi32 {
+	FW_PORT_CAP32_MDI_AUTO,
+};
+
+#define S_FW_PORT_CAP32_MDI 21
+#define M_FW_PORT_CAP32_MDI 3
+#define V_FW_PORT_CAP32_MDI(x) ((x) << S_FW_PORT_CAP32_MDI)
+#define G_FW_PORT_CAP32_MDI(x) \
+	(((x) >> S_FW_PORT_CAP32_MDI) & M_FW_PORT_CAP32_MDI)
+
 enum fw_port_action {
 	FW_PORT_ACTION_L1_CFG		= 0x0001,
 	FW_PORT_ACTION_GET_PORT_INFO	= 0x0003,
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 769146cdf..781d75cc2 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -751,7 +751,7 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 	struct adapter *adapter = pi->adapter;
 	struct link_config *lc = &pi->link_cfg;
 
-	if (lc->supported & FW_PORT_CAP_ANEG) {
+	if (lc->pcaps & FW_PORT_CAP32_ANEG) {
 		if (fc_conf->autoneg)
 			lc->requested_fc |= PAUSE_AUTONEG;
 		else
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index 2ee0698c3..5792032e7 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -199,15 +199,16 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us,
 
 static inline bool is_x_1g_port(const struct link_config *lc)
 {
-	return (lc->supported & FW_PORT_CAP_SPEED_1G) != 0;
+	return (lc->pcaps & FW_PORT_CAP32_SPEED_1G) != 0;
 }
 
 static inline bool is_x_10g_port(const struct link_config *lc)
 {
 	unsigned int speeds, high_speeds;
 
-	speeds = V_FW_PORT_CAP_SPEED(G_FW_PORT_CAP_SPEED(lc->supported));
-	high_speeds = speeds & ~(FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G);
+	speeds = V_FW_PORT_CAP32_SPEED(G_FW_PORT_CAP32_SPEED(lc->pcaps));
+	high_speeds = speeds &
+		      ~(FW_PORT_CAP32_SPEED_100M | FW_PORT_CAP32_SPEED_1G);
 
 	return high_speeds != 0;
 }
@@ -387,17 +388,19 @@ static void print_port_info(struct adapter *adap)
 		const struct port_info *pi = adap2pinfo(adap, i);
 		char *bufp = buf;
 
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100M)
 			bufp += sprintf(bufp, "100M/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_1G)
 			bufp += sprintf(bufp, "1G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_10G)
 			bufp += sprintf(bufp, "10G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_25G)
 			bufp += sprintf(bufp, "25G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_40G)
 			bufp += sprintf(bufp, "40G/");
-		if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G)
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_50G)
+			bufp += sprintf(bufp, "50G/");
+		if (pi->link_cfg.pcaps & FW_PORT_CAP32_SPEED_100G)
 			bufp += sprintf(bufp, "100G/");
 		if (bufp != buf)
 			--bufp;
@@ -1096,7 +1099,7 @@ static void fw_caps_to_speed_caps(enum fw_port_type port_type,
 
 #define FW_CAPS_TO_SPEED(__fw_name) \
 	do { \
-		if (fw_caps & FW_PORT_CAP_ ## __fw_name) \
+		if (fw_caps & FW_PORT_CAP32_ ## __fw_name) \
 			SET_SPEED(__fw_name); \
 	} while (0)
 
@@ -1151,6 +1154,7 @@ static void fw_caps_to_speed_caps(enum fw_port_type port_type,
 	case FW_PORT_TYPE_CR4_QSFP:
 		FW_CAPS_TO_SPEED(SPEED_25G);
 		FW_CAPS_TO_SPEED(SPEED_40G);
+		FW_CAPS_TO_SPEED(SPEED_50G);
 		FW_CAPS_TO_SPEED(SPEED_100G);
 		break;
 
@@ -1173,10 +1177,10 @@ void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps)
 {
 	*speed_caps = 0;
 
-	fw_caps_to_speed_caps(pi->port_type, pi->link_cfg.supported,
+	fw_caps_to_speed_caps(pi->port_type, pi->link_cfg.pcaps,
 			      speed_caps);
 
-	if (!(pi->link_cfg.supported & FW_PORT_CAP_ANEG))
+	if (!(pi->link_cfg.pcaps & FW_PORT_CAP32_ANEG))
 		*speed_caps |= ETH_LINK_SPEED_FIXED;
 }
 
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v2 7/7] cxgbe: rework and use 32-bit port capability
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                     ` (5 preceding siblings ...)
  2018-02-28 18:04   ` [PATCH v2 6/7] cxgbe: update link configuration for 32-bit port capability Rahul Lakkireddy
@ 2018-02-28 18:04   ` Rahul Lakkireddy
  2018-03-08 13:44   ` [PATCH v2 0/7] cxgbe: bug fixes and updates Ferruh Yigit
  7 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-02-28 18:04 UTC (permalink / raw)
  To: dev; +Cc: kumaras, surendra, nirranjan, indranil

The new code uses the new 32-bit Port Capabilities exclusively and
only translates to/from the old 16-bit Port Capabilities at the last
point possible when talking to older Firmware.

For the old versus new Firmware issue, we use the new FW_PARAMS_CMD[PFVF,
CAPS32] command to tell the Firmware that we want Asynchronous Port Status
updates to use the new 32-bit version of the Port Information message.  If
we get an error, we know we're dealing with older Firmware, and if not,
we'll start getting th new 32-bit Port Capability message formats.

Also, refactor t4_handle_fw_rpl() to handle new 32-bit Port Capability
replies from firmware in t4_handle_get_port_info().

Original work by Surendra Mobiya <surendra@chelsio.com>

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
---
v2:
- No changes.

 doc/guides/nics/cxgbe.rst               |  10 +-
 drivers/net/cxgbe/base/common.h         |   8 +
 drivers/net/cxgbe/base/t4_hw.c          | 356 +++++++++++++++++++++++---------
 drivers/net/cxgbe/base/t4fw_interface.h |  47 ++++-
 4 files changed, 323 insertions(+), 98 deletions(-)

diff --git a/doc/guides/nics/cxgbe.rst b/doc/guides/nics/cxgbe.rst
index 6126167c5..c4afe8678 100644
--- a/doc/guides/nics/cxgbe.rst
+++ b/doc/guides/nics/cxgbe.rst
@@ -82,7 +82,7 @@ Supported Chelsio T6 NICs
 Prerequisites
 -------------
 
-- Requires firmware version **1.16.43.0** and higher. Visit
+- Requires firmware version **1.17.14.0** and higher. Visit
   `Chelsio Download Center <http://service.chelsio.com>`_ to get latest firmware
   bundled with the latest Chelsio Unified Wire package.
 
@@ -210,7 +210,7 @@ Unified Wire package for Linux operating system are as follows:
 
    .. code-block:: console
 
-      firmware-version: 1.16.43.0, TP 0.1.4.9
+      firmware-version: 1.17.14.0, TP 0.1.4.9
 
 Running testpmd
 ~~~~~~~~~~~~~~~
@@ -268,7 +268,7 @@ devices managed by librte_pmd_cxgbe in Linux operating system.
       EAL:   PCI memory mapped at 0x7fd7c0200000
       EAL:   PCI memory mapped at 0x7fd77cdfd000
       EAL:   PCI memory mapped at 0x7fd7c10b7000
-      PMD: rte_cxgbe_pmd: fw: 1.16.43.0, TP: 0.1.4.9
+      PMD: rte_cxgbe_pmd: fw: 1.17.14.0, TP: 0.1.4.9
       PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
       Interactive-mode selected
       Configuring Port 0 (socket 0)
@@ -352,7 +352,7 @@ Unified Wire package for FreeBSD operating system are as follows:
 
    .. code-block:: console
 
-      dev.t5nex.0.firmware_version: 1.16.43.0
+      dev.t5nex.0.firmware_version: 1.17.14.0
 
 Running testpmd
 ~~~~~~~~~~~~~~~
@@ -470,7 +470,7 @@ devices managed by librte_pmd_cxgbe in FreeBSD operating system.
       EAL:   PCI memory mapped at 0x8007ec000
       EAL:   PCI memory mapped at 0x842800000
       EAL:   PCI memory mapped at 0x80086c000
-      PMD: rte_cxgbe_pmd: fw: 1.16.43.0, TP: 0.1.4.9
+      PMD: rte_cxgbe_pmd: fw: 1.17.14.0, TP: 0.1.4.9
       PMD: rte_cxgbe_pmd: Coming up as MASTER: Initializing adapter
       Interactive-mode selected
       Configuring Port 0 (socket 0)
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 98886288c..365e9e692 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -239,6 +239,7 @@ struct adapter_params {
 	struct arch_specific_params arch; /* chip specific params */
 
 	bool ulptx_memwrite_dsgl;          /* use of T5 DSGL allowed */
+	u8 fw_caps_support;		  /* 32-bit Port Capabilities */
 };
 
 /* Firmware Port Capabilities types.
@@ -246,6 +247,12 @@ struct adapter_params {
 typedef u16 fw_port_cap16_t;    /* 16-bit Port Capabilities integral value */
 typedef u32 fw_port_cap32_t;    /* 32-bit Port Capabilities integral value */
 
+enum fw_caps {
+	FW_CAPS_UNKNOWN = 0,    /* 0'ed out initial state */
+	FW_CAPS16       = 1,    /* old Firmware: 16-bit Port Capabilities */
+	FW_CAPS32       = 2,    /* new Firmware: 32-bit Port Capabilities */
+};
+
 struct link_config {
 	fw_port_cap32_t pcaps;          /* link capabilities */
 	fw_port_cap32_t acaps;          /* advertised capabilities */
@@ -265,6 +272,7 @@ struct link_config {
 	unsigned char autoneg;          /* autonegotiating? */
 
 	unsigned char link_ok;          /* link up? */
+	unsigned char link_down_rc;     /* link down reason */
 };
 
 #include "adapter.h"
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index 46b296a9d..c66e2a6f7 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2791,6 +2791,43 @@ void t4_dump_version_info(struct adapter *adapter)
 
 #define ADVERT_MASK (V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED) | \
 		     FW_PORT_CAP32_ANEG)
+/**
+ *     fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
+ *     @caps16: a 16-bit Port Capabilities value
+ *
+ *     Returns the equivalent 32-bit Port Capabilities value.
+ */
+static fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
+{
+	fw_port_cap32_t caps32 = 0;
+
+#define CAP16_TO_CAP32(__cap) \
+	do { \
+		if (caps16 & FW_PORT_CAP_##__cap) \
+			caps32 |= FW_PORT_CAP32_##__cap; \
+	} while (0)
+
+	CAP16_TO_CAP32(SPEED_100M);
+	CAP16_TO_CAP32(SPEED_1G);
+	CAP16_TO_CAP32(SPEED_25G);
+	CAP16_TO_CAP32(SPEED_10G);
+	CAP16_TO_CAP32(SPEED_40G);
+	CAP16_TO_CAP32(SPEED_100G);
+	CAP16_TO_CAP32(FC_RX);
+	CAP16_TO_CAP32(FC_TX);
+	CAP16_TO_CAP32(ANEG);
+	CAP16_TO_CAP32(MDIX);
+	CAP16_TO_CAP32(MDIAUTO);
+	CAP16_TO_CAP32(FEC_RS);
+	CAP16_TO_CAP32(FEC_BASER_RS);
+	CAP16_TO_CAP32(802_3_PAUSE);
+	CAP16_TO_CAP32(802_3_ASM_DIR);
+
+#undef CAP16_TO_CAP32
+
+	return caps32;
+}
+
 /**
  *     fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
  *     @caps32: a 32-bit Port Capabilities value
@@ -2900,6 +2937,7 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 		  struct link_config *lc)
 {
 	unsigned int fw_mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO);
+	unsigned int fw_caps = adap->params.fw_caps_support;
 	fw_port_cap32_t fw_fc, cc_fec, fw_fec, rcap;
 	struct fw_port_cmd cmd;
 
@@ -2941,9 +2979,15 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port,
 				       F_FW_CMD_REQUEST | F_FW_CMD_EXEC |
 				       V_FW_PORT_CMD_PORTID(port));
 	cmd.action_to_len16 =
-		cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) |
+		cpu_to_be32(V_FW_PORT_CMD_ACTION(fw_caps == FW_CAPS16 ?
+						 FW_PORT_ACTION_L1_CFG :
+						 FW_PORT_ACTION_L1_CFG32) |
 			    FW_LEN16(cmd));
-	cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
+
+	if (fw_caps == FW_CAPS16)
+		cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
+	else
+		cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
 
 	return t4_wr_mbox(adap, mbox, &cmd, sizeof(cmd), NULL);
 }
@@ -4278,6 +4322,31 @@ int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
 }
 
+/**
+ * t4_link_down_rc_str - return a string for a Link Down Reason Code
+ * @link_down_rc: Link Down Reason Code
+ *
+ * Returns a string representation of the Link Down Reason Code.
+ */
+static const char *t4_link_down_rc_str(unsigned char link_down_rc)
+{
+	static const char * const reason[] = {
+		"Link Down",
+		"Remote Fault",
+		"Auto-negotiation Failure",
+		"Reserved",
+		"Insufficient Airflow",
+		"Unable To Determine Reason",
+		"No RX Signal Detected",
+		"Reserved",
+	};
+
+	if (link_down_rc >= ARRAY_SIZE(reason))
+		return "Bad Reason Code";
+
+	return reason[link_down_rc];
+}
+
 /* Return the highest speed set in the port capabilities, in Mb/s. */
 static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
 {
@@ -4300,6 +4369,122 @@ static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
 	return 0;
 }
 
+/**
+ * t4_handle_get_port_info - process a FW reply message
+ * @pi: the port info
+ * @rpl: start of the FW message
+ *
+ * Processes a GET_PORT_INFO FW reply message.
+ */
+static void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
+{
+	const struct fw_port_cmd *cmd = (const void *)rpl;
+	int action = G_FW_PORT_CMD_ACTION(be32_to_cpu(cmd->action_to_len16));
+	fw_port_cap32_t pcaps, acaps, linkattr;
+	struct link_config *lc = &pi->link_cfg;
+	struct adapter *adapter = pi->adapter;
+	enum fw_port_module_type mod_type;
+	enum fw_port_type port_type;
+	unsigned int speed, fc, fec;
+	int link_ok, linkdnrc;
+
+	/* Extract the various fields from the Port Information message.
+	 */
+	switch (action) {
+	case FW_PORT_ACTION_GET_PORT_INFO: {
+		u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype);
+
+		link_ok = (lstatus & F_FW_PORT_CMD_LSTATUS) != 0;
+		linkdnrc = G_FW_PORT_CMD_LINKDNRC(lstatus);
+		port_type = G_FW_PORT_CMD_PTYPE(lstatus);
+		mod_type = G_FW_PORT_CMD_MODTYPE(lstatus);
+		pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap));
+		acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap));
+
+		/* Unfortunately the format of the Link Status in the old
+		 * 16-bit Port Information message isn't the same as the
+		 * 16-bit Port Capabilities bitfield used everywhere else ...
+		 */
+		linkattr = 0;
+		if (lstatus & F_FW_PORT_CMD_RXPAUSE)
+			linkattr |= FW_PORT_CAP32_FC_RX;
+		if (lstatus & F_FW_PORT_CMD_TXPAUSE)
+			linkattr |= FW_PORT_CAP32_FC_TX;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
+			linkattr |= FW_PORT_CAP32_SPEED_100M;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
+			linkattr |= FW_PORT_CAP32_SPEED_1G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
+			linkattr |= FW_PORT_CAP32_SPEED_10G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G))
+			linkattr |= FW_PORT_CAP32_SPEED_25G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
+			linkattr |= FW_PORT_CAP32_SPEED_40G;
+		if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G))
+			linkattr |= FW_PORT_CAP32_SPEED_100G;
+
+		break;
+		}
+
+	case FW_PORT_ACTION_GET_PORT_INFO32: {
+		u32 lstatus32 =
+			be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
+
+		link_ok = (lstatus32 & F_FW_PORT_CMD_LSTATUS32) != 0;
+		linkdnrc = G_FW_PORT_CMD_LINKDNRC32(lstatus32);
+		port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
+		mod_type = G_FW_PORT_CMD_MODTYPE32(lstatus32);
+		pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
+		acaps = be32_to_cpu(cmd->u.info32.acaps32);
+		linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
+		break;
+		}
+
+	default:
+		dev_warn(adapter, "Handle Port Information: Bad Command/Action %#x\n",
+			 be32_to_cpu(cmd->action_to_len16));
+		return;
+	}
+
+	fec = fwcap_to_cc_fec(acaps);
+
+	fc = fwcap_to_cc_pause(linkattr);
+	speed = fwcap_to_speed(linkattr);
+
+	if (mod_type != pi->mod_type) {
+		lc->auto_fec = fec;
+		pi->port_type = port_type;
+		pi->mod_type = mod_type;
+		t4_os_portmod_changed(adapter, pi->port_id);
+	}
+	if (link_ok != lc->link_ok || speed != lc->speed ||
+	    fc != lc->fc || fec != lc->fec) { /* something changed */
+		if (!link_ok && lc->link_ok) {
+			lc->link_down_rc = linkdnrc;
+			dev_warn(adap, "Port %d link down, reason: %s\n",
+				 pi->tx_chan, t4_link_down_rc_str(linkdnrc));
+		}
+		lc->link_ok = link_ok;
+		lc->speed = speed;
+		lc->fc = fc;
+		lc->fec = fec;
+		lc->pcaps = pcaps;
+		lc->acaps = acaps & ADVERT_MASK;
+
+		if (lc->acaps & FW_PORT_CAP32_ANEG) {
+			lc->autoneg = AUTONEG_ENABLE;
+		} else {
+			/* When Autoneg is disabled, user needs to set
+			 * single speed.
+			 * Similar to cxgb4_ethtool.c: set_link_ksettings
+			 */
+			lc->acaps = 0;
+			lc->requested_speed = fwcap_to_speed(acaps);
+			lc->autoneg = AUTONEG_DISABLE;
+		}
+	}
+}
+
 /**
  * t4_handle_fw_rpl - process a FW reply message
  * @adap: the adapter
@@ -4321,83 +4506,21 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
 	unsigned int action =
 		G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16));
 
-	if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) {
+	if (opcode == FW_PORT_CMD &&
+	    (action == FW_PORT_ACTION_GET_PORT_INFO ||
+	     action == FW_PORT_ACTION_GET_PORT_INFO32)) {
 		/* link/module state change message */
-		unsigned int speed = 0, fc = 0, i;
 		int chan = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid));
 		struct port_info *pi = NULL;
-		struct link_config *lc;
-		u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
-		int link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0;
-		u32 mod = G_FW_PORT_CMD_MODTYPE(stat);
-		unsigned int fec;
-
-		fc = fwcap_to_cc_pause(stat);
-		fec = fwcap_to_cc_fec(stat);
-
-		if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
-			speed = ETH_SPEED_NUM_100M;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
-			speed = ETH_SPEED_NUM_1G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
-			speed = ETH_SPEED_NUM_10G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G))
-			speed = ETH_SPEED_NUM_25G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
-			speed = ETH_SPEED_NUM_40G;
-		else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G))
-			speed = ETH_SPEED_NUM_100G;
+		int i;
 
 		for_each_port(adap, i) {
 			pi = adap2pinfo(adap, i);
 			if (pi->tx_chan == chan)
 				break;
 		}
-		lc = &pi->link_cfg;
 
-		if (mod != pi->mod_type) {
-			lc->auto_fec = fec;
-			pi->mod_type = mod;
-			t4_os_portmod_changed(adap, i);
-		}
-		if (link_ok != lc->link_ok || speed != lc->speed ||
-		    fc != lc->fc || fec != lc->fec) { /* something changed */
-			if (!link_ok && lc->link_ok) {
-				static const char * const reason[] = {
-					"Link Down",
-					"Remote Fault",
-					"Auto-negotiation Failure",
-					"Reserved",
-					"Insufficient Airflow",
-					"Unable To Determine Reason",
-					"No RX Signal Detected",
-					"Reserved",
-				};
-				unsigned int rc = G_FW_PORT_CMD_LINKDNRC(stat);
-
-				dev_warn(adap, "Port %d link down, reason: %s\n",
-					 chan, reason[rc]);
-			}
-			lc->link_ok = link_ok;
-			lc->speed = speed;
-			lc->fc = fc;
-			lc->fec = fec;
-			lc->pcaps = be16_to_cpu(p->u.info.pcap);
-			lc->acaps = be16_to_cpu(p->u.info.acap) & ADVERT_MASK;
-			if (lc->acaps & FW_PORT_CAP32_ANEG) {
-				lc->autoneg = AUTONEG_ENABLE;
-			} else {
-				/* When Autoneg is disabled, user needs to set
-				 * single speed.
-				 */
-				lc->acaps = 0;
-				lc->requested_speed =
-					be16_to_cpu(p->u.info.acap);
-				lc->requested_speed =
-					fwcap_to_speed(lc->requested_speed);
-				lc->autoneg = AUTONEG_DISABLE;
-			}
-		}
+		t4_handle_get_port_info(pi, rpl);
 	} else {
 		dev_warn(adap, "Unknown firmware reply %d\n", opcode);
 		return -EINVAL;
@@ -4426,8 +4549,8 @@ void t4_reset_link_config(struct adapter *adap, int idx)
  * Initializes the SW state maintained for each link, including the link's
  * capabilities and default speed/flow-control/autonegotiation settings.
  */
-static void init_link_config(struct link_config *lc, unsigned int pcaps,
-			     unsigned int acaps)
+static void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
+			     fw_port_cap32_t acaps)
 {
 	lc->pcaps = pcaps;
 	lc->requested_speed = 0;
@@ -4969,46 +5092,95 @@ int t4_init_rss_mode(struct adapter *adap, int mbox)
 
 int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
 {
-	u8 addr[6];
+	unsigned int fw_caps = adap->params.fw_caps_support;
+	fw_port_cap32_t pcaps, acaps;
+	enum fw_port_type port_type;
+	struct fw_port_cmd cmd;
 	int ret, i, j = 0;
-	struct fw_port_cmd c;
+	int mdio_addr;
+	u32 action;
+	u8 addr[6];
 
-	memset(&c, 0, sizeof(c));
+	memset(&cmd, 0, sizeof(cmd));
 
 	for_each_port(adap, i) {
+		struct port_info *pi = adap2pinfo(adap, i);
 		unsigned int rss_size = 0;
-		struct port_info *p = adap2pinfo(adap, i);
 
 		while ((adap->params.portvec & (1 << j)) == 0)
 			j++;
 
-		c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
-					     F_FW_CMD_REQUEST | F_FW_CMD_READ |
-					     V_FW_PORT_CMD_PORTID(j));
-		c.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(
-						FW_PORT_ACTION_GET_PORT_INFO) |
-						FW_LEN16(c));
-		ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
+		/* If we haven't yet determined whether we're talking to
+		 * Firmware which knows the new 32-bit Port Capabilities, it's
+		 * time to find out now.  This will also tell new Firmware to
+		 * send us Port Status Updates using the new 32-bit Port
+		 * Capabilities version of the Port Information message.
+		 */
+		if (fw_caps == FW_CAPS_UNKNOWN) {
+			u32 param, val, caps;
+
+			caps = FW_PARAMS_PARAM_PFVF_PORT_CAPS32;
+			param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) |
+				 V_FW_PARAMS_PARAM_X(caps));
+			val = 1;
+			ret = t4_set_params(adap, mbox, pf, vf, 1, &param,
+					    &val);
+			fw_caps = ret == 0 ? FW_CAPS32 : FW_CAPS16;
+			adap->params.fw_caps_support = fw_caps;
+		}
+
+		memset(&cmd, 0, sizeof(cmd));
+		cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
+					       F_FW_CMD_REQUEST |
+					       F_FW_CMD_READ |
+					       V_FW_PORT_CMD_PORTID(j));
+		action = fw_caps == FW_CAPS16 ? FW_PORT_ACTION_GET_PORT_INFO :
+						FW_PORT_ACTION_GET_PORT_INFO32;
+		cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) |
+						  FW_LEN16(cmd));
+		ret = t4_wr_mbox(pi->adapter, mbox, &cmd, sizeof(cmd), &cmd);
 		if (ret)
 			return ret;
 
+		/* Extract the various fields from the Port Information message.
+		 */
+		if (fw_caps == FW_CAPS16) {
+			u32 lstatus =
+				be32_to_cpu(cmd.u.info.lstatus_to_modtype);
+
+			port_type = G_FW_PORT_CMD_PTYPE(lstatus);
+			mdio_addr = (lstatus & F_FW_PORT_CMD_MDIOCAP) ?
+				    (int)G_FW_PORT_CMD_MDIOADDR(lstatus) : -1;
+			pcaps = be16_to_cpu(cmd.u.info.pcap);
+			acaps = be16_to_cpu(cmd.u.info.acap);
+			pcaps = fwcaps16_to_caps32(pcaps);
+			acaps = fwcaps16_to_caps32(acaps);
+		} else {
+			u32 lstatus32 =
+				be32_to_cpu(cmd.u.info32.lstatus32_to_cbllen32);
+
+			port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
+			mdio_addr = (lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ?
+				    (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) :
+				    -1;
+			pcaps = be32_to_cpu(cmd.u.info32.pcaps32);
+			acaps = be32_to_cpu(cmd.u.info32.acaps32);
+		}
+
 		ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
 		if (ret < 0)
 			return ret;
 
-		p->viid = ret;
-		p->tx_chan = j;
-		p->rss_size = rss_size;
+		pi->viid = ret;
+		pi->tx_chan = j;
+		pi->rss_size = rss_size;
 		t4_os_set_hw_addr(adap, i, addr);
 
-		ret = be32_to_cpu(c.u.info.lstatus_to_modtype);
-		p->mdio_addr = (ret & F_FW_PORT_CMD_MDIOCAP) ?
-				G_FW_PORT_CMD_MDIOADDR(ret) : -1;
-		p->port_type = G_FW_PORT_CMD_PTYPE(ret);
-		p->mod_type = FW_PORT_MOD_TYPE_NA;
+		pi->port_type = port_type;
+		pi->mdio_addr = mdio_addr;
+		pi->mod_type = FW_PORT_MOD_TYPE_NA;
 
-		init_link_config(&p->link_cfg, be16_to_cpu(c.u.info.pcap),
-				 be16_to_cpu(c.u.info.acap));
+		init_link_config(&pi->link_cfg, pcaps, acaps);
 		j++;
 	}
 	return 0;
diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h
index 0e139377f..d71c5a4af 100644
--- a/drivers/net/cxgbe/base/t4fw_interface.h
+++ b/drivers/net/cxgbe/base/t4fw_interface.h
@@ -491,7 +491,8 @@ enum fw_params_param_dev {
  * physical and virtual function parameters
  */
 enum fw_params_param_pfvf {
-	FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31
+	FW_PARAMS_PARAM_PFVF_CPLFW4MSG_ENCAP = 0x31,
+	FW_PARAMS_PARAM_PFVF_PORT_CAPS32 = 0x3A
 };
 
 /*
@@ -1226,6 +1227,8 @@ enum fw_port_mdi32 {
 enum fw_port_action {
 	FW_PORT_ACTION_L1_CFG		= 0x0001,
 	FW_PORT_ACTION_GET_PORT_INFO	= 0x0003,
+	FW_PORT_ACTION_L1_CFG32         = 0x0009,
+	FW_PORT_ACTION_GET_PORT_INFO32  = 0x000a,
 };
 
 struct fw_port_cmd {
@@ -1314,6 +1317,18 @@ struct fw_port_cmd {
 				__be64 r12;
 			} control;
 		} dcb;
+		struct fw_port_l1cfg32 {
+			__be32 rcap32;
+			__be32 r;
+		} l1cfg32;
+		struct fw_port_info32 {
+			__be32 lstatus32_to_cbllen32;
+			__be32 auxlinfo32_mtu32;
+			__be32 linkattr32;
+			__be32 pcaps32;
+			__be32 acaps32;
+			__be32 lpacaps32;
+		} info32;
 	} u;
 };
 
@@ -1387,6 +1402,36 @@ struct fw_port_cmd {
 #define G_FW_PORT_CMD_MODTYPE(x)	\
 	(((x) >> S_FW_PORT_CMD_MODTYPE) & M_FW_PORT_CMD_MODTYPE)
 
+#define S_FW_PORT_CMD_LSTATUS32                31
+#define M_FW_PORT_CMD_LSTATUS32                0x1
+#define V_FW_PORT_CMD_LSTATUS32(x)     ((x) << S_FW_PORT_CMD_LSTATUS32)
+#define F_FW_PORT_CMD_LSTATUS32        V_FW_PORT_CMD_LSTATUS32(1U)
+
+#define S_FW_PORT_CMD_LINKDNRC32       28
+#define M_FW_PORT_CMD_LINKDNRC32       0x7
+#define G_FW_PORT_CMD_LINKDNRC32(x)    \
+	(((x) >> S_FW_PORT_CMD_LINKDNRC32) & M_FW_PORT_CMD_LINKDNRC32)
+
+#define S_FW_PORT_CMD_MDIOCAP32                26
+#define M_FW_PORT_CMD_MDIOCAP32                0x1
+#define V_FW_PORT_CMD_MDIOCAP32(x)     ((x) << S_FW_PORT_CMD_MDIOCAP32)
+#define F_FW_PORT_CMD_MDIOCAP32        V_FW_PORT_CMD_MDIOCAP32(1U)
+
+#define S_FW_PORT_CMD_MDIOADDR32       21
+#define M_FW_PORT_CMD_MDIOADDR32       0x1f
+#define G_FW_PORT_CMD_MDIOADDR32(x)    \
+	(((x) >> S_FW_PORT_CMD_MDIOADDR32) & M_FW_PORT_CMD_MDIOADDR32)
+
+#define S_FW_PORT_CMD_PORTTYPE32        13
+#define M_FW_PORT_CMD_PORTTYPE32        0xff
+#define G_FW_PORT_CMD_PORTTYPE32(x)     \
+	(((x) >> S_FW_PORT_CMD_PORTTYPE32) & M_FW_PORT_CMD_PORTTYPE32)
+
+#define S_FW_PORT_CMD_MODTYPE32                8
+#define M_FW_PORT_CMD_MODTYPE32                0x1f
+#define G_FW_PORT_CMD_MODTYPE32(x)     \
+	(((x) >> S_FW_PORT_CMD_MODTYPE32) & M_FW_PORT_CMD_MODTYPE32)
+
 /*
  * These are configured into the VPD and hence tools that generate
  * VPD may use this enumeration.
-- 
2.14.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-02-28 18:04   ` [PATCH v2 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
@ 2018-03-08 13:34     ` Ferruh Yigit
  2018-03-10  5:21       ` Rahul Lakkireddy
  0 siblings, 1 reply; 29+ messages in thread
From: Ferruh Yigit @ 2018-03-08 13:34 UTC (permalink / raw)
  To: Rahul Lakkireddy, dev; +Cc: kumaras, surendra, nirranjan, indranil

On 2/28/2018 6:04 PM, Rahul Lakkireddy wrote:
> From: Kumar Sanghvi <kumaras@chelsio.com>
> 
> Add firmware API for updating RSS hash configuration and key.  Move
> RSS hash configuration from cxgb4_write_rss() to a separate function
> cxgbe_write_rss_conf().
> 
> Also, rename cxgb4_write_rss() to cxgbe_write_rss() for consistency.
> 
> Original work by Surendra Mobiya <surendra@chelsio.com>
> 
> Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>

<...>

> @@ -985,6 +1016,7 @@ static const struct eth_dev_ops cxgbe_eth_dev_ops = {
>  	.get_eeprom		= cxgbe_get_eeprom,
>  	.set_eeprom		= cxgbe_set_eeprom,
>  	.get_reg		= cxgbe_get_regs,
> +	.rss_hash_update	= cxgbe_dev_rss_hash_update,

Also in cxgbe_dev_info_get(), rte_eth_dev_info->flow_type_rss_offloads should be
updated with supported RSS hash functions.

I don't see any usage of "flow_type_rss_offloads" in sample apps except testpmd
is using it to print the log, but that is the way to notify applications about
support.

You don't need to send a new version of patchset for this, please send an
incremental patch and I can squash it into this set.

<...>

> +int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t rss_hf)
> +{
> +	struct adapter *adapter = pi->adapter;
> +	const struct sge_eth_rxq *rxq;
> +	u64 flags = 0;
> +	u16 rss;
> +	int err;
> +
> +	/*  Should never be called before setting up sge eth rx queues */
> +	if (!(adapter->flags & FULL_INIT_DONE)) {
> +		dev_err(adap, "%s No RXQs available on port %d\n",
> +			__func__, pi->port_id);
> +		return -EINVAL;
> +	}
> +
> +	if (rss_hf & ETH_RSS_IPV4)
> +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN;
> +
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
> +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN;
> +
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
> +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN |
> +			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
> +
> +	if (rss_hf & ETH_RSS_IPV6)
> +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN;
> +
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
> +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN;
> +
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
> +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
> +			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
> +
> +	rxq = &adapter->sge.ethrxq[pi->first_qset];
> +	rss = rxq[0].rspq.abs_id;

What if driver gets a rss_hf that is not supported, will the API report back an
error to the application?

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 0/7] cxgbe: bug fixes and updates
  2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
                     ` (6 preceding siblings ...)
  2018-02-28 18:04   ` [PATCH v2 7/7] cxgbe: rework and use " Rahul Lakkireddy
@ 2018-03-08 13:44   ` Ferruh Yigit
  2018-03-08 13:50     ` Ferruh Yigit
  7 siblings, 1 reply; 29+ messages in thread
From: Ferruh Yigit @ 2018-03-08 13:44 UTC (permalink / raw)
  To: Rahul Lakkireddy, dev; +Cc: kumaras, surendra, nirranjan, indranil

On 2/28/2018 6:04 PM, Rahul Lakkireddy wrote:
> Patch 1 reworks rte_eth_dev allocation for other ports under same PF.
> 
> Patch 2 fixes secondary process initialization failure.
> 
> Patches 3 and 4 allow configuring RSS hash and key.
> 
> Patch 5 updates link Forward Error Correction (FEC) to support IEEE
> 802.3 standard based FEC selection.
> 
> Patches 6 and 7 update to new firmware 32-bit port capabilities to
> support more link speeds and module types.
> 
> Thanks,
> Rahul
> 
> ---
> v2:
> - Patch 2 regarding link update from v1 has been dropped.
> - Split rte_eth_dev allocation rework for other ports under same PF
> to patch 1.
> - Split secondary process fix to patch 2.
> 
> Kumar Sanghvi (4):
>   cxgbe: fix secondary process initialization
>   cxgbe: add support to update RSS hash configuration and key
>   cxgbe: add support to get programmed RSS hash configuration and key
>   cxgbe: update link Forward Error Correction (FEC)
> 
> Rahul Lakkireddy (3):
>   cxgbe: rework rte_eth_dev allocation
>   cxgbe: update link configuration for 32-bit port capability
>   cxgbe: rework and use 32-bit port capability

Series applied to dpdk-next-net/master, thanks.

Please check comments on 3/7 for further work.

(Patch titles updated from "cxgbe:" to "net/cxgbe:")

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 0/7] cxgbe: bug fixes and updates
  2018-03-08 13:44   ` [PATCH v2 0/7] cxgbe: bug fixes and updates Ferruh Yigit
@ 2018-03-08 13:50     ` Ferruh Yigit
  2018-03-10  5:24       ` Rahul Lakkireddy
  0 siblings, 1 reply; 29+ messages in thread
From: Ferruh Yigit @ 2018-03-08 13:50 UTC (permalink / raw)
  To: Rahul Lakkireddy, dev; +Cc: kumaras, surendra, nirranjan, indranil

On 3/8/2018 1:44 PM, Ferruh Yigit wrote:
> On 2/28/2018 6:04 PM, Rahul Lakkireddy wrote:
>> Patch 1 reworks rte_eth_dev allocation for other ports under same PF.
>>
>> Patch 2 fixes secondary process initialization failure.
>>
>> Patches 3 and 4 allow configuring RSS hash and key.
>>
>> Patch 5 updates link Forward Error Correction (FEC) to support IEEE
>> 802.3 standard based FEC selection.
>>
>> Patches 6 and 7 update to new firmware 32-bit port capabilities to
>> support more link speeds and module types.
>>
>> Thanks,
>> Rahul
>>
>> ---
>> v2:
>> - Patch 2 regarding link update from v1 has been dropped.
>> - Split rte_eth_dev allocation rework for other ports under same PF
>> to patch 1.
>> - Split secondary process fix to patch 2.
>>
>> Kumar Sanghvi (4):
>>   cxgbe: fix secondary process initialization
>>   cxgbe: add support to update RSS hash configuration and key
>>   cxgbe: add support to get programmed RSS hash configuration and key
>>   cxgbe: update link Forward Error Correction (FEC)
>>
>> Rahul Lakkireddy (3):
>>   cxgbe: rework rte_eth_dev allocation
>>   cxgbe: update link configuration for 32-bit port capability
>>   cxgbe: rework and use 32-bit port capability
> 
> Series applied to dpdk-next-net/master, thanks.
> 
> Please check comments on 3/7 for further work.
> 
> (Patch titles updated from "cxgbe:" to "net/cxgbe:")

BTW, cxgbe seems still not switched to SPDX tags, is there a plan for the switch?

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 3/7] cxgbe: add support to update RSS hash configuration and key
  2018-03-08 13:34     ` Ferruh Yigit
@ 2018-03-10  5:21       ` Rahul Lakkireddy
  0 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-03-10  5:21 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, Kumar A S, Surendra Mobiya, Nirranjan Kirubaharan,
	Indranil Choudhury

On Thursday, March 03/08/18, 2018 at 19:04:31 +0530, Ferruh Yigit wrote:
> On 2/28/2018 6:04 PM, Rahul Lakkireddy wrote:
> > From: Kumar Sanghvi <kumaras@chelsio.com>
> > 
> > Add firmware API for updating RSS hash configuration and key.  Move
> > RSS hash configuration from cxgb4_write_rss() to a separate function
> > cxgbe_write_rss_conf().
> > 
> > Also, rename cxgb4_write_rss() to cxgbe_write_rss() for consistency.
> > 
> > Original work by Surendra Mobiya <surendra@chelsio.com>
> > 
> > Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
> > Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
> 
> <...>
> 
> > @@ -985,6 +1016,7 @@ static const struct eth_dev_ops cxgbe_eth_dev_ops = {
> >  	.get_eeprom		= cxgbe_get_eeprom,
> >  	.set_eeprom		= cxgbe_set_eeprom,
> >  	.get_reg		= cxgbe_get_regs,
> > +	.rss_hash_update	= cxgbe_dev_rss_hash_update,
> 
> Also in cxgbe_dev_info_get(), rte_eth_dev_info->flow_type_rss_offloads should be
> updated with supported RSS hash functions.
> 
> I don't see any usage of "flow_type_rss_offloads" in sample apps except testpmd
> is using it to print the log, but that is the way to notify applications about
> support.
> 
> You don't need to send a new version of patchset for this, please send an
> incremental patch and I can squash it into this set.
> 
> <...>
> 

Ok, will update supported RSS hash functions in flow_type_rss_offloads.
Will send a fix.

> > +int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t rss_hf)
> > +{
> > +	struct adapter *adapter = pi->adapter;
> > +	const struct sge_eth_rxq *rxq;
> > +	u64 flags = 0;
> > +	u16 rss;
> > +	int err;
> > +
> > +	/*  Should never be called before setting up sge eth rx queues */
> > +	if (!(adapter->flags & FULL_INIT_DONE)) {
> > +		dev_err(adap, "%s No RXQs available on port %d\n",
> > +			__func__, pi->port_id);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (rss_hf & ETH_RSS_IPV4)
> > +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN;
> > +
> > +	if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
> > +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN;
> > +
> > +	if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
> > +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN |
> > +			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
> > +
> > +	if (rss_hf & ETH_RSS_IPV6)
> > +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN;
> > +
> > +	if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
> > +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN;
> > +
> > +	if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
> > +		flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
> > +			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
> > +
> > +	rxq = &adapter->sge.ethrxq[pi->first_qset];
> > +	rss = rxq[0].rspq.abs_id;
> 
> What if driver gets a rss_hf that is not supported, will the API report back an
> error to the application?
> 

Good catch!  Will send a fix.

Thanks,
Rahul

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 0/7] cxgbe: bug fixes and updates
  2018-03-08 13:50     ` Ferruh Yigit
@ 2018-03-10  5:24       ` Rahul Lakkireddy
  0 siblings, 0 replies; 29+ messages in thread
From: Rahul Lakkireddy @ 2018-03-10  5:24 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, Kumar A S, Surendra Mobiya, Nirranjan Kirubaharan,
	Indranil Choudhury

On Thursday, March 03/08/18, 2018 at 19:20:14 +0530, Ferruh Yigit wrote:
> On 3/8/2018 1:44 PM, Ferruh Yigit wrote:
> > On 2/28/2018 6:04 PM, Rahul Lakkireddy wrote:
> >> Patch 1 reworks rte_eth_dev allocation for other ports under same PF.
> >>
> >> Patch 2 fixes secondary process initialization failure.
> >>
> >> Patches 3 and 4 allow configuring RSS hash and key.
> >>
> >> Patch 5 updates link Forward Error Correction (FEC) to support IEEE
> >> 802.3 standard based FEC selection.
> >>
> >> Patches 6 and 7 update to new firmware 32-bit port capabilities to
> >> support more link speeds and module types.
> >>
> >> Thanks,
> >> Rahul
> >>
> >> ---
> >> v2:
> >> - Patch 2 regarding link update from v1 has been dropped.
> >> - Split rte_eth_dev allocation rework for other ports under same PF
> >> to patch 1.
> >> - Split secondary process fix to patch 2.
> >>
> >> Kumar Sanghvi (4):
> >>   cxgbe: fix secondary process initialization
> >>   cxgbe: add support to update RSS hash configuration and key
> >>   cxgbe: add support to get programmed RSS hash configuration and key
> >>   cxgbe: update link Forward Error Correction (FEC)
> >>
> >> Rahul Lakkireddy (3):
> >>   cxgbe: rework rte_eth_dev allocation
> >>   cxgbe: update link configuration for 32-bit port capability
> >>   cxgbe: rework and use 32-bit port capability
> > 
> > Series applied to dpdk-next-net/master, thanks.
> > 
> > Please check comments on 3/7 for further work.
> > 
> > (Patch titles updated from "cxgbe:" to "net/cxgbe:")
> 
> BTW, cxgbe seems still not switched to SPDX tags, is there a plan for the switch?
> 
> Thanks,
> ferruh
> 

We plan to switch to SPDX tags as well.  Will send a patch.

Thanks,
Rahul

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2018-03-10  5:24 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-04  6:06 [PATCH 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
2018-02-04  6:06 ` [PATCH 1/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
2018-02-05 17:23   ` Ferruh Yigit
2018-02-06  9:20     ` Rahul Lakkireddy
2018-02-04  6:06 ` [PATCH 2/7] cxgbe: update link state when link speed changes Rahul Lakkireddy
2018-02-05 17:05   ` Ferruh Yigit
2018-02-04  6:06 ` [PATCH 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
2018-02-05 17:09   ` Ferruh Yigit
2018-02-06  9:22     ` Rahul Lakkireddy
2018-02-06 10:11       ` Ferruh Yigit
2018-02-06 10:38         ` Thomas Monjalon
2018-02-07  7:01           ` Rahul Lakkireddy
2018-02-04  6:06 ` [PATCH 4/7] cxgbe: add support to get programmed " Rahul Lakkireddy
2018-02-04  6:06 ` [PATCH 5/7] cxgbe: update link Forward Error Correction (FEC) Rahul Lakkireddy
2018-02-04  6:06 ` [PATCH 6/7] cxgbe: update link configuration for 32-bit port capability Rahul Lakkireddy
2018-02-04  6:06 ` [PATCH 7/7] cxgbe: rework and use " Rahul Lakkireddy
2018-02-28 18:04 ` [PATCH v2 0/7] cxgbe: bug fixes and updates Rahul Lakkireddy
2018-02-28 18:04   ` [PATCH v2 1/7] cxgbe: rework rte_eth_dev allocation Rahul Lakkireddy
2018-02-28 18:04   ` [PATCH v2 2/7] cxgbe: fix secondary process initialization Rahul Lakkireddy
2018-02-28 18:04   ` [PATCH v2 3/7] cxgbe: add support to update RSS hash configuration and key Rahul Lakkireddy
2018-03-08 13:34     ` Ferruh Yigit
2018-03-10  5:21       ` Rahul Lakkireddy
2018-02-28 18:04   ` [PATCH v2 4/7] cxgbe: add support to get programmed " Rahul Lakkireddy
2018-02-28 18:04   ` [PATCH v2 5/7] cxgbe: update link Forward Error Correction (FEC) Rahul Lakkireddy
2018-02-28 18:04   ` [PATCH v2 6/7] cxgbe: update link configuration for 32-bit port capability Rahul Lakkireddy
2018-02-28 18:04   ` [PATCH v2 7/7] cxgbe: rework and use " Rahul Lakkireddy
2018-03-08 13:44   ` [PATCH v2 0/7] cxgbe: bug fixes and updates Ferruh Yigit
2018-03-08 13:50     ` Ferruh Yigit
2018-03-10  5:24       ` Rahul Lakkireddy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.