[dpdk-dev] [PATCH v3 44/46] net/liquidio: add API to close device

Shijith Thotton shijith.thotton at caviumnetworks.com
Sat Mar 25 07:24:55 CET 2017


Signed-off-by: Shijith Thotton <shijith.thotton at caviumnetworks.com>
Signed-off-by: Jerin Jacob <jerin.jacob at caviumnetworks.com>
Signed-off-by: Derek Chickles <derek.chickles at caviumnetworks.com>
Signed-off-by: Venkat Koppula <venkat.koppula at caviumnetworks.com>
Signed-off-by: Srisivasubramanian S <ssrinivasan at caviumnetworks.com>
Signed-off-by: Mallesham Jatharakonda <mjatharakonda at oneconvergence.com>
---
 drivers/net/liquidio/lio_ethdev.c | 68 +++++++++++++++++++++++++++++++++++++--
 drivers/net/liquidio/lio_ethdev.h |  5 +++
 drivers/net/liquidio/lio_rxtx.c   | 57 ++++++++++++++++++++++++++++++++
 drivers/net/liquidio/lio_rxtx.h   |  2 ++
 4 files changed, 130 insertions(+), 2 deletions(-)

diff --git a/drivers/net/liquidio/lio_ethdev.c b/drivers/net/liquidio/lio_ethdev.c
index 76d775d..60dfa61 100644
--- a/drivers/net/liquidio/lio_ethdev.c
+++ b/drivers/net/liquidio/lio_ethdev.c
@@ -1109,7 +1109,7 @@ struct rte_lio_xstats_name_off {
  * @return
  *    - nothing
  */
-static void
+void
 lio_dev_rx_queue_release(void *rxq)
 {
 	struct lio_droq *droq = rxq;
@@ -1204,7 +1204,7 @@ struct rte_lio_xstats_name_off {
  * @return
  *    - nothing
  */
-static void
+void
 lio_dev_tx_queue_release(void *txq)
 {
 	struct lio_instr_queue *tq = txq;
@@ -1433,6 +1433,68 @@ struct rte_lio_xstats_name_off {
 }
 
 /**
+ * Reset and stop the device. This occurs on the first
+ * call to this routine. Subsequent calls will simply
+ * return. NB: This will require the NIC to be rebooted.
+ *
+ * @param eth_dev
+ *    Pointer to the structure rte_eth_dev
+ *
+ * @return
+ *    - nothing
+ */
+static void
+lio_dev_close(struct rte_eth_dev *eth_dev)
+{
+	struct lio_device *lio_dev = LIO_DEV(eth_dev);
+	uint32_t i;
+
+	lio_dev_info(lio_dev, "closing port %d\n", eth_dev->data->port_id);
+
+	if (lio_dev->intf_open)
+		lio_dev_stop(eth_dev);
+
+	lio_wait_for_instr_fetch(lio_dev);
+
+	lio_dev->fn_list.disable_io_queues(lio_dev);
+
+	cn23xx_vf_set_io_queues_off(lio_dev);
+
+	/* Reset iq regs (IQ_DBELL).
+	 * Clear sli_pktx_cnts (OQ_PKTS_SENT).
+	 */
+	for (i = 0; i < lio_dev->nb_rx_queues; i++) {
+		struct lio_droq *droq = lio_dev->droq[i];
+
+		if (droq == NULL)
+			break;
+
+		uint32_t pkt_count = rte_read32(droq->pkts_sent_reg);
+
+		lio_dev_dbg(lio_dev,
+			    "pending oq count %u\n", pkt_count);
+		rte_write32(pkt_count, droq->pkts_sent_reg);
+	}
+
+	/* Do FLR for the VF */
+	cn23xx_vf_ask_pf_to_do_flr(lio_dev);
+
+	/* lio_free_mbox */
+	lio_dev->fn_list.free_mbox(lio_dev);
+
+	/* Free glist resources */
+	rte_free(lio_dev->glist_head);
+	rte_free(lio_dev->glist_lock);
+	lio_dev->glist_head = NULL;
+	lio_dev->glist_lock = NULL;
+
+	lio_dev->port_configured = 0;
+
+	 /* Delete all queues */
+	lio_dev_clear_queues(eth_dev);
+}
+
+/**
  * Enable tunnel rx checksum verification from firmware.
  */
 static void
@@ -1678,6 +1740,7 @@ static int lio_dev_configure(struct rte_eth_dev *eth_dev)
 	.dev_stop		= lio_dev_stop,
 	.dev_set_link_up	= lio_dev_set_link_up,
 	.dev_set_link_down	= lio_dev_set_link_down,
+	.dev_close		= lio_dev_close,
 	.allmulticast_enable	= lio_dev_allmulticast_enable,
 	.allmulticast_disable	= lio_dev_allmulticast_disable,
 	.link_update		= lio_dev_link_update,
@@ -1839,6 +1902,7 @@ static int lio_dev_configure(struct rte_eth_dev *eth_dev)
 	rte_free(eth_dev->data->mac_addrs);
 	eth_dev->data->mac_addrs = NULL;
 
+	eth_dev->dev_ops = NULL;
 	eth_dev->rx_pkt_burst = NULL;
 	eth_dev->tx_pkt_burst = NULL;
 
diff --git a/drivers/net/liquidio/lio_ethdev.h b/drivers/net/liquidio/lio_ethdev.h
index 150e9c9..ee30615 100644
--- a/drivers/net/liquidio/lio_ethdev.h
+++ b/drivers/net/liquidio/lio_ethdev.h
@@ -196,4 +196,9 @@ struct lio_rss_set {
 	uint8_t itable[LIO_RSS_MAX_TABLE_SZ];
 	uint8_t key[LIO_RSS_MAX_KEY_SZ];
 };
+
+void lio_dev_rx_queue_release(void *rxq);
+
+void lio_dev_tx_queue_release(void *txq);
+
 #endif	/* _LIO_ETHDEV_H_ */
diff --git a/drivers/net/liquidio/lio_rxtx.c b/drivers/net/liquidio/lio_rxtx.c
index 470131c..9533015 100644
--- a/drivers/net/liquidio/lio_rxtx.c
+++ b/drivers/net/liquidio/lio_rxtx.c
@@ -918,6 +918,40 @@
 	return -1;
 }
 
+int
+lio_wait_for_instr_fetch(struct lio_device *lio_dev)
+{
+	int pending, instr_cnt;
+	int i, retry = 1000;
+
+	do {
+		instr_cnt = 0;
+
+		for (i = 0; i < LIO_MAX_INSTR_QUEUES(lio_dev); i++) {
+			if (!(lio_dev->io_qmask.iq & (1ULL << i)))
+				continue;
+
+			if (lio_dev->instr_queue[i] == NULL)
+				break;
+
+			pending = rte_atomic64_read(
+			    &lio_dev->instr_queue[i]->instr_pending);
+			if (pending)
+				lio_flush_iq(lio_dev, lio_dev->instr_queue[i]);
+
+			instr_cnt += pending;
+		}
+
+		if (instr_cnt == 0)
+			break;
+
+		rte_delay_ms(1);
+
+	} while (retry-- && instr_cnt);
+
+	return instr_cnt;
+}
+
 static inline void
 lio_ring_doorbell(struct lio_device *lio_dev,
 		  struct lio_instr_queue *iq)
@@ -1826,3 +1860,26 @@ struct lio_soft_command *
 	return processed;
 }
 
+void
+lio_dev_clear_queues(struct rte_eth_dev *eth_dev)
+{
+	struct lio_instr_queue *txq;
+	struct lio_droq *rxq;
+	uint16_t i;
+
+	for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
+		txq = eth_dev->data->tx_queues[i];
+		if (txq != NULL) {
+			lio_dev_tx_queue_release(txq);
+			eth_dev->data->tx_queues[i] = NULL;
+		}
+	}
+
+	for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
+		rxq = eth_dev->data->rx_queues[i];
+		if (rxq != NULL) {
+			lio_dev_rx_queue_release(rxq);
+			eth_dev->data->rx_queues[i] = NULL;
+		}
+	}
+}
diff --git a/drivers/net/liquidio/lio_rxtx.h b/drivers/net/liquidio/lio_rxtx.h
index d5aed6a..85685dc 100644
--- a/drivers/net/liquidio/lio_rxtx.h
+++ b/drivers/net/liquidio/lio_rxtx.h
@@ -752,6 +752,7 @@ int lio_setup_sglists(struct lio_device *lio_dev, int iq_no,
 		      int fw_mapped_iq, int num_descs, unsigned int socket_id);
 uint16_t lio_dev_xmit_pkts(void *tx_queue, struct rte_mbuf **pkts,
 			   uint16_t nb_pkts);
+int lio_wait_for_instr_fetch(struct lio_device *lio_dev);
 int lio_setup_iq(struct lio_device *lio_dev, int q_index,
 		 union octeon_txpciq iq_no, uint32_t num_descs, void *app_ctx,
 		 unsigned int socket_id);
@@ -764,4 +765,5 @@ int lio_setup_iq(struct lio_device *lio_dev, int q_index,
  */
 int lio_setup_instr_queue0(struct lio_device *lio_dev);
 void lio_free_instr_queue0(struct lio_device *lio_dev);
+void lio_dev_clear_queues(struct rte_eth_dev *eth_dev);
 #endif	/* _LIO_RXTX_H_ */
-- 
1.8.3.1



More information about the dev mailing list