net/sfc: add device start and stop operations
authorAndrew Rybchenko <arybchenko@solarflare.com>
Tue, 29 Nov 2016 16:19:06 +0000 (16:19 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:39:26 +0000 (19:39 +0100)
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
drivers/net/sfc/sfc.c
drivers/net/sfc/sfc.h
drivers/net/sfc/sfc_ethdev.c

index 5e6f7c1..736900a 100644 (file)
@@ -126,6 +126,71 @@ sfc_check_conf(struct sfc_adapter *sa)
        return rc;
 }
 
+int
+sfc_start(struct sfc_adapter *sa)
+{
+       int rc;
+
+       sfc_log_init(sa, "entry");
+
+       SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+       switch (sa->state) {
+       case SFC_ADAPTER_CONFIGURED:
+               break;
+       case SFC_ADAPTER_STARTED:
+               sfc_info(sa, "already started");
+               return 0;
+       default:
+               rc = EINVAL;
+               goto fail_bad_state;
+       }
+
+       sa->state = SFC_ADAPTER_STARTING;
+
+       sfc_log_init(sa, "init nic");
+       rc = efx_nic_init(sa->nic);
+       if (rc != 0)
+               goto fail_nic_init;
+
+       sa->state = SFC_ADAPTER_STARTED;
+       sfc_log_init(sa, "done");
+       return 0;
+
+fail_nic_init:
+       sa->state = SFC_ADAPTER_CONFIGURED;
+fail_bad_state:
+       sfc_log_init(sa, "failed %d", rc);
+       return rc;
+}
+
+void
+sfc_stop(struct sfc_adapter *sa)
+{
+       sfc_log_init(sa, "entry");
+
+       SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+       switch (sa->state) {
+       case SFC_ADAPTER_STARTED:
+               break;
+       case SFC_ADAPTER_CONFIGURED:
+               sfc_info(sa, "already stopped");
+               return;
+       default:
+               sfc_err(sa, "stop in unexpected state %u", sa->state);
+               SFC_ASSERT(B_FALSE);
+               return;
+       }
+
+       sa->state = SFC_ADAPTER_STOPPING;
+
+       efx_nic_fini(sa->nic);
+
+       sa->state = SFC_ADAPTER_CONFIGURED;
+       sfc_log_init(sa, "done");
+}
+
 int
 sfc_configure(struct sfc_adapter *sa)
 {
index 2683bc5..6bf7638 100644 (file)
@@ -67,6 +67,20 @@ extern "C" {
  *     V                       |.dev_close
  * +---------------+------------+
  * |  CONFIGURED   |
+ * +---------------+<-----------+
+ *     |.dev_start             |
+ *     V                       |
+ * +---------------+           |
+ * |   STARTING    |------------^
+ * +---------------+ failed    |
+ *     |success                |
+ *     |               +---------------+
+ *     |               |   STOPPING    |
+ *     |               +---------------+
+ *     |                       ^
+ *     V                       |.dev_stop
+ * +---------------+------------+
+ * |    STARTED    |
  * +---------------+
  */
 enum sfc_adapter_state {
@@ -75,6 +89,9 @@ enum sfc_adapter_state {
        SFC_ADAPTER_CONFIGURING,
        SFC_ADAPTER_CONFIGURED,
        SFC_ADAPTER_CLOSING,
+       SFC_ADAPTER_STARTING,
+       SFC_ADAPTER_STARTED,
+       SFC_ADAPTER_STOPPING,
 
        SFC_ADAPTER_NSTATES
 };
@@ -161,6 +178,8 @@ void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp);
 
 int sfc_attach(struct sfc_adapter *sa);
 void sfc_detach(struct sfc_adapter *sa);
+int sfc_start(struct sfc_adapter *sa);
+void sfc_stop(struct sfc_adapter *sa);
 
 int sfc_mcdi_init(struct sfc_adapter *sa);
 void sfc_mcdi_fini(struct sfc_adapter *sa);
index 190750f..2eb5e9a 100644 (file)
@@ -81,6 +81,37 @@ sfc_dev_configure(struct rte_eth_dev *dev)
        return -rc;
 }
 
+static int
+sfc_dev_start(struct rte_eth_dev *dev)
+{
+       struct sfc_adapter *sa = dev->data->dev_private;
+       int rc;
+
+       sfc_log_init(sa, "entry");
+
+       sfc_adapter_lock(sa);
+       rc = sfc_start(sa);
+       sfc_adapter_unlock(sa);
+
+       sfc_log_init(sa, "done %d", rc);
+       SFC_ASSERT(rc >= 0);
+       return -rc;
+}
+
+static void
+sfc_dev_stop(struct rte_eth_dev *dev)
+{
+       struct sfc_adapter *sa = dev->data->dev_private;
+
+       sfc_log_init(sa, "entry");
+
+       sfc_adapter_lock(sa);
+       sfc_stop(sa);
+       sfc_adapter_unlock(sa);
+
+       sfc_log_init(sa, "done");
+}
+
 static void
 sfc_dev_close(struct rte_eth_dev *dev)
 {
@@ -90,6 +121,10 @@ sfc_dev_close(struct rte_eth_dev *dev)
 
        sfc_adapter_lock(sa);
        switch (sa->state) {
+       case SFC_ADAPTER_STARTED:
+               sfc_stop(sa);
+               SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
+               /* FALLTHROUGH */
        case SFC_ADAPTER_CONFIGURED:
                sfc_close(sa);
                SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
@@ -107,6 +142,8 @@ sfc_dev_close(struct rte_eth_dev *dev)
 
 static const struct eth_dev_ops sfc_eth_dev_ops = {
        .dev_configure                  = sfc_dev_configure,
+       .dev_start                      = sfc_dev_start,
+       .dev_stop                       = sfc_dev_stop,
        .dev_close                      = sfc_dev_close,
        .dev_infos_get                  = sfc_dev_infos_get,
 };