DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start
@ 2020-12-10 14:22 Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 1/6] net/ionic: preserve RSS state unless RETA size changes Andrew Boyer
                   ` (14 more replies)
  0 siblings, 15 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-10 14:22 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

These patches address issues found when testing port stop and start,
link up and down, and queue stop and start.

The UNMAINTAINED flag is removed in patch 3.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>

Andrew Boyer (6):
  net/ionic: preserve RSS state unless RETA size changes
  net/ionic: preserve RX mode across LIF stop/start
  net/ionic: fully implement remove-on-close
  net/ionic: improve link state handling
  net/ionic: improve queue state handling
  net/ionic: stop queues when LIF is stopped

 MAINTAINERS                      |   2 +-
 drivers/net/ionic/ionic_ethdev.c |  90 ++++++++------------
 drivers/net/ionic/ionic_ethdev.h |   4 +
 drivers/net/ionic/ionic_lif.c    | 141 ++++++++++++++++++++++---------
 drivers/net/ionic/ionic_lif.h    |   6 +-
 drivers/net/ionic/ionic_rxtx.c   |  62 +++++++++-----
 6 files changed, 188 insertions(+), 117 deletions(-)

-- 
2.17.1


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

* [dpdk-dev] [PATCH 1/6] net/ionic: preserve RSS state unless RETA size changes
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
@ 2020-12-10 14:22 ` Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 2/6] net/ionic: preserve RX mode across LIF stop/start Andrew Boyer
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-10 14:22 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

This preserves settings across a stop/start.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_lif.c | 44 ++++++++++++++++-------------------
 drivers/net/ionic/ionic_lif.h |  1 +
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 28ae9dc8a..646c921b2 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -962,8 +962,6 @@ ionic_lif_rss_config(struct ionic_lif *lif,
 static int
 ionic_lif_rss_setup(struct ionic_lif *lif)
 {
-	size_t tbl_size = sizeof(*lif->rss_ind_tbl) *
-		lif->adapter->ident.lif.eth.rss_ind_tbl_sz;
 	static const uint8_t toeplitz_symmetric_key[] = {
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
@@ -971,34 +969,35 @@ ionic_lif_rss_setup(struct ionic_lif *lif)
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
 	};
-	uint32_t socket_id = rte_socket_id();
 	uint32_t i;
-	int err;
+	uint16_t tbl_sz = lif->adapter->ident.lif.eth.rss_ind_tbl_sz;
 
 	IONIC_PRINT_CALL();
 
-	lif->rss_ind_tbl_z = rte_eth_dma_zone_reserve(lif->eth_dev,
-		"rss_ind_tbl",
-		0 /* queue_idx*/, tbl_size, IONIC_ALIGN, socket_id);
-
 	if (!lif->rss_ind_tbl_z) {
-		IONIC_PRINT(ERR, "OOM");
-		return -ENOMEM;
-	}
+		lif->rss_ind_tbl_z = rte_eth_dma_zone_reserve(lif->eth_dev,
+					"rss_ind_tbl", 0 /* queue_idx */,
+					sizeof(*lif->rss_ind_tbl) * tbl_sz,
+					IONIC_ALIGN, rte_socket_id());
+		if (!lif->rss_ind_tbl_z) {
+			IONIC_PRINT(ERR, "OOM");
+			return -ENOMEM;
+		}
 
-	lif->rss_ind_tbl = lif->rss_ind_tbl_z->addr;
-	lif->rss_ind_tbl_pa = lif->rss_ind_tbl_z->iova;
+		lif->rss_ind_tbl = lif->rss_ind_tbl_z->addr;
+		lif->rss_ind_tbl_pa = lif->rss_ind_tbl_z->iova;
+	}
 
-	/* Fill indirection table with 'default' values */
-	for (i = 0; i < lif->adapter->ident.lif.eth.rss_ind_tbl_sz; i++)
-		lif->rss_ind_tbl[i] = i % lif->nrxqcqs;
+	if (lif->rss_ind_tbl_nrxqcqs != lif->nrxqcqs) {
+		lif->rss_ind_tbl_nrxqcqs = lif->nrxqcqs;
 
-	err = ionic_lif_rss_config(lif, IONIC_RSS_OFFLOAD_ALL,
-		toeplitz_symmetric_key, NULL);
-	if (err)
-		return err;
+		/* Fill indirection table with 'default' values */
+		for (i = 0; i < tbl_sz; i++)
+			lif->rss_ind_tbl[i] = i % lif->nrxqcqs;
+	}
 
-	return 0;
+	return ionic_lif_rss_config(lif, IONIC_RSS_OFFLOAD_ALL,
+			toeplitz_symmetric_key, NULL);
 }
 
 static void
@@ -1578,9 +1577,6 @@ ionic_lif_start(struct ionic_lif *lif)
 	uint32_t i;
 	int err;
 
-	IONIC_PRINT(DEBUG, "Setting RSS configuration on port %u",
-		lif->port_id);
-
 	err = ionic_lif_rss_setup(lif);
 	if (err)
 		return err;
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index 8e2b42443..b80931c61 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -108,6 +108,7 @@ struct ionic_lif {
 	uint8_t *rss_ind_tbl;
 	rte_iova_t rss_ind_tbl_pa;
 	const struct rte_memzone *rss_ind_tbl_z;
+	uint32_t rss_ind_tbl_nrxqcqs;
 	uint32_t info_sz;
 	struct ionic_lif_info *info;
 	rte_iova_t info_pa;
-- 
2.17.1


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

* [dpdk-dev] [PATCH 2/6] net/ionic: preserve RX mode across LIF stop/start
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 1/6] net/ionic: preserve RSS state unless RETA size changes Andrew Boyer
@ 2020-12-10 14:22 ` Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 3/6] net/ionic: fully implement remove-on-close Andrew Boyer
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-10 14:22 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Otherwise, non-default settings (like PROMISC) get reset.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_lif.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 646c921b2..875c7e585 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -1573,7 +1573,7 @@ ionic_lif_configure(struct ionic_lif *lif)
 int
 ionic_lif_start(struct ionic_lif *lif)
 {
-	uint32_t rx_mode = 0;
+	uint32_t rx_mode;
 	uint32_t i;
 	int err;
 
@@ -1581,16 +1581,16 @@ ionic_lif_start(struct ionic_lif *lif)
 	if (err)
 		return err;
 
-	IONIC_PRINT(DEBUG, "Setting RX mode on port %u",
-		lif->port_id);
-
-	rx_mode |= IONIC_RX_MODE_F_UNICAST;
-	rx_mode |= IONIC_RX_MODE_F_MULTICAST;
-	rx_mode |= IONIC_RX_MODE_F_BROADCAST;
+	if (!lif->rx_mode) {
+		IONIC_PRINT(DEBUG, "Setting RX mode on %s",
+			lif->name);
 
-	lif->rx_mode = 0; /* set by ionic_set_rx_mode */
+		rx_mode  = IONIC_RX_MODE_F_UNICAST;
+		rx_mode |= IONIC_RX_MODE_F_MULTICAST;
+		rx_mode |= IONIC_RX_MODE_F_BROADCAST;
 
-	ionic_set_rx_mode(lif, rx_mode);
+		ionic_set_rx_mode(lif, rx_mode);
+	}
 
 	IONIC_PRINT(DEBUG, "Starting %u RX queues and %u TX queues "
 		"on port %u",
-- 
2.17.1


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

* [dpdk-dev] [PATCH 3/6] net/ionic: fully implement remove-on-close
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 1/6] net/ionic: preserve RSS state unless RETA size changes Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 2/6] net/ionic: preserve RX mode across LIF stop/start Andrew Boyer
@ 2020-12-10 14:22 ` Andrew Boyer
  2020-12-15 13:42   ` Ferruh Yigit
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 4/6] net/ionic: improve link state handling Andrew Boyer
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 19+ messages in thread
From: Andrew Boyer @ 2020-12-10 14:22 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

This is now required behavior for a PMD.
Remove the UNMAINTAINED flag.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 MAINTAINERS                      |  2 +-
 drivers/net/ionic/ionic_ethdev.c | 41 ++++++++++++++++----------------
 drivers/net/ionic/ionic_lif.c    | 15 ++++++++++++
 drivers/net/ionic/ionic_lif.h    |  1 +
 4 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7bc0010f2..fc1b09923 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -840,7 +840,7 @@ F: doc/guides/nics/pfe.rst
 F: drivers/net/pfe/
 F: doc/guides/nics/features/pfe.ini
 
-Pensando ionic - UNMAINTAINED
+Pensando ionic
 M: Andrew Boyer <aboyer@pensando.io>
 F: drivers/net/ionic/
 F: doc/guides/nics/ionic.rst
diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index 5a360ac08..629d7068b 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -958,6 +958,8 @@ ionic_dev_stop(struct rte_eth_dev *eth_dev)
 	return err;
 }
 
+static void ionic_unconfigure_intr(struct ionic_adapter *adapter);
+
 /*
  * Reset and stop device.
  */
@@ -965,6 +967,8 @@ static int
 ionic_dev_close(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+	struct ionic_adapter *adapter = lif->adapter;
+	uint32_t i;
 	int err;
 
 	IONIC_PRINT_CALL();
@@ -977,12 +981,21 @@ ionic_dev_close(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	err = eth_ionic_dev_uninit(eth_dev);
-	if (err) {
-		IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err);
-		return -1;
+	ionic_lif_free_queues(lif);
+
+	IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name);
+	ionic_unconfigure_intr(adapter);
+
+	for (i = 0; i < adapter->nlifs; i++) {
+		lif = adapter->lifs[i];
+		rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);
 	}
 
+	ionic_port_reset(adapter);
+	ionic_reset(adapter);
+
+	rte_free(adapter);
+
 	return 0;
 }
 
@@ -1280,10 +1293,7 @@ static int
 eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
-	struct ionic_adapter *adapter = NULL;
 	struct rte_eth_dev *eth_dev;
-	struct ionic_lif *lif;
-	uint32_t i;
 
 	/* Adapter lookup is using (the first) eth_dev name */
 	snprintf(name, sizeof(name), "net_%s_lif_0",
@@ -1291,19 +1301,10 @@ eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
 
 	eth_dev = rte_eth_dev_allocated(name);
 	if (eth_dev) {
-		lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-		adapter = lif->adapter;
-	}
-
-	if (adapter) {
-		ionic_unconfigure_intr(adapter);
-
-		for (i = 0; i < adapter->nlifs; i++) {
-			lif = adapter->lifs[i];
-			rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);
-		}
-
-		rte_free(adapter);
+		ionic_dev_close(eth_dev);
+	} else {
+		IONIC_PRINT(WARNING, "Cannot find device %s",
+			pci_dev->device.name);
 	}
 
 	return 0;
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 875c7e585..e213597ee 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -927,6 +927,21 @@ ionic_lif_free(struct ionic_lif *lif)
 	}
 }
 
+void
+ionic_lif_free_queues(struct ionic_lif *lif)
+{
+	uint32_t i;
+
+	for (i = 0; i < lif->ntxqcqs; i++) {
+		ionic_dev_tx_queue_release(lif->eth_dev->data->tx_queues[i]);
+		lif->eth_dev->data->tx_queues[i] = NULL;
+	}
+	for (i = 0; i < lif->nrxqcqs; i++) {
+		ionic_dev_rx_queue_release(lif->eth_dev->data->rx_queues[i]);
+		lif->eth_dev->data->rx_queues[i] = NULL;
+	}
+}
+
 int
 ionic_lif_rss_config(struct ionic_lif *lif,
 		const uint16_t types, const uint8_t *key, const uint32_t *indir)
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index b80931c61..bf010716e 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -122,6 +122,7 @@ int ionic_lifs_size(struct ionic_adapter *ionic);
 
 int ionic_lif_alloc(struct ionic_lif *lif);
 void ionic_lif_free(struct ionic_lif *lif);
+void ionic_lif_free_queues(struct ionic_lif *lif);
 
 int ionic_lif_init(struct ionic_lif *lif);
 void ionic_lif_deinit(struct ionic_lif *lif);
-- 
2.17.1


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

* [dpdk-dev] [PATCH 4/6] net/ionic: improve link state handling
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (2 preceding siblings ...)
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 3/6] net/ionic: fully implement remove-on-close Andrew Boyer
@ 2020-12-10 14:22 ` Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 5/6] net/ionic: improve queue " Andrew Boyer
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-10 14:22 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Add UP and FW_RESET state flags.
Update the stack info when the link state changes.
Convert set_link_up/set_link_down to lif_start/lif_stop.
Condition reported link state on UP flag.
Change lif_stop to return void.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_ethdev.c | 49 ++++++++++---------------------
 drivers/net/ionic/ionic_ethdev.h |  4 +++
 drivers/net/ionic/ionic_lif.c    | 50 ++++++++++++++++++++++++++------
 drivers/net/ionic/ionic_lif.h    |  4 ++-
 4 files changed, 64 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index 629d7068b..973c03a8d 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -28,8 +28,6 @@ static int  ionic_dev_stop(struct rte_eth_dev *dev);
 static int  ionic_dev_close(struct rte_eth_dev *dev);
 static int  ionic_dev_set_link_up(struct rte_eth_dev *dev);
 static int  ionic_dev_set_link_down(struct rte_eth_dev *dev);
-static int  ionic_dev_link_update(struct rte_eth_dev *eth_dev,
-	int wait_to_complete);
 static int  ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev,
 	struct rte_eth_fc_conf *fc_conf);
 static int  ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev,
@@ -236,21 +234,17 @@ static int
 ionic_dev_set_link_up(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-	struct ionic_adapter *adapter = lif->adapter;
-	struct ionic_dev *idev = &adapter->idev;
 	int err;
 
 	IONIC_PRINT_CALL();
 
-	ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP);
+	err = ionic_lif_start(lif);
+	if (err)
+		IONIC_PRINT(ERR, "Could not start lif to set link up");
 
-	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
-	if (err) {
-		IONIC_PRINT(WARNING, "Failed to bring port UP");
-		return err;
-	}
+	ionic_dev_link_update(lif->eth_dev, 0);
 
-	return 0;
+	return err;
 }
 
 /*
@@ -260,24 +254,17 @@ static int
 ionic_dev_set_link_down(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-	struct ionic_adapter *adapter = lif->adapter;
-	struct ionic_dev *idev = &adapter->idev;
-	int err;
 
 	IONIC_PRINT_CALL();
 
-	ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_DOWN);
+	ionic_lif_stop(lif);
 
-	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
-	if (err) {
-		IONIC_PRINT(WARNING, "Failed to bring port DOWN");
-		return err;
-	}
+	ionic_dev_link_update(lif->eth_dev, 0);
 
 	return 0;
 }
 
-static int
+int
 ionic_dev_link_update(struct rte_eth_dev *eth_dev,
 		int wait_to_complete __rte_unused)
 {
@@ -291,7 +278,8 @@ ionic_dev_link_update(struct rte_eth_dev *eth_dev,
 	memset(&link, 0, sizeof(link));
 	link.link_autoneg = ETH_LINK_AUTONEG;
 
-	if (!adapter->link_up) {
+	if (!adapter->link_up ||
+	    !(lif->state & IONIC_LIF_F_UP)) {
 		/* Interface is down */
 		link.link_status = ETH_LINK_DOWN;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
@@ -947,15 +935,12 @@ static int
 ionic_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-	int err;
 
 	IONIC_PRINT_CALL();
 
-	err = ionic_lif_stop(lif);
-	if (err)
-		IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
+	ionic_lif_stop(lif);
 
-	return err;
+	return 0;
 }
 
 static void ionic_unconfigure_intr(struct ionic_adapter *adapter);
@@ -969,17 +954,12 @@ ionic_dev_close(struct rte_eth_dev *eth_dev)
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
 	struct ionic_adapter *adapter = lif->adapter;
 	uint32_t i;
-	int err;
 
 	IONIC_PRINT_CALL();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	err = ionic_lif_stop(lif);
-	if (err) {
-		IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
-		return -1;
-	}
+	ionic_lif_stop(lif);
 
 	ionic_lif_free_queues(lif);
 
@@ -1084,6 +1064,9 @@ eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev)
 	ionic_lif_deinit(lif);
 	ionic_lif_free(lif);
 
+	if (!(lif->state & IONIC_LIF_F_FW_RESET))
+		ionic_lif_reset(lif);
+
 	return 0;
 }
 
diff --git a/drivers/net/ionic/ionic_ethdev.h b/drivers/net/ionic/ionic_ethdev.h
index 578e2301f..6cbcd0f82 100644
--- a/drivers/net/ionic/ionic_ethdev.h
+++ b/drivers/net/ionic/ionic_ethdev.h
@@ -5,6 +5,8 @@
 #ifndef _IONIC_ETHDEV_H_
 #define _IONIC_ETHDEV_H_
 
+#include <rte_ethdev.h>
+
 #define IONIC_ETH_RSS_OFFLOAD_ALL ( \
 	ETH_RSS_IPV4 | \
 	ETH_RSS_NONFRAG_IPV4_TCP | \
@@ -18,5 +20,7 @@
 #define IONIC_ETH_DEV_TO_ADAPTER(eth_dev) \
 	(IONIC_ETH_DEV_TO_LIF(eth_dev)->adapter)
 
+int ionic_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete);
+
 #endif /* _IONIC_ETHDEV_H_ */
 
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index e213597ee..2452451be 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -65,12 +65,12 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
 	return ionic_adminq_post_wait(lif, &ctx);
 }
 
-int
-ionic_lif_stop(struct ionic_lif *lif __rte_unused)
+void
+ionic_lif_stop(struct ionic_lif *lif)
 {
-	/* Carrier OFF here */
+	IONIC_PRINT_CALL();
 
-	return 0;
+	lif->state &= ~IONIC_LIF_F_UP;
 }
 
 void
@@ -1105,14 +1105,32 @@ ionic_link_status_check(struct ionic_lif *lif)
 		return;
 
 	if (link_up) {
-		IONIC_PRINT(DEBUG, "Link up - %d Gbps",
-			lif->info->status.link_speed);
 		adapter->link_speed = lif->info->status.link_speed;
+		IONIC_PRINT(DEBUG, "Link up - %d Gbps",
+			adapter->link_speed);
 	} else {
 		IONIC_PRINT(DEBUG, "Link down");
 	}
 
 	adapter->link_up = link_up;
+	ionic_dev_link_update(lif->eth_dev, 0);
+}
+
+static void
+ionic_lif_handle_fw_down(struct ionic_lif *lif)
+{
+	if (lif->state & IONIC_LIF_F_FW_RESET)
+		return;
+
+	lif->state |= IONIC_LIF_F_FW_RESET;
+
+	if (lif->state & IONIC_LIF_F_UP) {
+		IONIC_PRINT(NOTICE,
+			"Surprise FW stop, stopping %s\n", lif->name);
+		ionic_lif_stop(lif);
+	}
+
+	IONIC_PRINT(NOTICE, "FW down, %s stopped", lif->name);
 }
 
 static bool
@@ -1134,14 +1152,27 @@ ionic_notifyq_cb(struct ionic_cq *cq, uint32_t cq_desc_index, void *cb_arg)
 	switch (cq_desc->event.ecode) {
 	case IONIC_EVENT_LINK_CHANGE:
 		IONIC_PRINT(DEBUG,
-			"Notifyq IONIC_EVENT_LINK_CHANGE eid=%jd link_status=%d link_speed=%d",
+			"Notifyq IONIC_EVENT_LINK_CHANGE %s "
+			"eid=%jd link_status=%d link_speed=%d",
+			lif->name,
 			cq_desc->event.eid,
 			cq_desc->link_change.link_status,
 			cq_desc->link_change.link_speed);
 
 		lif->state |= IONIC_LIF_F_LINK_CHECK_NEEDED;
+		break;
 
+	case IONIC_EVENT_RESET:
+		IONIC_PRINT(NOTICE,
+			"Notifyq IONIC_EVENT_RESET %s "
+			"eid=%jd, reset_code=%d state=%d",
+			lif->name,
+			cq_desc->event.eid,
+			cq_desc->reset.reset_code,
+			cq_desc->reset.state);
+		ionic_lif_handle_fw_down(lif);
 		break;
+
 	default:
 		IONIC_PRINT(WARNING, "Notifyq bad event ecode=%d eid=%jd",
 			cq_desc->event.ecode, cq_desc->event.eid);
@@ -1631,9 +1662,10 @@ ionic_lif_start(struct ionic_lif *lif)
 		}
 	}
 
-	ionic_link_status_check(lif);
-
 	/* Carrier ON here */
+	lif->state |= IONIC_LIF_F_UP;
+
+	ionic_link_status_check(lif);
 
 	return 0;
 }
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index bf010716e..d11909746 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -77,6 +77,8 @@ struct ionic_qcq {
 
 #define IONIC_LIF_F_INITED		BIT(0)
 #define IONIC_LIF_F_LINK_CHECK_NEEDED	BIT(1)
+#define IONIC_LIF_F_UP			BIT(2)
+#define IONIC_LIF_F_FW_RESET		BIT(3)
 
 #define IONIC_LIF_NAME_MAX_SZ		(32)
 
@@ -128,7 +130,7 @@ int ionic_lif_init(struct ionic_lif *lif);
 void ionic_lif_deinit(struct ionic_lif *lif);
 
 int ionic_lif_start(struct ionic_lif *lif);
-int ionic_lif_stop(struct ionic_lif *lif);
+void ionic_lif_stop(struct ionic_lif *lif);
 
 int ionic_lif_configure(struct ionic_lif *lif);
 void ionic_lif_reset(struct ionic_lif *lif);
-- 
2.17.1


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

* [dpdk-dev] [PATCH 5/6] net/ionic: improve queue state handling
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (3 preceding siblings ...)
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 4/6] net/ionic: improve link state handling Andrew Boyer
@ 2020-12-10 14:22 ` Andrew Boyer
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 6/6] net/ionic: stop queues when LIF is stopped Andrew Boyer
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-10 14:22 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Skip ionic_lif_[rxq|txq]_init() in queue start if it's already done.
Move ionic_lif_[rxq|txq]_deinit() from queue stop to queue release.

This allows the queues to be restarted.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_rxtx.c | 62 +++++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ionic/ionic_rxtx.c b/drivers/net/ionic/ionic_rxtx.c
index b689c8381..d06f1246c 100644
--- a/drivers/net/ionic/ionic_rxtx.c
+++ b/drivers/net/ionic/ionic_rxtx.c
@@ -125,6 +125,8 @@ ionic_dev_tx_queue_release(void *tx_queue)
 
 	IONIC_PRINT_CALL();
 
+	ionic_lif_txq_deinit(txq);
+
 	ionic_qcq_free(txq);
 }
 
@@ -137,6 +139,9 @@ ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 
 	txq = eth_dev->data->tx_queues[tx_queue_id];
 
+	eth_dev->data->tx_queue_state[tx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	/*
 	 * Note: we should better post NOP Tx desc and wait for its completion
 	 * before disabling Tx queue
@@ -146,11 +151,6 @@ ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 
 	ionic_tx_flush(&txq->cq);
 
-	ionic_lif_txq_deinit(txq);
-
-	eth_dev->data->tx_queue_state[tx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STOPPED;
-
 	return 0;
 }
 
@@ -187,6 +187,9 @@ ionic_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id,
 		eth_dev->data->tx_queues[tx_queue_id] = NULL;
 	}
 
+	eth_dev->data->tx_queue_state[tx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	err = ionic_tx_qcq_alloc(lif, tx_queue_id, nb_desc, &txq);
 	if (err) {
 		IONIC_PRINT(DEBUG, "Queue allocation failure");
@@ -210,22 +213,30 @@ ionic_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id,
 int __rte_cold
 ionic_dev_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 {
+	uint8_t *tx_queue_state = eth_dev->data->tx_queue_state;
 	struct ionic_qcq *txq;
 	int err;
 
+	if (tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STARTED) {
+		IONIC_PRINT(DEBUG, "TX queue %u already started",
+			tx_queue_id);
+		return 0;
+	}
+
 	txq = eth_dev->data->tx_queues[tx_queue_id];
 
 	IONIC_PRINT(DEBUG, "Starting TX queue %u, %u descs",
 		tx_queue_id, txq->q.num_descs);
 
-	err = ionic_lif_txq_init(txq);
-	if (err)
-		return err;
+	if (!(txq->flags & IONIC_QCQ_F_INITED)) {
+		err = ionic_lif_txq_init(txq);
+		if (err)
+			return err;
+	}
 
 	ionic_qcq_enable(txq);
 
-	eth_dev->data->tx_queue_state[tx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STARTED;
+	tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
 
 	return 0;
 }
@@ -634,6 +645,8 @@ ionic_dev_rx_queue_release(void *rx_queue)
 
 	ionic_rx_empty(&rxq->q);
 
+	ionic_lif_rxq_deinit(rxq);
+
 	ionic_qcq_free(rxq);
 }
 
@@ -682,6 +695,9 @@ ionic_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 		eth_dev->data->rx_queues[rx_queue_id] = NULL;
 	}
 
+	eth_dev->data->rx_queue_state[rx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	err = ionic_rx_qcq_alloc(lif, rx_queue_id, nb_desc, &rxq);
 	if (err) {
 		IONIC_PRINT(ERR, "Queue %d allocation failure", rx_queue_id);
@@ -953,17 +969,26 @@ int __rte_cold
 ionic_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 {
 	uint32_t frame_size = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
+	uint8_t *rx_queue_state = eth_dev->data->rx_queue_state;
 	struct ionic_qcq *rxq;
 	int err;
 
+	if (rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STARTED) {
+		IONIC_PRINT(DEBUG, "RX queue %u already started",
+			rx_queue_id);
+		return 0;
+	}
+
 	rxq = eth_dev->data->rx_queues[rx_queue_id];
 
 	IONIC_PRINT(DEBUG, "Starting RX queue %u, %u descs (size: %u)",
 		rx_queue_id, rxq->q.num_descs, frame_size);
 
-	err = ionic_lif_rxq_init(rxq);
-	if (err)
-		return err;
+	if (!(rxq->flags & IONIC_QCQ_F_INITED)) {
+		err = ionic_lif_rxq_init(rxq);
+		if (err)
+			return err;
+	}
 
 	/* Allocate buffers for descriptor rings */
 	if (ionic_rx_fill(rxq, frame_size) != 0) {
@@ -974,8 +999,7 @@ ionic_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 
 	ionic_qcq_enable(rxq);
 
-	eth_dev->data->rx_queue_state[rx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STARTED;
+	rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
 
 	return 0;
 }
@@ -1044,16 +1068,14 @@ ionic_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 
 	rxq = eth_dev->data->rx_queues[rx_queue_id];
 
+	eth_dev->data->rx_queue_state[rx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	ionic_qcq_disable(rxq);
 
 	/* Flush */
 	ionic_rxq_service(&rxq->cq, -1, NULL);
 
-	ionic_lif_rxq_deinit(rxq);
-
-	eth_dev->data->rx_queue_state[rx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STOPPED;
-
 	return 0;
 }
 
-- 
2.17.1


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

* [dpdk-dev] [PATCH 6/6] net/ionic: stop queues when LIF is stopped
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (4 preceding siblings ...)
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 5/6] net/ionic: improve queue " Andrew Boyer
@ 2020-12-10 14:22 ` Andrew Boyer
  2020-12-15 14:01 ` [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Ferruh Yigit
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-10 14:22 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Otherwise they can not be restarted.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_lif.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 2452451be..98797b22b 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -68,9 +68,23 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
 void
 ionic_lif_stop(struct ionic_lif *lif)
 {
+	uint32_t i;
+
 	IONIC_PRINT_CALL();
 
 	lif->state &= ~IONIC_LIF_F_UP;
+
+	for (i = 0; i < lif->nrxqcqs; i++) {
+		struct ionic_qcq *rxq = lif->rxqcqs[i];
+		if (rxq->flags & IONIC_QCQ_F_INITED)
+			(void)ionic_dev_rx_queue_stop(lif->eth_dev, i);
+	}
+
+	for (i = 0; i < lif->ntxqcqs; i++) {
+		struct ionic_qcq *txq = lif->txqcqs[i];
+		if (txq->flags & IONIC_QCQ_F_INITED)
+			(void)ionic_dev_tx_queue_stop(lif->eth_dev, i);
+	}
 }
 
 void
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH 3/6] net/ionic: fully implement remove-on-close
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 3/6] net/ionic: fully implement remove-on-close Andrew Boyer
@ 2020-12-15 13:42   ` Ferruh Yigit
  2020-12-16 19:52     ` Andrew Boyer
  0 siblings, 1 reply; 19+ messages in thread
From: Ferruh Yigit @ 2020-12-15 13:42 UTC (permalink / raw)
  To: Andrew Boyer, dev; +Cc: Alfredo Cardigliano

On 12/10/2020 2:22 PM, Andrew Boyer wrote:
> This is now required behavior for a PMD.
> Remove the UNMAINTAINED flag.
> 
> Signed-off-by: Andrew Boyer <aboyer@pensando.io>
> ---
>   MAINTAINERS                      |  2 +-
>   drivers/net/ionic/ionic_ethdev.c | 41 ++++++++++++++++----------------
>   drivers/net/ionic/ionic_lif.c    | 15 ++++++++++++
>   drivers/net/ionic/ionic_lif.h    |  1 +
>   4 files changed, 38 insertions(+), 21 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7bc0010f2..fc1b09923 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -840,7 +840,7 @@ F: doc/guides/nics/pfe.rst
>   F: drivers/net/pfe/
>   F: doc/guides/nics/features/pfe.ini
>   
> -Pensando ionic - UNMAINTAINED
> +Pensando ionic
>   M: Andrew Boyer <aboyer@pensando.io>
>   F: drivers/net/ionic/
>   F: doc/guides/nics/ionic.rst
> diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
> index 5a360ac08..629d7068b 100644
> --- a/drivers/net/ionic/ionic_ethdev.c
> +++ b/drivers/net/ionic/ionic_ethdev.c
> @@ -958,6 +958,8 @@ ionic_dev_stop(struct rte_eth_dev *eth_dev)
>   	return err;
>   }
>   
> +static void ionic_unconfigure_intr(struct ionic_adapter *adapter);
> +
>   /*
>    * Reset and stop device.
>    */
> @@ -965,6 +967,8 @@ static int
>   ionic_dev_close(struct rte_eth_dev *eth_dev)
>   {
>   	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
> +	struct ionic_adapter *adapter = lif->adapter;
> +	uint32_t i;
>   	int err;
>   
>   	IONIC_PRINT_CALL();
> @@ -977,12 +981,21 @@ ionic_dev_close(struct rte_eth_dev *eth_dev)
>   		return -1;
>   	}
>   
> -	err = eth_ionic_dev_uninit(eth_dev);
> -	if (err) {
> -		IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err);
> -		return -1;
> +	ionic_lif_free_queues(lif);
> +
> +	IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name);
> +	ionic_unconfigure_intr(adapter);
> +
> +	for (i = 0; i < adapter->nlifs; i++) {
> +		lif = adapter->lifs[i];
> +		rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);

Should 'ionic_lif_stop()' & 'ionic_lif_free_queues()' be called per 'lif' here?

>   	}
>   
> +	ionic_port_reset(adapter);
> +	ionic_reset(adapter);
> +
> +	rte_free(adapter);
> +

In ionic, an ethdev is created per 'lif' during probe and when one of the ethdev 
closed, all 'lif' destroyed and 'adapter' freed, so all ethdev should be 
unusable at this stage.
1) First better to document this behavior in the commit log, and as overall can 
you please prefer more descriptive commit logs.

2) What happens to the ethdev statuses, 'lif' destroyed and ethdev are not 
usable but ethdev status not updated or freed?
What happens if the application tries to access to ethdev of another 'lif' after 
'ionic_dev_close()'?

>   	return 0;
>   }
>   
> @@ -1280,10 +1293,7 @@ static int
>   eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
>   {
>   	char name[RTE_ETH_NAME_MAX_LEN];
> -	struct ionic_adapter *adapter = NULL;
>   	struct rte_eth_dev *eth_dev;
> -	struct ionic_lif *lif;
> -	uint32_t i;
>   
>   	/* Adapter lookup is using (the first) eth_dev name */
>   	snprintf(name, sizeof(name), "net_%s_lif_0",
> @@ -1291,19 +1301,10 @@ eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
>   

Should remove '__rte_unused'

>   	eth_dev = rte_eth_dev_allocated(name);
>   	if (eth_dev) {
> -		lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
> -		adapter = lif->adapter;
> -	}
> -
> -	if (adapter) {
> -		ionic_unconfigure_intr(adapter);
> -
> -		for (i = 0; i < adapter->nlifs; i++) {
> -			lif = adapter->lifs[i];
> -			rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);
> -		}
> -
> -		rte_free(adapter);
> +		ionic_dev_close(eth_dev);
> +	} else {
> +		IONIC_PRINT(WARNING, "Cannot find device %s",
> +			pci_dev->device.name);

Not sure if this warning is correct, if there is no allocated ethdev this is not 
an error, this means there is nothing to remove and function can continue with 
'return 0'


>   	}
>   
>   	return 0;
> diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
> index 875c7e585..e213597ee 100644
> --- a/drivers/net/ionic/ionic_lif.c
> +++ b/drivers/net/ionic/ionic_lif.c
> @@ -927,6 +927,21 @@ ionic_lif_free(struct ionic_lif *lif)
>   	}
>   }
>   
> +void
> +ionic_lif_free_queues(struct ionic_lif *lif)
> +{
> +	uint32_t i;
> +
> +	for (i = 0; i < lif->ntxqcqs; i++) {
> +		ionic_dev_tx_queue_release(lif->eth_dev->data->tx_queues[i]);
> +		lif->eth_dev->data->tx_queues[i] = NULL;
> +	}
> +	for (i = 0; i < lif->nrxqcqs; i++) {
> +		ionic_dev_rx_queue_release(lif->eth_dev->data->rx_queues[i]);
> +		lif->eth_dev->data->rx_queues[i] = NULL;
> +	}
> +}
> +
>   int
>   ionic_lif_rss_config(struct ionic_lif *lif,
>   		const uint16_t types, const uint8_t *key, const uint32_t *indir)
> diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
> index b80931c61..bf010716e 100644
> --- a/drivers/net/ionic/ionic_lif.h
> +++ b/drivers/net/ionic/ionic_lif.h
> @@ -122,6 +122,7 @@ int ionic_lifs_size(struct ionic_adapter *ionic);
>   
>   int ionic_lif_alloc(struct ionic_lif *lif);
>   void ionic_lif_free(struct ionic_lif *lif);
> +void ionic_lif_free_queues(struct ionic_lif *lif);
>   
>   int ionic_lif_init(struct ionic_lif *lif);
>   void ionic_lif_deinit(struct ionic_lif *lif);
> 


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

* Re: [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (5 preceding siblings ...)
  2020-12-10 14:22 ` [dpdk-dev] [PATCH 6/6] net/ionic: stop queues when LIF is stopped Andrew Boyer
@ 2020-12-15 14:01 ` Ferruh Yigit
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 0/7] " Andrew Boyer
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Ferruh Yigit @ 2020-12-15 14:01 UTC (permalink / raw)
  To: Andrew Boyer, dev; +Cc: Alfredo Cardigliano

On 12/10/2020 2:22 PM, Andrew Boyer wrote:
> These patches address issues found when testing port stop and start,
> link up and down, and queue stop and start.
> 
> The UNMAINTAINED flag is removed in patch 3.
> 
> Signed-off-by: Andrew Boyer <aboyer@pensando.io>
> 
> Andrew Boyer (6):
>    net/ionic: preserve RSS state unless RETA size changes
>    net/ionic: preserve RX mode across LIF stop/start
>    net/ionic: fully implement remove-on-close
>    net/ionic: improve link state handling
>    net/ionic: improve queue state handling
>    net/ionic: stop queues when LIF is stopped
> 

Can you also run './devtools/check-git-log.sh' checks and fix warnings please?
It is used as "./devtools/check-git-log.sh -n6".

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

* Re: [dpdk-dev] [PATCH 3/6] net/ionic: fully implement remove-on-close
  2020-12-15 13:42   ` Ferruh Yigit
@ 2020-12-16 19:52     ` Andrew Boyer
  0 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 19:52 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Alfredo Cardigliano

Hello Ferruh,

> On Dec 15, 2020, at 8:42 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
> On 12/10/2020 2:22 PM, Andrew Boyer wrote:
>> This is now required behavior for a PMD.
>> Remove the UNMAINTAINED flag.
>> Signed-off-by: Andrew Boyer <aboyer@pensando.io>
>> ---
>>  MAINTAINERS                      |  2 +-
>>  drivers/net/ionic/ionic_ethdev.c | 41 ++++++++++++++++----------------
>>  drivers/net/ionic/ionic_lif.c    | 15 ++++++++++++
>>  drivers/net/ionic/ionic_lif.h    |  1 +
>>  4 files changed, 38 insertions(+), 21 deletions(-)
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 7bc0010f2..fc1b09923 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -840,7 +840,7 @@ F: doc/guides/nics/pfe.rst
>>  F: drivers/net/pfe/
>>  F: doc/guides/nics/features/pfe.ini
>>  -Pensando ionic - UNMAINTAINED
>> +Pensando ionic
>>  M: Andrew Boyer <aboyer@pensando.io>
>>  F: drivers/net/ionic/
>>  F: doc/guides/nics/ionic.rst
>> diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
>> index 5a360ac08..629d7068b 100644
>> --- a/drivers/net/ionic/ionic_ethdev.c
>> +++ b/drivers/net/ionic/ionic_ethdev.c
>> @@ -958,6 +958,8 @@ ionic_dev_stop(struct rte_eth_dev *eth_dev)
>>  	return err;
>>  }
>>  +static void ionic_unconfigure_intr(struct ionic_adapter *adapter);
>> +
>>  /*
>>   * Reset and stop device.
>>   */
>> @@ -965,6 +967,8 @@ static int
>>  ionic_dev_close(struct rte_eth_dev *eth_dev)
>>  {
>>  	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
>> +	struct ionic_adapter *adapter = lif->adapter;
>> +	uint32_t i;
>>  	int err;
>>    	IONIC_PRINT_CALL();
>> @@ -977,12 +981,21 @@ ionic_dev_close(struct rte_eth_dev *eth_dev)
>>  		return -1;
>>  	}
>>  -	err = eth_ionic_dev_uninit(eth_dev);
>> -	if (err) {
>> -		IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err);
>> -		return -1;
>> +	ionic_lif_free_queues(lif);
>> +
>> +	IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name);
>> +	ionic_unconfigure_intr(adapter);
>> +
>> +	for (i = 0; i < adapter->nlifs; i++) {
>> +		lif = adapter->lifs[i];
>> +		rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);
> 
> Should 'ionic_lif_stop()' & 'ionic_lif_free_queues()' be called per 'lif' here?

You are correct. A future patch removes multi-lif support - it is unused. So this is a result of how I broke up the changes. See below.

>>  	}
>>  +	ionic_port_reset(adapter);
>> +	ionic_reset(adapter);
>> +
>> +	rte_free(adapter);
>> +
> 
> In ionic, an ethdev is created per 'lif' during probe and when one of the ethdev closed, all 'lif' destroyed and 'adapter' freed, so all ethdev should be unusable at this stage.
> 1) First better to document this behavior in the commit log, and as overall can you please prefer more descriptive commit logs.

Sure, I will add more detail to commit logs.

> 2) What happens to the ethdev statuses, 'lif' destroyed and ethdev are not usable but ethdev status not updated or freed?
> What happens if the application tries to access to ethdev of another 'lif' after 'ionic_dev_close()'?

I see what you’re saying, we get here from eth_dev_ops.dev_close -> ionic_dev_close(), so the first ethdev to get closed brings down the adapter etc.

In reality we are going to have one adapter <-> one lif <-> one ethdev, so closing the ethdev will be the end of everything. (Just for this PF/VF; they are independent.)
Rather than doing any design work to fix this I will reorder the patches to take out multi-lif support first.

-Andrew

> 
>>  	return 0;
>>  }
>>  @@ -1280,10 +1293,7 @@ static int
>>  eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
>>  {
>>  	char name[RTE_ETH_NAME_MAX_LEN];
>> -	struct ionic_adapter *adapter = NULL;
>>  	struct rte_eth_dev *eth_dev;
>> -	struct ionic_lif *lif;
>> -	uint32_t i;
>>    	/* Adapter lookup is using (the first) eth_dev name */
>>  	snprintf(name, sizeof(name), "net_%s_lif_0",
>> @@ -1291,19 +1301,10 @@ eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
>>  
> 
> Should remove '__rte_unused'

OK

> 
>>  	eth_dev = rte_eth_dev_allocated(name);
>>  	if (eth_dev) {
>> -		lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
>> -		adapter = lif->adapter;
>> -	}
>> -
>> -	if (adapter) {
>> -		ionic_unconfigure_intr(adapter);
>> -
>> -		for (i = 0; i < adapter->nlifs; i++) {
>> -			lif = adapter->lifs[i];
>> -			rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);
>> -		}
>> -
>> -		rte_free(adapter);
>> +		ionic_dev_close(eth_dev);
>> +	} else {
>> +		IONIC_PRINT(WARNING, "Cannot find device %s",
>> +			pci_dev->device.name);
> 
> Not sure if this warning is correct, if there is no allocated ethdev this is not an error, this means there is nothing to remove and function can continue with 'return 0'

OK, I will reduce it to DEBUG level.

>>  	}
>>    	return 0;
>> diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
>> index 875c7e585..e213597ee 100644
>> --- a/drivers/net/ionic/ionic_lif.c
>> +++ b/drivers/net/ionic/ionic_lif.c
>> @@ -927,6 +927,21 @@ ionic_lif_free(struct ionic_lif *lif)
>>  	}
>>  }
>>  +void
>> +ionic_lif_free_queues(struct ionic_lif *lif)
>> +{
>> +	uint32_t i;
>> +
>> +	for (i = 0; i < lif->ntxqcqs; i++) {
>> +		ionic_dev_tx_queue_release(lif->eth_dev->data->tx_queues[i]);
>> +		lif->eth_dev->data->tx_queues[i] = NULL;
>> +	}
>> +	for (i = 0; i < lif->nrxqcqs; i++) {
>> +		ionic_dev_rx_queue_release(lif->eth_dev->data->rx_queues[i]);
>> +		lif->eth_dev->data->rx_queues[i] = NULL;
>> +	}
>> +}
>> +
>>  int
>>  ionic_lif_rss_config(struct ionic_lif *lif,
>>  		const uint16_t types, const uint8_t *key, const uint32_t *indir)
>> diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
>> index b80931c61..bf010716e 100644
>> --- a/drivers/net/ionic/ionic_lif.h
>> +++ b/drivers/net/ionic/ionic_lif.h
>> @@ -122,6 +122,7 @@ int ionic_lifs_size(struct ionic_adapter *ionic);
>>    int ionic_lif_alloc(struct ionic_lif *lif);
>>  void ionic_lif_free(struct ionic_lif *lif);
>> +void ionic_lif_free_queues(struct ionic_lif *lif);
>>    int ionic_lif_init(struct ionic_lif *lif);
>>  void ionic_lif_deinit(struct ionic_lif *lif);


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

* [dpdk-dev] [PATCH v2 0/7] net/ionic: fixes for stop and start
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (6 preceding siblings ...)
  2020-12-15 14:01 ` [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Ferruh Yigit
@ 2020-12-16 21:12 ` Andrew Boyer
  2021-01-11 17:08   ` Ferruh Yigit
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 1/7] net/ionic: preserve RSS state unless RETA size changes Andrew Boyer
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

These patches address issues found when testing port stop and start,
link up and down, and queue stop and start.

The UNMAINTAINED flag is removed in patch 3.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>

---
v2:
* Address Ferruh's comments
* Insert a new patch "net/ionic: remove multi-LIF support" so that the
  patch "net/ionic: fully implement remove-on-close" makes sense

Andrew Boyer (7):
  net/ionic: preserve RSS state unless RETA size changes
  net/ionic: preserve Rx mode across LIF stop/start
  net/ionic: remove multi-LIF support
  net/ionic: fully implement remove-on-close
  net/ionic: improve link state handling
  net/ionic: improve queue state handling
  net/ionic: stop queues when LIF is stopped

 MAINTAINERS                      |   2 +-
 drivers/net/ionic/ionic.h        |   3 +-
 drivers/net/ionic/ionic_dev.c    |  16 +--
 drivers/net/ionic/ionic_dev.h    |   8 +-
 drivers/net/ionic/ionic_ethdev.c | 137 ++++++++++---------------
 drivers/net/ionic/ionic_ethdev.h |   4 +
 drivers/net/ionic/ionic_lif.c    | 165 +++++++++++++++++++------------
 drivers/net/ionic/ionic_lif.h    |   7 +-
 drivers/net/ionic/ionic_rxtx.c   |  62 ++++++++----
 9 files changed, 217 insertions(+), 187 deletions(-)

-- 
2.17.1


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

* [dpdk-dev] [PATCH v2 1/7] net/ionic: preserve RSS state unless RETA size changes
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (7 preceding siblings ...)
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 0/7] " Andrew Boyer
@ 2020-12-16 21:12 ` Andrew Boyer
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 2/7] net/ionic: preserve Rx mode across LIF stop/start Andrew Boyer
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

This preserves settings across a LIF stop/start.
This will become important when link toggling is tied to LIF stop/start.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_lif.c | 44 ++++++++++++++++-------------------
 drivers/net/ionic/ionic_lif.h |  1 +
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 28ae9dc8a..646c921b2 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -962,8 +962,6 @@ ionic_lif_rss_config(struct ionic_lif *lif,
 static int
 ionic_lif_rss_setup(struct ionic_lif *lif)
 {
-	size_t tbl_size = sizeof(*lif->rss_ind_tbl) *
-		lif->adapter->ident.lif.eth.rss_ind_tbl_sz;
 	static const uint8_t toeplitz_symmetric_key[] = {
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
@@ -971,34 +969,35 @@ ionic_lif_rss_setup(struct ionic_lif *lif)
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
 		0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
 	};
-	uint32_t socket_id = rte_socket_id();
 	uint32_t i;
-	int err;
+	uint16_t tbl_sz = lif->adapter->ident.lif.eth.rss_ind_tbl_sz;
 
 	IONIC_PRINT_CALL();
 
-	lif->rss_ind_tbl_z = rte_eth_dma_zone_reserve(lif->eth_dev,
-		"rss_ind_tbl",
-		0 /* queue_idx*/, tbl_size, IONIC_ALIGN, socket_id);
-
 	if (!lif->rss_ind_tbl_z) {
-		IONIC_PRINT(ERR, "OOM");
-		return -ENOMEM;
-	}
+		lif->rss_ind_tbl_z = rte_eth_dma_zone_reserve(lif->eth_dev,
+					"rss_ind_tbl", 0 /* queue_idx */,
+					sizeof(*lif->rss_ind_tbl) * tbl_sz,
+					IONIC_ALIGN, rte_socket_id());
+		if (!lif->rss_ind_tbl_z) {
+			IONIC_PRINT(ERR, "OOM");
+			return -ENOMEM;
+		}
 
-	lif->rss_ind_tbl = lif->rss_ind_tbl_z->addr;
-	lif->rss_ind_tbl_pa = lif->rss_ind_tbl_z->iova;
+		lif->rss_ind_tbl = lif->rss_ind_tbl_z->addr;
+		lif->rss_ind_tbl_pa = lif->rss_ind_tbl_z->iova;
+	}
 
-	/* Fill indirection table with 'default' values */
-	for (i = 0; i < lif->adapter->ident.lif.eth.rss_ind_tbl_sz; i++)
-		lif->rss_ind_tbl[i] = i % lif->nrxqcqs;
+	if (lif->rss_ind_tbl_nrxqcqs != lif->nrxqcqs) {
+		lif->rss_ind_tbl_nrxqcqs = lif->nrxqcqs;
 
-	err = ionic_lif_rss_config(lif, IONIC_RSS_OFFLOAD_ALL,
-		toeplitz_symmetric_key, NULL);
-	if (err)
-		return err;
+		/* Fill indirection table with 'default' values */
+		for (i = 0; i < tbl_sz; i++)
+			lif->rss_ind_tbl[i] = i % lif->nrxqcqs;
+	}
 
-	return 0;
+	return ionic_lif_rss_config(lif, IONIC_RSS_OFFLOAD_ALL,
+			toeplitz_symmetric_key, NULL);
 }
 
 static void
@@ -1578,9 +1577,6 @@ ionic_lif_start(struct ionic_lif *lif)
 	uint32_t i;
 	int err;
 
-	IONIC_PRINT(DEBUG, "Setting RSS configuration on port %u",
-		lif->port_id);
-
 	err = ionic_lif_rss_setup(lif);
 	if (err)
 		return err;
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index 8e2b42443..b80931c61 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -108,6 +108,7 @@ struct ionic_lif {
 	uint8_t *rss_ind_tbl;
 	rte_iova_t rss_ind_tbl_pa;
 	const struct rte_memzone *rss_ind_tbl_z;
+	uint32_t rss_ind_tbl_nrxqcqs;
 	uint32_t info_sz;
 	struct ionic_lif_info *info;
 	rte_iova_t info_pa;
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2 2/7] net/ionic: preserve Rx mode across LIF stop/start
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (8 preceding siblings ...)
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 1/7] net/ionic: preserve RSS state unless RETA size changes Andrew Boyer
@ 2020-12-16 21:12 ` Andrew Boyer
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 3/7] net/ionic: remove multi-LIF support Andrew Boyer
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Otherwise, non-default settings (like PROMISC) get reset.
This will become important when link toggling is tied to LIF stop/start.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_lif.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 646c921b2..875c7e585 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -1573,7 +1573,7 @@ ionic_lif_configure(struct ionic_lif *lif)
 int
 ionic_lif_start(struct ionic_lif *lif)
 {
-	uint32_t rx_mode = 0;
+	uint32_t rx_mode;
 	uint32_t i;
 	int err;
 
@@ -1581,16 +1581,16 @@ ionic_lif_start(struct ionic_lif *lif)
 	if (err)
 		return err;
 
-	IONIC_PRINT(DEBUG, "Setting RX mode on port %u",
-		lif->port_id);
-
-	rx_mode |= IONIC_RX_MODE_F_UNICAST;
-	rx_mode |= IONIC_RX_MODE_F_MULTICAST;
-	rx_mode |= IONIC_RX_MODE_F_BROADCAST;
+	if (!lif->rx_mode) {
+		IONIC_PRINT(DEBUG, "Setting RX mode on %s",
+			lif->name);
 
-	lif->rx_mode = 0; /* set by ionic_set_rx_mode */
+		rx_mode  = IONIC_RX_MODE_F_UNICAST;
+		rx_mode |= IONIC_RX_MODE_F_MULTICAST;
+		rx_mode |= IONIC_RX_MODE_F_BROADCAST;
 
-	ionic_set_rx_mode(lif, rx_mode);
+		ionic_set_rx_mode(lif, rx_mode);
+	}
 
 	IONIC_PRINT(DEBUG, "Starting %u RX queues and %u TX queues "
 		"on port %u",
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2 3/7] net/ionic: remove multi-LIF support
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (9 preceding siblings ...)
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 2/7] net/ionic: preserve Rx mode across LIF stop/start Andrew Boyer
@ 2020-12-16 21:12 ` Andrew Boyer
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 4/7] net/ionic: fully implement remove-on-close Andrew Boyer
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

This feature is unused, so remove it.

There is exactly one adapter / lif / ethdev per port.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic.h        |  3 +-
 drivers/net/ionic/ionic_dev.c    | 16 ++--------
 drivers/net/ionic/ionic_dev.h    |  8 ++---
 drivers/net/ionic/ionic_ethdev.c | 50 ++++++++++++--------------------
 drivers/net/ionic/ionic_lif.c    | 24 ++++-----------
 drivers/net/ionic/ionic_lif.h    |  1 -
 6 files changed, 31 insertions(+), 71 deletions(-)

diff --git a/drivers/net/ionic/ionic.h b/drivers/net/ionic/ionic.h
index 7ad0ab69e..49d1fc003 100644
--- a/drivers/net/ionic/ionic.h
+++ b/drivers/net/ionic/ionic.h
@@ -51,9 +51,8 @@ struct ionic_adapter {
 	const char *name;
 	struct ionic_dev_bar bars[IONIC_BARS_MAX];
 	struct ionic_identity	ident;
-	struct ionic_lif *lifs[IONIC_LIFS_MAX];
+	struct ionic_lif *lif;
 	uint32_t num_bars;
-	uint32_t nlifs;
 	uint32_t max_ntxqs_per_lif;
 	uint32_t max_nrxqs_per_lif;
 	uint32_t max_mac_addrs;
diff --git a/drivers/net/ionic/ionic_dev.c b/drivers/net/ionic/ionic_dev.c
index f32966521..4b5e24f98 100644
--- a/drivers/net/ionic/ionic_dev.c
+++ b/drivers/net/ionic/ionic_dev.c
@@ -288,12 +288,10 @@ ionic_dev_cmd_lif_identify(struct ionic_dev *idev, uint8_t type, uint8_t ver)
 }
 
 void
-ionic_dev_cmd_lif_init(struct ionic_dev *idev, uint16_t lif_index,
-		       rte_iova_t info_pa)
+ionic_dev_cmd_lif_init(struct ionic_dev *idev, rte_iova_t info_pa)
 {
 	union ionic_dev_cmd cmd = {
 		.lif_init.opcode = IONIC_CMD_LIF_INIT,
-		.lif_init.index = lif_index,
 		.lif_init.info_pa = info_pa,
 	};
 
@@ -301,11 +299,10 @@ ionic_dev_cmd_lif_init(struct ionic_dev *idev, uint16_t lif_index,
 }
 
 void
-ionic_dev_cmd_lif_reset(struct ionic_dev *idev, uint16_t lif_index)
+ionic_dev_cmd_lif_reset(struct ionic_dev *idev)
 {
 	union ionic_dev_cmd cmd = {
 		.lif_init.opcode = IONIC_CMD_LIF_RESET,
-		.lif_init.index = lif_index,
 	};
 
 	ionic_dev_cmd_go(idev, &cmd);
@@ -317,12 +314,6 @@ ionic_db_map(struct ionic_lif *lif, struct ionic_queue *q)
 	return lif->kern_dbpage + q->hw_type;
 }
 
-int
-ionic_db_page_num(struct ionic_lif *lif, int pid)
-{
-	return (lif->index * 0) + pid;
-}
-
 void
 ionic_intr_init(struct ionic_dev *idev, struct ionic_intr_info *intr,
 		unsigned long index)
@@ -334,14 +325,13 @@ ionic_intr_init(struct ionic_dev *idev, struct ionic_intr_info *intr,
 void
 ionic_dev_cmd_adminq_init(struct ionic_dev *idev,
 		struct ionic_qcq *qcq,
-		uint16_t lif_index, uint16_t intr_index)
+		uint16_t intr_index)
 {
 	struct ionic_queue *q = &qcq->q;
 	struct ionic_cq *cq = &qcq->cq;
 
 	union ionic_dev_cmd cmd = {
 		.q_init.opcode = IONIC_CMD_Q_INIT,
-		.q_init.lif_index = lif_index,
 		.q_init.type = q->type,
 		.q_init.index = q->index,
 		.q_init.flags = IONIC_QINIT_F_ENA,
diff --git a/drivers/net/ionic/ionic_dev.h b/drivers/net/ionic/ionic_dev.h
index 026c4a9f3..6588a373f 100644
--- a/drivers/net/ionic/ionic_dev.h
+++ b/drivers/net/ionic/ionic_dev.h
@@ -232,15 +232,13 @@ void ionic_dev_cmd_port_loopback(struct ionic_dev *idev,
 
 void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, uint8_t type,
 	uint8_t ver);
-void ionic_dev_cmd_lif_init(struct ionic_dev *idev, uint16_t lif_index,
-	rte_iova_t addr);
-void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, uint16_t lif_index);
+void ionic_dev_cmd_lif_init(struct ionic_dev *idev, rte_iova_t addr);
+void ionic_dev_cmd_lif_reset(struct ionic_dev *idev);
 void ionic_dev_cmd_adminq_init(struct ionic_dev *idev, struct ionic_qcq *qcq,
-	uint16_t lif_index, uint16_t intr_index);
+	uint16_t intr_index);
 
 struct ionic_doorbell __iomem *ionic_db_map(struct ionic_lif *lif,
 	struct ionic_queue *q);
-int ionic_db_page_num(struct ionic_lif *lif, int pid);
 
 int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq,
 	struct ionic_intr_info *intr, uint32_t num_descs,
diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index 5a360ac08..54d7a6cad 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -339,14 +339,11 @@ static void
 ionic_dev_interrupt_handler(void *param)
 {
 	struct ionic_adapter *adapter = (struct ionic_adapter *)param;
-	uint32_t i;
 
 	IONIC_PRINT(DEBUG, "->");
 
-	for (i = 0; i < adapter->nlifs; i++) {
-		if (adapter->lifs[i])
-			ionic_notifyq_handler(adapter->lifs[i], -1);
-	}
+	if (adapter->lif)
+		ionic_notifyq_handler(adapter->lif, -1);
 }
 
 static int
@@ -1008,10 +1005,9 @@ eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
 
-	lif->index = adapter->nlifs;
 	lif->eth_dev = eth_dev;
 	lif->adapter = adapter;
-	adapter->lifs[adapter->nlifs] = lif;
+	adapter->lif = lif;
 
 	IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported",
 		adapter->max_mac_addrs);
@@ -1066,7 +1062,7 @@ eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	adapter->lifs[lif->index] = NULL;
+	adapter->lif = NULL;
 
 	ionic_lif_deinit(lif);
 	ionic_lif_free(lif);
@@ -1243,22 +1239,19 @@ eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
 	adapter->max_mac_addrs = adapter->ident.lif.eth.max_ucast_filters;
 
-	adapter->nlifs = 0;
-	for (i = 0; i < adapter->ident.dev.nlifs; i++) {
-		snprintf(name, sizeof(name), "net_%s_lif_%lu",
-			pci_dev->device.name, i);
-
-		err = rte_eth_dev_create(&pci_dev->device, name,
-			sizeof(struct ionic_lif),
-			NULL, NULL,
-			eth_ionic_dev_init, adapter);
-		if (err) {
-			IONIC_PRINT(ERR, "Cannot create eth device for "
-				"ionic lif %s", name);
-			break;
-		}
+	if (adapter->ident.dev.nlifs != 1) {
+		IONIC_PRINT(ERR, "Unexpected request for %d LIFs",
+			adapter->ident.dev.nlifs);
+		goto err_free_adapter;
+	}
 
-		adapter->nlifs++;
+	snprintf(name, sizeof(name), "%s_lif", pci_dev->device.name);
+	err = rte_eth_dev_create(&pci_dev->device,
+			name, sizeof(struct ionic_lif),
+			NULL, NULL, eth_ionic_dev_init, adapter);
+	if (err) {
+		IONIC_PRINT(ERR, "Cannot create eth device for %s", name);
+		goto err_free_adapter;
 	}
 
 	err = ionic_configure_intr(adapter);
@@ -1283,11 +1276,9 @@ eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
 	struct ionic_adapter *adapter = NULL;
 	struct rte_eth_dev *eth_dev;
 	struct ionic_lif *lif;
-	uint32_t i;
 
-	/* Adapter lookup is using (the first) eth_dev name */
-	snprintf(name, sizeof(name), "net_%s_lif_0",
-		pci_dev->device.name);
+	/* Adapter lookup is using the eth_dev name */
+	snprintf(name, sizeof(name), "%s_lif", pci_dev->device.name);
 
 	eth_dev = rte_eth_dev_allocated(name);
 	if (eth_dev) {
@@ -1298,10 +1289,7 @@ eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
 	if (adapter) {
 		ionic_unconfigure_intr(adapter);
 
-		for (i = 0; i < adapter->nlifs; i++) {
-			lif = adapter->lifs[i];
-			rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);
-		}
+		rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit);
 
 		rte_free(adapter);
 	}
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 875c7e585..4b5221b83 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -25,7 +25,6 @@ ionic_qcq_enable(struct ionic_qcq *qcq)
 		.pending_work = true,
 		.cmd.q_control = {
 			.opcode = IONIC_CMD_Q_CONTROL,
-			.lif_index = lif->index,
 			.type = q->type,
 			.index = q->index,
 			.oper = IONIC_Q_ENABLE,
@@ -50,7 +49,6 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
 		.pending_work = true,
 		.cmd.q_control = {
 			.opcode = IONIC_CMD_Q_CONTROL,
-			.lif_index = lif->index,
 			.type = q->type,
 			.index = q->index,
 			.oper = IONIC_Q_DISABLE,
@@ -81,7 +79,7 @@ ionic_lif_reset(struct ionic_lif *lif)
 
 	IONIC_PRINT_CALL();
 
-	ionic_dev_cmd_lif_reset(idev, lif->index);
+	ionic_dev_cmd_lif_reset(idev);
 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
 	if (err)
 		IONIC_PRINT(WARNING, "Failed to reset %s", lif->name);
@@ -438,7 +436,6 @@ ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
 		.pending_work = true,
 		.cmd.rx_mode_set = {
 			.opcode = IONIC_CMD_RX_MODE_SET,
-			.lif_index = lif->index,
 			.rx_mode = rx_mode,
 		},
 	};
@@ -530,7 +527,6 @@ ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu)
 		.pending_work = true,
 		.cmd.lif_setattr = {
 			.opcode = IONIC_CMD_LIF_SETATTR,
-			.index = lif->index,
 			.attr = IONIC_LIF_ATTR_MTU,
 			.mtu = new_mtu,
 		},
@@ -824,7 +820,6 @@ ionic_lif_alloc(struct ionic_lif *lif)
 {
 	struct ionic_adapter *adapter = lif->adapter;
 	uint32_t socket_id = rte_socket_id();
-	int dbpage_num;
 	int err;
 
 	/*
@@ -840,9 +835,7 @@ ionic_lif_alloc(struct ionic_lif *lif)
 	rte_spinlock_init(&lif->adminq_lock);
 	rte_spinlock_init(&lif->adminq_service_lock);
 
-	dbpage_num = ionic_db_page_num(lif, 0);
-
-	lif->kern_dbpage = ionic_bus_map_dbpage(adapter, dbpage_num);
+	lif->kern_dbpage = ionic_bus_map_dbpage(adapter, 0);
 	if (!lif->kern_dbpage) {
 		IONIC_PRINT(ERR, "Cannot map dbpage, aborting");
 		return -ENOMEM;
@@ -1174,7 +1167,7 @@ ionic_lif_adminq_init(struct ionic_lif *lif)
 	struct ionic_q_init_comp comp;
 	int err;
 
-	ionic_dev_cmd_adminq_init(idev, qcq, lif->index, qcq->intr.index);
+	ionic_dev_cmd_adminq_init(idev, qcq, qcq->intr.index);
 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
 	if (err)
 		return err;
@@ -1210,7 +1203,6 @@ ionic_lif_notifyq_init(struct ionic_lif *lif)
 		.pending_work = true,
 		.cmd.q_init = {
 			.opcode = IONIC_CMD_Q_INIT,
-			.lif_index = lif->index,
 			.type = q->type,
 			.index = q->index,
 			.flags = (IONIC_QINIT_F_IRQ | IONIC_QINIT_F_ENA),
@@ -1256,7 +1248,6 @@ ionic_lif_set_features(struct ionic_lif *lif)
 		.pending_work = true,
 		.cmd.lif_setattr = {
 			.opcode = IONIC_CMD_LIF_SETATTR,
-			.index = lif->index,
 			.attr = IONIC_LIF_ATTR_FEATURES,
 			.features = lif->features,
 		},
@@ -1318,7 +1309,6 @@ ionic_lif_txq_init(struct ionic_qcq *qcq)
 		.pending_work = true,
 		.cmd.q_init = {
 			.opcode = IONIC_CMD_Q_INIT,
-			.lif_index = lif->index,
 			.type = q->type,
 			.index = q->index,
 			.flags = IONIC_QINIT_F_SG,
@@ -1365,7 +1355,6 @@ ionic_lif_rxq_init(struct ionic_qcq *qcq)
 		.pending_work = true,
 		.cmd.q_init = {
 			.opcode = IONIC_CMD_Q_INIT,
-			.lif_index = lif->index,
 			.type = q->type,
 			.index = q->index,
 			.flags = IONIC_QINIT_F_SG,
@@ -1409,7 +1398,6 @@ ionic_station_set(struct ionic_lif *lif)
 		.pending_work = true,
 		.cmd.lif_getattr = {
 			.opcode = IONIC_CMD_LIF_GETATTR,
-			.index = lif->index,
 			.attr = IONIC_LIF_ATTR_MAC,
 		},
 	};
@@ -1449,7 +1437,6 @@ ionic_lif_set_name(struct ionic_lif *lif)
 		.pending_work = true,
 		.cmd.lif_setattr = {
 			.opcode = IONIC_CMD_LIF_SETATTR,
-			.index = lif->index,
 			.attr = IONIC_LIF_ATTR_NAME,
 		},
 	};
@@ -1469,7 +1456,7 @@ ionic_lif_init(struct ionic_lif *lif)
 
 	memset(&lif->stats_base, 0, sizeof(lif->stats_base));
 
-	ionic_dev_cmd_lif_init(idev, lif->index, lif->info_pa);
+	ionic_dev_cmd_lif_init(idev, lif->info_pa);
 	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
 	ionic_dev_cmd_comp(idev, &comp);
 	if (err)
@@ -1672,7 +1659,6 @@ int
 ionic_lifs_size(struct ionic_adapter *adapter)
 {
 	struct ionic_identity *ident = &adapter->ident;
-	uint32_t nlifs = ident->dev.nlifs;
 	uint32_t nintrs, dev_nintrs = ident->dev.nintrs;
 
 	adapter->max_ntxqs_per_lif =
@@ -1680,7 +1666,7 @@ ionic_lifs_size(struct ionic_adapter *adapter)
 	adapter->max_nrxqs_per_lif =
 		ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
 
-	nintrs = nlifs * 1 /* notifyq */;
+	nintrs = 1 /* notifyq */;
 
 	if (nintrs > dev_nintrs) {
 		IONIC_PRINT(ERR,
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index b80931c61..c1d15dca6 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -84,7 +84,6 @@ struct ionic_lif {
 	struct ionic_adapter *adapter;
 	struct rte_eth_dev *eth_dev;
 	uint16_t port_id;  /**< Device port identifier */
-	uint32_t index;
 	uint32_t hw_index;
 	uint32_t state;
 	uint32_t ntxqcqs;
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2 4/7] net/ionic: fully implement remove-on-close
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (10 preceding siblings ...)
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 3/7] net/ionic: remove multi-LIF support Andrew Boyer
@ 2020-12-16 21:12 ` Andrew Boyer
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 5/7] net/ionic: improve link state handling Andrew Boyer
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

ionic_dev_close() is responsible for destroying the ethdev, lif, and
adapter. eth_ionic_dev_remove() calls ionic_dev_close().

Remove-on-close is now required behavior for a PMD.
Remove the UNMAINTAINED flag.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 MAINTAINERS                      |  2 +-
 drivers/net/ionic/ionic_ethdev.c | 40 ++++++++++++++++----------------
 drivers/net/ionic/ionic_lif.c    | 15 ++++++++++++
 drivers/net/ionic/ionic_lif.h    |  1 +
 4 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6787b15dc..76ed473e4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -841,7 +841,7 @@ F: doc/guides/nics/pfe.rst
 F: drivers/net/pfe/
 F: doc/guides/nics/features/pfe.ini
 
-Pensando ionic - UNMAINTAINED
+Pensando ionic
 M: Andrew Boyer <aboyer@pensando.io>
 F: drivers/net/ionic/
 F: doc/guides/nics/ionic.rst
diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index 54d7a6cad..7ab32a0d7 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -955,6 +955,8 @@ ionic_dev_stop(struct rte_eth_dev *eth_dev)
 	return err;
 }
 
+static void ionic_unconfigure_intr(struct ionic_adapter *adapter);
+
 /*
  * Reset and stop device.
  */
@@ -962,6 +964,7 @@ static int
 ionic_dev_close(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+	struct ionic_adapter *adapter = lif->adapter;
 	int err;
 
 	IONIC_PRINT_CALL();
@@ -974,11 +977,17 @@ ionic_dev_close(struct rte_eth_dev *eth_dev)
 		return -1;
 	}
 
-	err = eth_ionic_dev_uninit(eth_dev);
-	if (err) {
-		IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err);
-		return -1;
-	}
+	ionic_lif_free_queues(lif);
+
+	IONIC_PRINT(NOTICE, "Removing device %s", eth_dev->device->name);
+	ionic_unconfigure_intr(adapter);
+
+	rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit);
+
+	ionic_port_reset(adapter);
+	ionic_reset(adapter);
+
+	rte_free(adapter);
 
 	return 0;
 }
@@ -1270,29 +1279,20 @@ eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 }
 
 static int
-eth_ionic_pci_remove(struct rte_pci_device *pci_dev __rte_unused)
+eth_ionic_pci_remove(struct rte_pci_device *pci_dev)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
-	struct ionic_adapter *adapter = NULL;
 	struct rte_eth_dev *eth_dev;
-	struct ionic_lif *lif;
 
 	/* Adapter lookup is using the eth_dev name */
 	snprintf(name, sizeof(name), "%s_lif", pci_dev->device.name);
 
 	eth_dev = rte_eth_dev_allocated(name);
-	if (eth_dev) {
-		lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-		adapter = lif->adapter;
-	}
-
-	if (adapter) {
-		ionic_unconfigure_intr(adapter);
-
-		rte_eth_dev_destroy(eth_dev, eth_ionic_dev_uninit);
-
-		rte_free(adapter);
-	}
+	if (eth_dev)
+		ionic_dev_close(eth_dev);
+	else
+		IONIC_PRINT(DEBUG, "Cannot find device %s",
+			pci_dev->device.name);
 
 	return 0;
 }
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 4b5221b83..9b11e6310 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -920,6 +920,21 @@ ionic_lif_free(struct ionic_lif *lif)
 	}
 }
 
+void
+ionic_lif_free_queues(struct ionic_lif *lif)
+{
+	uint32_t i;
+
+	for (i = 0; i < lif->ntxqcqs; i++) {
+		ionic_dev_tx_queue_release(lif->eth_dev->data->tx_queues[i]);
+		lif->eth_dev->data->tx_queues[i] = NULL;
+	}
+	for (i = 0; i < lif->nrxqcqs; i++) {
+		ionic_dev_rx_queue_release(lif->eth_dev->data->rx_queues[i]);
+		lif->eth_dev->data->rx_queues[i] = NULL;
+	}
+}
+
 int
 ionic_lif_rss_config(struct ionic_lif *lif,
 		const uint16_t types, const uint8_t *key, const uint32_t *indir)
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index c1d15dca6..cc0e4f04e 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -121,6 +121,7 @@ int ionic_lifs_size(struct ionic_adapter *ionic);
 
 int ionic_lif_alloc(struct ionic_lif *lif);
 void ionic_lif_free(struct ionic_lif *lif);
+void ionic_lif_free_queues(struct ionic_lif *lif);
 
 int ionic_lif_init(struct ionic_lif *lif);
 void ionic_lif_deinit(struct ionic_lif *lif);
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2 5/7] net/ionic: improve link state handling
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (11 preceding siblings ...)
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 4/7] net/ionic: fully implement remove-on-close Andrew Boyer
@ 2020-12-16 21:12 ` Andrew Boyer
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 6/7] net/ionic: improve queue " Andrew Boyer
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 7/7] net/ionic: stop queues when LIF is stopped Andrew Boyer
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Add UP and FW_RESET state flags.
Update the stack info when the link state changes.
Convert set_link_up/set_link_down to lif_start/lif_stop.
Condition reported link state on UP flag.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_ethdev.c | 49 ++++++++++---------------------
 drivers/net/ionic/ionic_ethdev.h |  4 +++
 drivers/net/ionic/ionic_lif.c    | 50 ++++++++++++++++++++++++++------
 drivers/net/ionic/ionic_lif.h    |  4 ++-
 4 files changed, 64 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index 7ab32a0d7..fd7cd510e 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -28,8 +28,6 @@ static int  ionic_dev_stop(struct rte_eth_dev *dev);
 static int  ionic_dev_close(struct rte_eth_dev *dev);
 static int  ionic_dev_set_link_up(struct rte_eth_dev *dev);
 static int  ionic_dev_set_link_down(struct rte_eth_dev *dev);
-static int  ionic_dev_link_update(struct rte_eth_dev *eth_dev,
-	int wait_to_complete);
 static int  ionic_flow_ctrl_get(struct rte_eth_dev *eth_dev,
 	struct rte_eth_fc_conf *fc_conf);
 static int  ionic_flow_ctrl_set(struct rte_eth_dev *eth_dev,
@@ -236,21 +234,17 @@ static int
 ionic_dev_set_link_up(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-	struct ionic_adapter *adapter = lif->adapter;
-	struct ionic_dev *idev = &adapter->idev;
 	int err;
 
 	IONIC_PRINT_CALL();
 
-	ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP);
+	err = ionic_lif_start(lif);
+	if (err)
+		IONIC_PRINT(ERR, "Could not start lif to set link up");
 
-	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
-	if (err) {
-		IONIC_PRINT(WARNING, "Failed to bring port UP");
-		return err;
-	}
+	ionic_dev_link_update(lif->eth_dev, 0);
 
-	return 0;
+	return err;
 }
 
 /*
@@ -260,24 +254,17 @@ static int
 ionic_dev_set_link_down(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-	struct ionic_adapter *adapter = lif->adapter;
-	struct ionic_dev *idev = &adapter->idev;
-	int err;
 
 	IONIC_PRINT_CALL();
 
-	ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_DOWN);
+	ionic_lif_stop(lif);
 
-	err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
-	if (err) {
-		IONIC_PRINT(WARNING, "Failed to bring port DOWN");
-		return err;
-	}
+	ionic_dev_link_update(lif->eth_dev, 0);
 
 	return 0;
 }
 
-static int
+int
 ionic_dev_link_update(struct rte_eth_dev *eth_dev,
 		int wait_to_complete __rte_unused)
 {
@@ -291,7 +278,8 @@ ionic_dev_link_update(struct rte_eth_dev *eth_dev,
 	memset(&link, 0, sizeof(link));
 	link.link_autoneg = ETH_LINK_AUTONEG;
 
-	if (!adapter->link_up) {
+	if (!adapter->link_up ||
+	    !(lif->state & IONIC_LIF_F_UP)) {
 		/* Interface is down */
 		link.link_status = ETH_LINK_DOWN;
 		link.link_duplex = ETH_LINK_HALF_DUPLEX;
@@ -944,15 +932,12 @@ static int
 ionic_dev_stop(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
-	int err;
 
 	IONIC_PRINT_CALL();
 
-	err = ionic_lif_stop(lif);
-	if (err)
-		IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
+	ionic_lif_stop(lif);
 
-	return err;
+	return 0;
 }
 
 static void ionic_unconfigure_intr(struct ionic_adapter *adapter);
@@ -965,17 +950,12 @@ ionic_dev_close(struct rte_eth_dev *eth_dev)
 {
 	struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
 	struct ionic_adapter *adapter = lif->adapter;
-	int err;
 
 	IONIC_PRINT_CALL();
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
-	err = ionic_lif_stop(lif);
-	if (err) {
-		IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
-		return -1;
-	}
+	ionic_lif_stop(lif);
 
 	ionic_lif_free_queues(lif);
 
@@ -1076,6 +1056,9 @@ eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev)
 	ionic_lif_deinit(lif);
 	ionic_lif_free(lif);
 
+	if (!(lif->state & IONIC_LIF_F_FW_RESET))
+		ionic_lif_reset(lif);
+
 	return 0;
 }
 
diff --git a/drivers/net/ionic/ionic_ethdev.h b/drivers/net/ionic/ionic_ethdev.h
index 578e2301f..6cbcd0f82 100644
--- a/drivers/net/ionic/ionic_ethdev.h
+++ b/drivers/net/ionic/ionic_ethdev.h
@@ -5,6 +5,8 @@
 #ifndef _IONIC_ETHDEV_H_
 #define _IONIC_ETHDEV_H_
 
+#include <rte_ethdev.h>
+
 #define IONIC_ETH_RSS_OFFLOAD_ALL ( \
 	ETH_RSS_IPV4 | \
 	ETH_RSS_NONFRAG_IPV4_TCP | \
@@ -18,5 +20,7 @@
 #define IONIC_ETH_DEV_TO_ADAPTER(eth_dev) \
 	(IONIC_ETH_DEV_TO_LIF(eth_dev)->adapter)
 
+int ionic_dev_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete);
+
 #endif /* _IONIC_ETHDEV_H_ */
 
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index 9b11e6310..c1a95ca7c 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -63,12 +63,12 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
 	return ionic_adminq_post_wait(lif, &ctx);
 }
 
-int
-ionic_lif_stop(struct ionic_lif *lif __rte_unused)
+void
+ionic_lif_stop(struct ionic_lif *lif)
 {
-	/* Carrier OFF here */
+	IONIC_PRINT_CALL();
 
-	return 0;
+	lif->state &= ~IONIC_LIF_F_UP;
 }
 
 void
@@ -1098,14 +1098,32 @@ ionic_link_status_check(struct ionic_lif *lif)
 		return;
 
 	if (link_up) {
-		IONIC_PRINT(DEBUG, "Link up - %d Gbps",
-			lif->info->status.link_speed);
 		adapter->link_speed = lif->info->status.link_speed;
+		IONIC_PRINT(DEBUG, "Link up - %d Gbps",
+			adapter->link_speed);
 	} else {
 		IONIC_PRINT(DEBUG, "Link down");
 	}
 
 	adapter->link_up = link_up;
+	ionic_dev_link_update(lif->eth_dev, 0);
+}
+
+static void
+ionic_lif_handle_fw_down(struct ionic_lif *lif)
+{
+	if (lif->state & IONIC_LIF_F_FW_RESET)
+		return;
+
+	lif->state |= IONIC_LIF_F_FW_RESET;
+
+	if (lif->state & IONIC_LIF_F_UP) {
+		IONIC_PRINT(NOTICE,
+			"Surprise FW stop, stopping %s\n", lif->name);
+		ionic_lif_stop(lif);
+	}
+
+	IONIC_PRINT(NOTICE, "FW down, %s stopped", lif->name);
 }
 
 static bool
@@ -1127,14 +1145,27 @@ ionic_notifyq_cb(struct ionic_cq *cq, uint32_t cq_desc_index, void *cb_arg)
 	switch (cq_desc->event.ecode) {
 	case IONIC_EVENT_LINK_CHANGE:
 		IONIC_PRINT(DEBUG,
-			"Notifyq IONIC_EVENT_LINK_CHANGE eid=%jd link_status=%d link_speed=%d",
+			"Notifyq IONIC_EVENT_LINK_CHANGE %s "
+			"eid=%jd link_status=%d link_speed=%d",
+			lif->name,
 			cq_desc->event.eid,
 			cq_desc->link_change.link_status,
 			cq_desc->link_change.link_speed);
 
 		lif->state |= IONIC_LIF_F_LINK_CHECK_NEEDED;
+		break;
 
+	case IONIC_EVENT_RESET:
+		IONIC_PRINT(NOTICE,
+			"Notifyq IONIC_EVENT_RESET %s "
+			"eid=%jd, reset_code=%d state=%d",
+			lif->name,
+			cq_desc->event.eid,
+			cq_desc->reset.reset_code,
+			cq_desc->reset.state);
+		ionic_lif_handle_fw_down(lif);
 		break;
+
 	default:
 		IONIC_PRINT(WARNING, "Notifyq bad event ecode=%d eid=%jd",
 			cq_desc->event.ecode, cq_desc->event.eid);
@@ -1618,9 +1649,10 @@ ionic_lif_start(struct ionic_lif *lif)
 		}
 	}
 
-	ionic_link_status_check(lif);
-
 	/* Carrier ON here */
+	lif->state |= IONIC_LIF_F_UP;
+
+	ionic_link_status_check(lif);
 
 	return 0;
 }
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index cc0e4f04e..86d933606 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -77,6 +77,8 @@ struct ionic_qcq {
 
 #define IONIC_LIF_F_INITED		BIT(0)
 #define IONIC_LIF_F_LINK_CHECK_NEEDED	BIT(1)
+#define IONIC_LIF_F_UP			BIT(2)
+#define IONIC_LIF_F_FW_RESET		BIT(3)
 
 #define IONIC_LIF_NAME_MAX_SZ		(32)
 
@@ -127,7 +129,7 @@ int ionic_lif_init(struct ionic_lif *lif);
 void ionic_lif_deinit(struct ionic_lif *lif);
 
 int ionic_lif_start(struct ionic_lif *lif);
-int ionic_lif_stop(struct ionic_lif *lif);
+void ionic_lif_stop(struct ionic_lif *lif);
 
 int ionic_lif_configure(struct ionic_lif *lif);
 void ionic_lif_reset(struct ionic_lif *lif);
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2 6/7] net/ionic: improve queue state handling
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (12 preceding siblings ...)
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 5/7] net/ionic: improve link state handling Andrew Boyer
@ 2020-12-16 21:12 ` Andrew Boyer
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 7/7] net/ionic: stop queues when LIF is stopped Andrew Boyer
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Skip ionic_lif_[rxq|txq]_init() in queue start if it's already done.
Move ionic_lif_[rxq|txq]_deinit() from queue stop to queue release.

This allows the queues to be restarted.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_rxtx.c | 62 +++++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ionic/ionic_rxtx.c b/drivers/net/ionic/ionic_rxtx.c
index b689c8381..d06f1246c 100644
--- a/drivers/net/ionic/ionic_rxtx.c
+++ b/drivers/net/ionic/ionic_rxtx.c
@@ -125,6 +125,8 @@ ionic_dev_tx_queue_release(void *tx_queue)
 
 	IONIC_PRINT_CALL();
 
+	ionic_lif_txq_deinit(txq);
+
 	ionic_qcq_free(txq);
 }
 
@@ -137,6 +139,9 @@ ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 
 	txq = eth_dev->data->tx_queues[tx_queue_id];
 
+	eth_dev->data->tx_queue_state[tx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	/*
 	 * Note: we should better post NOP Tx desc and wait for its completion
 	 * before disabling Tx queue
@@ -146,11 +151,6 @@ ionic_dev_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 
 	ionic_tx_flush(&txq->cq);
 
-	ionic_lif_txq_deinit(txq);
-
-	eth_dev->data->tx_queue_state[tx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STOPPED;
-
 	return 0;
 }
 
@@ -187,6 +187,9 @@ ionic_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id,
 		eth_dev->data->tx_queues[tx_queue_id] = NULL;
 	}
 
+	eth_dev->data->tx_queue_state[tx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	err = ionic_tx_qcq_alloc(lif, tx_queue_id, nb_desc, &txq);
 	if (err) {
 		IONIC_PRINT(DEBUG, "Queue allocation failure");
@@ -210,22 +213,30 @@ ionic_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id,
 int __rte_cold
 ionic_dev_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t tx_queue_id)
 {
+	uint8_t *tx_queue_state = eth_dev->data->tx_queue_state;
 	struct ionic_qcq *txq;
 	int err;
 
+	if (tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STARTED) {
+		IONIC_PRINT(DEBUG, "TX queue %u already started",
+			tx_queue_id);
+		return 0;
+	}
+
 	txq = eth_dev->data->tx_queues[tx_queue_id];
 
 	IONIC_PRINT(DEBUG, "Starting TX queue %u, %u descs",
 		tx_queue_id, txq->q.num_descs);
 
-	err = ionic_lif_txq_init(txq);
-	if (err)
-		return err;
+	if (!(txq->flags & IONIC_QCQ_F_INITED)) {
+		err = ionic_lif_txq_init(txq);
+		if (err)
+			return err;
+	}
 
 	ionic_qcq_enable(txq);
 
-	eth_dev->data->tx_queue_state[tx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STARTED;
+	tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
 
 	return 0;
 }
@@ -634,6 +645,8 @@ ionic_dev_rx_queue_release(void *rx_queue)
 
 	ionic_rx_empty(&rxq->q);
 
+	ionic_lif_rxq_deinit(rxq);
+
 	ionic_qcq_free(rxq);
 }
 
@@ -682,6 +695,9 @@ ionic_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 		eth_dev->data->rx_queues[rx_queue_id] = NULL;
 	}
 
+	eth_dev->data->rx_queue_state[rx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	err = ionic_rx_qcq_alloc(lif, rx_queue_id, nb_desc, &rxq);
 	if (err) {
 		IONIC_PRINT(ERR, "Queue %d allocation failure", rx_queue_id);
@@ -953,17 +969,26 @@ int __rte_cold
 ionic_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 {
 	uint32_t frame_size = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
+	uint8_t *rx_queue_state = eth_dev->data->rx_queue_state;
 	struct ionic_qcq *rxq;
 	int err;
 
+	if (rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STARTED) {
+		IONIC_PRINT(DEBUG, "RX queue %u already started",
+			rx_queue_id);
+		return 0;
+	}
+
 	rxq = eth_dev->data->rx_queues[rx_queue_id];
 
 	IONIC_PRINT(DEBUG, "Starting RX queue %u, %u descs (size: %u)",
 		rx_queue_id, rxq->q.num_descs, frame_size);
 
-	err = ionic_lif_rxq_init(rxq);
-	if (err)
-		return err;
+	if (!(rxq->flags & IONIC_QCQ_F_INITED)) {
+		err = ionic_lif_rxq_init(rxq);
+		if (err)
+			return err;
+	}
 
 	/* Allocate buffers for descriptor rings */
 	if (ionic_rx_fill(rxq, frame_size) != 0) {
@@ -974,8 +999,7 @@ ionic_dev_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 
 	ionic_qcq_enable(rxq);
 
-	eth_dev->data->rx_queue_state[rx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STARTED;
+	rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
 
 	return 0;
 }
@@ -1044,16 +1068,14 @@ ionic_dev_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t rx_queue_id)
 
 	rxq = eth_dev->data->rx_queues[rx_queue_id];
 
+	eth_dev->data->rx_queue_state[rx_queue_id] =
+		RTE_ETH_QUEUE_STATE_STOPPED;
+
 	ionic_qcq_disable(rxq);
 
 	/* Flush */
 	ionic_rxq_service(&rxq->cq, -1, NULL);
 
-	ionic_lif_rxq_deinit(rxq);
-
-	eth_dev->data->rx_queue_state[rx_queue_id] =
-		RTE_ETH_QUEUE_STATE_STOPPED;
-
 	return 0;
 }
 
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2 7/7] net/ionic: stop queues when LIF is stopped
  2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
                   ` (13 preceding siblings ...)
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 6/7] net/ionic: improve queue " Andrew Boyer
@ 2020-12-16 21:12 ` Andrew Boyer
  14 siblings, 0 replies; 19+ messages in thread
From: Andrew Boyer @ 2020-12-16 21:12 UTC (permalink / raw)
  To: dev; +Cc: Alfredo Cardigliano, Andrew Boyer

Otherwise they cannot be restarted, because the FW will reject INIT
or ENA commands on queues which are already running.

Signed-off-by: Andrew Boyer <aboyer@pensando.io>
---
 drivers/net/ionic/ionic_lif.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index c1a95ca7c..3e643d145 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -66,9 +66,23 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
 void
 ionic_lif_stop(struct ionic_lif *lif)
 {
+	uint32_t i;
+
 	IONIC_PRINT_CALL();
 
 	lif->state &= ~IONIC_LIF_F_UP;
+
+	for (i = 0; i < lif->nrxqcqs; i++) {
+		struct ionic_qcq *rxq = lif->rxqcqs[i];
+		if (rxq->flags & IONIC_QCQ_F_INITED)
+			(void)ionic_dev_rx_queue_stop(lif->eth_dev, i);
+	}
+
+	for (i = 0; i < lif->ntxqcqs; i++) {
+		struct ionic_qcq *txq = lif->txqcqs[i];
+		if (txq->flags & IONIC_QCQ_F_INITED)
+			(void)ionic_dev_tx_queue_stop(lif->eth_dev, i);
+	}
 }
 
 void
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH v2 0/7] net/ionic: fixes for stop and start
  2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 0/7] " Andrew Boyer
@ 2021-01-11 17:08   ` Ferruh Yigit
  0 siblings, 0 replies; 19+ messages in thread
From: Ferruh Yigit @ 2021-01-11 17:08 UTC (permalink / raw)
  To: Andrew Boyer, dev; +Cc: Alfredo Cardigliano

On 12/16/2020 9:12 PM, Andrew Boyer wrote:
> These patches address issues found when testing port stop and start,
> link up and down, and queue stop and start.
> 
> The UNMAINTAINED flag is removed in patch 3.
> 
> Signed-off-by: Andrew Boyer <aboyer@pensando.io>
> 
> ---
> v2:
> * Address Ferruh's comments
> * Insert a new patch "net/ionic: remove multi-LIF support" so that the
>    patch "net/ionic: fully implement remove-on-close" makes sense
> 
> Andrew Boyer (7):
>    net/ionic: preserve RSS state unless RETA size changes
>    net/ionic: preserve Rx mode across LIF stop/start
>    net/ionic: remove multi-LIF support
>    net/ionic: fully implement remove-on-close
>    net/ionic: improve link state handling
>    net/ionic: improve queue state handling
>    net/ionic: stop queues when LIF is stopped

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

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

end of thread, other threads:[~2021-01-11 17:08 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-10 14:22 [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Andrew Boyer
2020-12-10 14:22 ` [dpdk-dev] [PATCH 1/6] net/ionic: preserve RSS state unless RETA size changes Andrew Boyer
2020-12-10 14:22 ` [dpdk-dev] [PATCH 2/6] net/ionic: preserve RX mode across LIF stop/start Andrew Boyer
2020-12-10 14:22 ` [dpdk-dev] [PATCH 3/6] net/ionic: fully implement remove-on-close Andrew Boyer
2020-12-15 13:42   ` Ferruh Yigit
2020-12-16 19:52     ` Andrew Boyer
2020-12-10 14:22 ` [dpdk-dev] [PATCH 4/6] net/ionic: improve link state handling Andrew Boyer
2020-12-10 14:22 ` [dpdk-dev] [PATCH 5/6] net/ionic: improve queue " Andrew Boyer
2020-12-10 14:22 ` [dpdk-dev] [PATCH 6/6] net/ionic: stop queues when LIF is stopped Andrew Boyer
2020-12-15 14:01 ` [dpdk-dev] [PATCH 0/6] net/ionic: fixes for stop and start Ferruh Yigit
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 0/7] " Andrew Boyer
2021-01-11 17:08   ` Ferruh Yigit
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 1/7] net/ionic: preserve RSS state unless RETA size changes Andrew Boyer
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 2/7] net/ionic: preserve Rx mode across LIF stop/start Andrew Boyer
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 3/7] net/ionic: remove multi-LIF support Andrew Boyer
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 4/7] net/ionic: fully implement remove-on-close Andrew Boyer
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 5/7] net/ionic: improve link state handling Andrew Boyer
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 6/7] net/ionic: improve queue " Andrew Boyer
2020-12-16 21:12 ` [dpdk-dev] [PATCH v2 7/7] net/ionic: stop queues when LIF is stopped Andrew Boyer

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git