Reviewed-by: Andy Moreton <amoreton at solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
---
 drivers/net/sfc/efx/sfc.c        | 29 +++++++++++++++++++
 drivers/net/sfc/efx/sfc.h        | 31 ++++++++++++++++----
 drivers/net/sfc/efx/sfc_ethdev.c | 62 ++++++++++++++++++++++++++++++++++++++--
 3 files changed, 114 insertions(+), 8 deletions(-)

diff --git a/drivers/net/sfc/efx/sfc.c b/drivers/net/sfc/efx/sfc.c
index 2a17d26..cbb14d7 100644
--- a/drivers/net/sfc/efx/sfc.c
+++ b/drivers/net/sfc/efx/sfc.c
@@ -82,6 +82,35 @@ sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp)
        memset(esmp, 0, sizeof(*esmp));
 }

+int
+sfc_configure(struct sfc_adapter *sa)
+{
+       sfc_log_init(sa, "entry");
+
+       SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+       SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
+       sa->state = SFC_ADAPTER_CONFIGURING;
+
+       sa->state = SFC_ADAPTER_CONFIGURED;
+       sfc_log_init(sa, "done");
+       return 0;
+}
+
+void
+sfc_close(struct sfc_adapter *sa)
+{
+       sfc_log_init(sa, "entry");
+
+       SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+       SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
+       sa->state = SFC_ADAPTER_CLOSING;
+
+       sa->state = SFC_ADAPTER_INITIALIZED;
+       sfc_log_init(sa, "done");
+}
+
 static int
 sfc_mem_bar_init(struct sfc_adapter *sa)
 {
diff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h
index 01d652d..d040f98 100644
--- a/drivers/net/sfc/efx/sfc.h
+++ b/drivers/net/sfc/efx/sfc.h
@@ -50,11 +50,28 @@ extern "C" {
  *     V                       |
  * +---------------+------------+
  * |  INITIALIZED  |
+ * +---------------+<-----------+
+ *     |.dev_configure         |
+ *     V                       |
+ * +---------------+           |
+ * |  CONFIGURING  |------------^
+ * +---------------+ failed    |
+ *     |success                |
+ *     |               +---------------+
+ *     |               |    CLOSING    |
+ *     |               +---------------+
+ *     |                       ^
+ *     V                       |.dev_close
+ * +---------------+------------+
+ * |  CONFIGURED   |
  * +---------------+
  */
 enum sfc_adapter_state {
        SFC_ADAPTER_UNINITIALIZED = 0,
        SFC_ADAPTER_INITIALIZED,
+       SFC_ADAPTER_CONFIGURING,
+       SFC_ADAPTER_CONFIGURED,
+       SFC_ADAPTER_CLOSING,

        SFC_ADAPTER_NSTATES
 };
@@ -78,11 +95,10 @@ struct sfc_mcdi {
 /* Adapter private data */
 struct sfc_adapter {
        /*
-        * PMD setup and configuration is not thread safe.
-        * Since it is not performance sensitive, it is better to guarantee
-        * thread-safety and add device level lock.
-        * Adapter control operations which change its state should
-        * acquire the lock.
+        * PMD setup and configuration is not thread safe. Since it is not
+        * performance sensitive, it is better to guarantee thread-safety
+        * and add device level lock. Adapter control operations which
+        * change its state should acquire the lock.
         */
        rte_spinlock_t                  lock;
        enum sfc_adapter_state          state;
@@ -131,7 +147,7 @@ sfc_adapter_unlock(struct sfc_adapter *sa)
 }

 static inline void
-sfc_adapter_lock_destroy(struct sfc_adapter *sa)
+sfc_adapter_lock_fini(struct sfc_adapter *sa)
 {
        /* Just for symmetry of the API */
 }
@@ -146,6 +162,9 @@ void sfc_detach(struct sfc_adapter *sa);
 int sfc_mcdi_init(struct sfc_adapter *sa);
 void sfc_mcdi_fini(struct sfc_adapter *sa);

+int sfc_configure(struct sfc_adapter *sa);
+void sfc_close(struct sfc_adapter *sa);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index e5b609c..120ee45 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -47,7 +47,65 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct 
rte_eth_dev_info *dev_info)
        sfc_log_init(sa, "entry");
 }

+static int
+sfc_dev_configure(struct rte_eth_dev *dev)
+{
+       struct rte_eth_dev_data *dev_data = dev->data;
+       struct sfc_adapter *sa = dev_data->dev_private;
+       int rc;
+
+       sfc_log_init(sa, "entry n_rxq=%u n_txq=%u",
+                    dev_data->nb_rx_queues, dev_data->nb_tx_queues);
+
+       sfc_adapter_lock(sa);
+       switch (sa->state) {
+       case SFC_ADAPTER_CONFIGURED:
+               sfc_close(sa);
+               SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
+               /* FALLTHROUGH */
+       case SFC_ADAPTER_INITIALIZED:
+               rc = sfc_configure(sa);
+               break;
+       default:
+               sfc_err(sa, "unexpected adapter state %u to configure",
+                       sa->state);
+               rc = EINVAL;
+               break;
+       }
+       sfc_adapter_unlock(sa);
+
+       sfc_log_init(sa, "done %d", rc);
+       SFC_ASSERT(rc >= 0);
+       return -rc;
+}
+
+static void
+sfc_dev_close(struct rte_eth_dev *dev)
+{
+       struct sfc_adapter *sa = dev->data->dev_private;
+
+       sfc_log_init(sa, "entry");
+
+       sfc_adapter_lock(sa);
+       switch (sa->state) {
+       case SFC_ADAPTER_CONFIGURED:
+               sfc_close(sa);
+               SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
+               /* FALLTHROUGH */
+       case SFC_ADAPTER_INITIALIZED:
+               break;
+       default:
+               sfc_err(sa, "unexpected adapter state %u on close", sa->state);
+               break;
+       }
+       sfc_adapter_unlock(sa);
+
+       sfc_log_init(sa, "done");
+}
+
 static const struct eth_dev_ops sfc_eth_dev_ops = {
+       .dev_configure                  = sfc_dev_configure,
+       .dev_close                      = sfc_dev_close,
        .dev_infos_get                  = sfc_dev_infos_get,
 };

@@ -109,7 +167,7 @@ sfc_eth_dev_init(struct rte_eth_dev *dev)

 fail_attach:
        sfc_adapter_unlock(sa);
-       sfc_adapter_lock_destroy(sa);
+       sfc_adapter_lock_fini(sa);
        rte_free(dev->data->mac_addrs);
        dev->data->mac_addrs = NULL;

@@ -142,7 +200,7 @@ sfc_eth_dev_uninit(struct rte_eth_dev *dev)
        sfc_kvargs_cleanup(sa);

        sfc_adapter_unlock(sa);
-       sfc_adapter_lock_destroy(sa);
+       sfc_adapter_lock_fini(sa);

        sfc_log_init(sa, "done");

-- 
2.5.5

Reply via email to