net/sfc: interrupts support sufficient for event queue init
authorAndrew Rybchenko <arybchenko@solarflare.com>
Tue, 29 Nov 2016 16:19:08 +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/Makefile
drivers/net/sfc/sfc.c
drivers/net/sfc/sfc.h
drivers/net/sfc/sfc_intr.c [new file with mode: 0644]

index ea8cb0c..d19497c 100644 (file)
@@ -82,6 +82,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_kvargs.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc.c
 SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_mcdi.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_intr.c
 
 VPATH += $(SRCDIR)/base
 
index b676524..8d18def 100644 (file)
@@ -257,10 +257,17 @@ sfc_start(struct sfc_adapter *sa)
        if (rc != 0)
                goto fail_nic_init;
 
+       rc = sfc_intr_start(sa);
+       if (rc != 0)
+               goto fail_intr_start;
+
        sa->state = SFC_ADAPTER_STARTED;
        sfc_log_init(sa, "done");
        return 0;
 
+fail_intr_start:
+       efx_nic_fini(sa->nic);
+
 fail_nic_init:
 fail_set_drv_limits:
        sa->state = SFC_ADAPTER_CONFIGURED;
@@ -290,6 +297,7 @@ sfc_stop(struct sfc_adapter *sa)
 
        sa->state = SFC_ADAPTER_STOPPING;
 
+       sfc_intr_stop(sa);
        efx_nic_fini(sa->nic);
 
        sa->state = SFC_ADAPTER_CONFIGURED;
@@ -312,10 +320,15 @@ sfc_configure(struct sfc_adapter *sa)
        if (rc != 0)
                goto fail_check_conf;
 
+       rc = sfc_intr_init(sa);
+       if (rc != 0)
+               goto fail_intr_init;
+
        sa->state = SFC_ADAPTER_CONFIGURED;
        sfc_log_init(sa, "done");
        return 0;
 
+fail_intr_init:
 fail_check_conf:
        sa->state = SFC_ADAPTER_INITIALIZED;
        sfc_log_init(sa, "failed %d", rc);
@@ -332,6 +345,8 @@ sfc_close(struct sfc_adapter *sa)
        SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
        sa->state = SFC_ADAPTER_CLOSING;
 
+       sfc_intr_fini(sa);
+
        sa->state = SFC_ADAPTER_INITIALIZED;
        sfc_log_init(sa, "done");
 }
@@ -423,6 +438,10 @@ sfc_attach(struct sfc_adapter *sa)
        if (rc != 0)
                goto fail_estimate_rsrc_limits;
 
+       rc = sfc_intr_attach(sa);
+       if (rc != 0)
+               goto fail_intr_attach;
+
        sfc_log_init(sa, "fini nic");
        efx_nic_fini(enp);
 
@@ -431,6 +450,7 @@ sfc_attach(struct sfc_adapter *sa)
        sfc_log_init(sa, "done");
        return 0;
 
+fail_intr_attach:
 fail_estimate_rsrc_limits:
 fail_nic_reset:
        sfc_log_init(sa, "unprobe nic");
@@ -462,6 +482,8 @@ sfc_detach(struct sfc_adapter *sa)
 
        SFC_ASSERT(sfc_adapter_is_locked(sa));
 
+       sfc_intr_detach(sa);
+
        sfc_log_init(sa, "unprobe nic");
        efx_nic_unprobe(enp);
 
index 6bf7638..44a98f4 100644 (file)
@@ -112,6 +112,10 @@ struct sfc_mcdi {
        efx_mcdi_transport_t            transport;
 };
 
+struct sfc_intr {
+       efx_intr_type_t                 type;
+};
+
 /* Adapter private data */
 struct sfc_adapter {
        /*
@@ -132,6 +136,7 @@ struct sfc_adapter {
        rte_spinlock_t                  nic_lock;
 
        struct sfc_mcdi                 mcdi;
+       struct sfc_intr                 intr;
 
        unsigned int                    rxq_max;
        unsigned int                    txq_max;
@@ -187,6 +192,13 @@ void sfc_mcdi_fini(struct sfc_adapter *sa);
 int sfc_configure(struct sfc_adapter *sa);
 void sfc_close(struct sfc_adapter *sa);
 
+int sfc_intr_attach(struct sfc_adapter *sa);
+void sfc_intr_detach(struct sfc_adapter *sa);
+int sfc_intr_init(struct sfc_adapter *sa);
+void sfc_intr_fini(struct sfc_adapter *sa);
+int sfc_intr_start(struct sfc_adapter *sa);
+void sfc_intr_stop(struct sfc_adapter *sa);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/net/sfc/sfc_intr.c b/drivers/net/sfc/sfc_intr.c
new file mode 100644 (file)
index 0000000..622b7cb
--- /dev/null
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "efx.h"
+
+#include "sfc.h"
+#include "sfc_log.h"
+
+int
+sfc_intr_start(struct sfc_adapter *sa)
+{
+       struct sfc_intr *intr = &sa->intr;
+       struct rte_intr_handle *intr_handle;
+       struct rte_pci_device *pci_dev;
+       int rc;
+
+       sfc_log_init(sa, "entry");
+
+       /*
+        * The EFX common code event queue module depends on the interrupt
+        * module. Ensure that the interrupt module is always initialized
+        * (even if interrupts are not used).  Status memory is required
+        * for Siena only and may be NULL for EF10.
+        */
+       sfc_log_init(sa, "efx_intr_init");
+       rc = efx_intr_init(sa->nic, intr->type, NULL);
+       if (rc != 0)
+               goto fail_intr_init;
+
+       pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
+       intr_handle = &pci_dev->intr_handle;
+
+       sfc_log_init(sa, "done type=%u max_intr=%d nb_efd=%u vec=%p",
+                    intr_handle->type, intr_handle->max_intr,
+                    intr_handle->nb_efd, intr_handle->intr_vec);
+       return 0;
+
+fail_intr_init:
+       sfc_log_init(sa, "failed %d", rc);
+       return rc;
+}
+
+void
+sfc_intr_stop(struct sfc_adapter *sa)
+{
+       sfc_log_init(sa, "entry");
+
+       efx_intr_fini(sa->nic);
+
+       sfc_log_init(sa, "done");
+}
+
+int
+sfc_intr_init(struct sfc_adapter *sa)
+{
+       sfc_log_init(sa, "entry");
+
+       sfc_log_init(sa, "done");
+       return 0;
+}
+
+void
+sfc_intr_fini(struct sfc_adapter *sa)
+{
+       sfc_log_init(sa, "entry");
+
+       sfc_log_init(sa, "done");
+}
+
+int
+sfc_intr_attach(struct sfc_adapter *sa)
+{
+       struct sfc_intr *intr = &sa->intr;
+       struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
+
+       sfc_log_init(sa, "entry");
+
+       switch (pci_dev->intr_handle.type) {
+#ifdef RTE_EXEC_ENV_LINUXAPP
+       case RTE_INTR_HANDLE_VFIO_LEGACY:
+               intr->type = EFX_INTR_LINE;
+               break;
+       case RTE_INTR_HANDLE_VFIO_MSI:
+       case RTE_INTR_HANDLE_VFIO_MSIX:
+               intr->type = EFX_INTR_MESSAGE;
+               break;
+#endif
+       default:
+               intr->type = EFX_INTR_INVALID;
+               break;
+       }
+
+       sfc_log_init(sa, "done");
+       return 0;
+}
+
+void
+sfc_intr_detach(struct sfc_adapter *sa)
+{
+       sfc_log_init(sa, "entry");
+
+       sa->intr.type = EFX_INTR_INVALID;
+
+       sfc_log_init(sa, "done");
+}