From: Andrew Rybchenko <arybchenko@solarflare.com>
To: <dev@dpdk.org>
Subject: [dpdk-dev] [PATCH 32/56] net/sfc: implement driver operation to init device on attach
Date: Mon, 21 Nov 2016 15:00:46 +0000 [thread overview]
Message-ID: <1479740470-6723-33-git-send-email-arybchenko@solarflare.com> (raw)
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>
The setup and configuration of the PMD is not performance sensitive,
but is not thread safe either. It is possible that the multiple
read/writes during PMD setup and configuration could be corrupted
in a multi-thread environment. Since this is not performance
sensitive, the developer can choose to add their own layer to provide
thread-safe setup and configuration. It is expected that, in most
applications, the initial configuration of the network ports would be
done by a single thread at startup.
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/efx/Makefile | 2 +
drivers/net/sfc/efx/sfc.c | 227 +++++++++++++++++++++++++++++++++++++++
drivers/net/sfc/efx/sfc.h | 100 +++++++++++++++++
drivers/net/sfc/efx/sfc_debug.h | 12 +++
drivers/net/sfc/efx/sfc_ethdev.c | 52 ++++++++-
drivers/net/sfc/efx/sfc_mcdi.c | 197 +++++++++++++++++++++++++++++++++
6 files changed, 589 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/sfc/efx/sfc.c
create mode 100644 drivers/net/sfc/efx/sfc_mcdi.c
diff --git a/drivers/net/sfc/efx/Makefile b/drivers/net/sfc/efx/Makefile
index de95ea8..eadb1ea 100644
--- a/drivers/net/sfc/efx/Makefile
+++ b/drivers/net/sfc/efx/Makefile
@@ -82,6 +82,8 @@ LIBABIVER := 1
#
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
VPATH += $(SRCDIR)/base
diff --git a/drivers/net/sfc/efx/sfc.c b/drivers/net/sfc/efx/sfc.c
new file mode 100644
index 0000000..2a17d26
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc.c
@@ -0,0 +1,227 @@
+/*-
+ * 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.
+ */
+
+/* sysconf() */
+#include <unistd.h>
+
+#include <rte_errno.h>
+
+#include "efx.h"
+
+#include "sfc.h"
+#include "sfc_log.h"
+
+
+int
+sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
+ size_t len, int socket_id, efsys_mem_t *esmp)
+{
+ const struct rte_memzone *mz;
+
+ sfc_log_init(sa, "name=%s id=%u len=%lu socket_id=%d",
+ name, id, len, socket_id);
+
+ mz = rte_eth_dma_zone_reserve(sa->eth_dev, name, id, len,
+ sysconf(_SC_PAGESIZE), socket_id);
+ if (mz == NULL) {
+ sfc_err(sa, "cannot reserve DMA zone for %s:%u %#x@%d: %s",
+ name, (unsigned int)id, (unsigned int)len, socket_id,
+ rte_strerror(rte_errno));
+ return ENOMEM;
+ }
+
+ esmp->esm_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+ if (esmp->esm_addr == RTE_BAD_PHYS_ADDR) {
+ (void)rte_memzone_free(mz);
+ return EFAULT;
+ }
+
+ esmp->esm_mz = mz;
+ esmp->esm_base = mz->addr;
+
+ return 0;
+}
+
+void
+sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp)
+{
+ int rc;
+
+ sfc_log_init(sa, "name=%s", esmp->esm_mz->name);
+
+ rc = rte_memzone_free(esmp->esm_mz);
+ if (rc != 0)
+ sfc_err(sa, "rte_memzone_free(() failed: %d", rc);
+
+ memset(esmp, 0, sizeof(*esmp));
+}
+
+static int
+sfc_mem_bar_init(struct sfc_adapter *sa)
+{
+ struct rte_eth_dev *eth_dev = sa->eth_dev;
+ struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ efsys_bar_t *ebp = &sa->mem_bar;
+ unsigned int i;
+ struct rte_mem_resource *res;
+
+ for (i = 0; i < RTE_DIM(pci_dev->mem_resource); i++) {
+ res = &pci_dev->mem_resource[i];
+ if ((res->len != 0) && (res->phys_addr != 0)) {
+ /* Found first memory BAR */
+ SFC_BAR_LOCK_INIT(ebp, eth_dev->data->name);
+ ebp->esb_rid = i;
+ ebp->esb_dev = pci_dev;
+ ebp->esb_base = res->addr;
+ return 0;
+ }
+ }
+
+ return EFAULT;
+}
+
+static void
+sfc_mem_bar_fini(struct sfc_adapter *sa)
+{
+ efsys_bar_t *ebp = &sa->mem_bar;
+
+ SFC_BAR_LOCK_DESTROY(ebp);
+ memset(ebp, 0, sizeof(*ebp));
+}
+
+int
+sfc_attach(struct sfc_adapter *sa)
+{
+ struct rte_pci_device *pci_dev = sa->eth_dev->pci_dev;
+ efx_nic_t *enp;
+ int rc;
+
+ sfc_log_init(sa, "entry");
+
+ SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+ sa->socket_id = rte_socket_id();
+
+ sfc_log_init(sa, "init mem bar");
+ rc = sfc_mem_bar_init(sa);
+ if (rc != 0)
+ goto fail_mem_bar_init;
+
+ sfc_log_init(sa, "get family");
+ rc = efx_family(pci_dev->id.vendor_id, pci_dev->id.device_id,
+ &sa->family);
+ if (rc != 0)
+ goto fail_family;
+ sfc_log_init(sa, "family is %u", sa->family);
+
+ sfc_log_init(sa, "create nic");
+ rte_spinlock_init(&sa->nic_lock);
+ rc = efx_nic_create(sa->family, (efsys_identifier_t *)sa,
+ &sa->mem_bar, &sa->nic_lock, &enp);
+ if (rc != 0)
+ goto fail_nic_create;
+ sa->nic = enp;
+
+ rc = sfc_mcdi_init(sa);
+ if (rc != 0)
+ goto fail_mcdi_init;
+
+ sfc_log_init(sa, "probe nic");
+ rc = efx_nic_probe(enp);
+ if (rc != 0)
+ goto fail_nic_probe;
+
+ efx_mcdi_new_epoch(enp);
+
+ sfc_log_init(sa, "reset nic");
+ rc = efx_nic_reset(enp);
+ if (rc != 0)
+ goto fail_nic_reset;
+
+ /* Initialize NIC to double-check hardware */
+ sfc_log_init(sa, "init nic");
+ rc = efx_nic_init(enp);
+ if (rc != 0)
+ goto fail_nic_init;
+
+ sfc_log_init(sa, "fini nic");
+ efx_nic_fini(enp);
+
+ sa->rxq_max = 1;
+ sa->txq_max = 1;
+
+ sa->state = SFC_ADAPTER_INITIALIZED;
+
+ sfc_log_init(sa, "done");
+ return 0;
+
+fail_nic_init:
+fail_nic_reset:
+ sfc_log_init(sa, "unprobe nic");
+ efx_nic_unprobe(enp);
+
+fail_nic_probe:
+ sfc_mcdi_fini(sa);
+
+fail_mcdi_init:
+ sfc_log_init(sa, "destroy nic");
+ sa->nic = NULL;
+ efx_nic_destroy(enp);
+
+fail_nic_create:
+fail_family:
+ sfc_mem_bar_fini(sa);
+
+fail_mem_bar_init:
+ sfc_log_init(sa, "failed %d", rc);
+ return rc;
+}
+
+void
+sfc_detach(struct sfc_adapter *sa)
+{
+ efx_nic_t *enp = sa->nic;
+
+ sfc_log_init(sa, "entry");
+
+ SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+ sfc_log_init(sa, "unprobe nic");
+ efx_nic_unprobe(enp);
+
+ sfc_mcdi_fini(sa);
+
+ sfc_log_init(sa, "destroy nic");
+ sa->nic = NULL;
+ efx_nic_destroy(enp);
+
+ sfc_mem_bar_fini(sa);
+
+ sa->state = SFC_ADAPTER_UNINITIALIZED;
+}
diff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h
index 16fd2bb..01d652d 100644
--- a/drivers/net/sfc/efx/sfc.h
+++ b/drivers/net/sfc/efx/sfc.h
@@ -34,18 +34,118 @@
#include <rte_ethdev.h>
#include <rte_kvargs.h>
+#include <rte_spinlock.h>
+
+#include "efx.h"
#ifdef __cplusplus
extern "C" {
#endif
+/*
+ * +---------------+
+ * | UNINITIALIZED |<-----------+
+ * +---------------+ |
+ * |.eth_dev_init |.eth_dev_uninit
+ * V |
+ * +---------------+------------+
+ * | INITIALIZED |
+ * +---------------+
+ */
+enum sfc_adapter_state {
+ SFC_ADAPTER_UNINITIALIZED = 0,
+ SFC_ADAPTER_INITIALIZED,
+
+ SFC_ADAPTER_NSTATES
+};
+
+enum sfc_mcdi_state {
+ SFC_MCDI_UNINITIALIZED = 0,
+ SFC_MCDI_INITIALIZED,
+ SFC_MCDI_BUSY,
+ SFC_MCDI_COMPLETED,
+
+ SFC_MCDI_NSTATES
+};
+
+struct sfc_mcdi {
+ rte_spinlock_t lock;
+ efsys_mem_t mem;
+ enum sfc_mcdi_state state;
+ efx_mcdi_transport_t transport;
+};
+
/* 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.
+ */
+ rte_spinlock_t lock;
+ enum sfc_adapter_state state;
struct rte_eth_dev *eth_dev;
struct rte_kvargs *kvargs;
bool debug_init;
+ int socket_id;
+ efsys_bar_t mem_bar;
+ efx_family_t family;
+ efx_nic_t *nic;
+ rte_spinlock_t nic_lock;
+
+ struct sfc_mcdi mcdi;
+
+ unsigned int rxq_max;
+ unsigned int txq_max;
};
+/*
+ * Add wrapper functions to acquire/release lock to be able to remove or
+ * change the lock in one place.
+ */
+
+static inline void
+sfc_adapter_lock_init(struct sfc_adapter *sa)
+{
+ rte_spinlock_init(&sa->lock);
+}
+
+static inline int
+sfc_adapter_is_locked(struct sfc_adapter *sa)
+{
+ return rte_spinlock_is_locked(&sa->lock);
+}
+
+static inline void
+sfc_adapter_lock(struct sfc_adapter *sa)
+{
+ rte_spinlock_lock(&sa->lock);
+}
+
+static inline void
+sfc_adapter_unlock(struct sfc_adapter *sa)
+{
+ rte_spinlock_unlock(&sa->lock);
+}
+
+static inline void
+sfc_adapter_lock_destroy(struct sfc_adapter *sa)
+{
+ /* Just for symmetry of the API */
+}
+
+int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
+ size_t len, int socket_id, efsys_mem_t *esmp);
+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_mcdi_init(struct sfc_adapter *sa);
+void sfc_mcdi_fini(struct sfc_adapter *sa);
+
#ifdef __cplusplus
}
#endif
diff --git a/drivers/net/sfc/efx/sfc_debug.h b/drivers/net/sfc/efx/sfc_debug.h
index de3ec61..2c3988b 100644
--- a/drivers/net/sfc/efx/sfc_debug.h
+++ b/drivers/net/sfc/efx/sfc_debug.h
@@ -42,4 +42,16 @@
#define SFC_ASSERT(exp) RTE_ASSERT(exp)
#endif
+/* Log PMD message, automatically add prefix and \n */
+#define sfc_panic(sa, fmt, args...) \
+ do { \
+ const struct rte_eth_dev *_dev = (sa)->eth_dev; \
+ const struct rte_pci_device *_pci_dev = _dev->pci_dev; \
+ \
+ rte_panic("sfc " PCI_PRI_FMT " #%" PRIu8 ": " fmt "\n", \
+ _pci_dev->addr.domain, _pci_dev->addr.bus, \
+ _pci_dev->addr.devid, _pci_dev->addr.function,\
+ _dev->data->port_id, ##args); \
+ } while (0)
+
#endif /* _SFC_DEBUG_H_ */
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index 0deff07..e5b609c 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -31,6 +31,8 @@
#include <rte_ethdev.h>
#include <rte_pci.h>
+#include "efx.h"
+
#include "sfc.h"
#include "sfc_debug.h"
#include "sfc_log.h"
@@ -55,6 +57,8 @@ sfc_eth_dev_init(struct rte_eth_dev *dev)
struct sfc_adapter *sa = dev->data->dev_private;
struct rte_pci_device *pci_dev = dev->pci_dev;
int rc;
+ const efx_nic_cfg_t *encp;
+ const struct ether_addr *from;
/* Required for logging */
sa->eth_dev = dev;
@@ -73,11 +77,43 @@ sfc_eth_dev_init(struct rte_eth_dev *dev)
sfc_log_init(sa, "entry");
+ dev->data->mac_addrs = rte_zmalloc("sfc", ETHER_ADDR_LEN, 0);
+ if (dev->data->mac_addrs == NULL) {
+ rc = ENOMEM;
+ goto fail_mac_addrs;
+ }
+
+ sfc_adapter_lock_init(sa);
+ sfc_adapter_lock(sa);
+
+ sfc_log_init(sa, "attaching");
+ rc = sfc_attach(sa);
+ if (rc != 0)
+ goto fail_attach;
+
+ encp = efx_nic_cfg_get(sa->nic);
+
+ /*
+ * The arguments are really reverse order in comparison to
+ * Linux kernel. Copy from NIC config to Ethernet device data.
+ */
+ from = (const struct ether_addr *)(encp->enc_mac_addr);
+ ether_addr_copy(from, &dev->data->mac_addrs[0]);
+
dev->dev_ops = &sfc_eth_dev_ops;
+ sfc_adapter_unlock(sa);
+
sfc_log_init(sa, "done");
return 0;
+fail_attach:
+ sfc_adapter_unlock(sa);
+ sfc_adapter_lock_destroy(sa);
+ rte_free(dev->data->mac_addrs);
+ dev->data->mac_addrs = NULL;
+
+fail_mac_addrs:
fail_kvarg_debug_init:
sfc_kvargs_cleanup(sa);
@@ -94,10 +130,20 @@ sfc_eth_dev_uninit(struct rte_eth_dev *dev)
sfc_log_init(sa, "entry");
+ sfc_adapter_lock(sa);
+
+ sfc_detach(sa);
+
+ rte_free(dev->data->mac_addrs);
+ dev->data->mac_addrs = NULL;
+
dev->dev_ops = NULL;
sfc_kvargs_cleanup(sa);
+ sfc_adapter_unlock(sa);
+ sfc_adapter_lock_destroy(sa);
+
sfc_log_init(sa, "done");
/* Required for logging, so cleanup last */
@@ -106,13 +152,17 @@ sfc_eth_dev_uninit(struct rte_eth_dev *dev)
}
static const struct rte_pci_id pci_id_sfc_efx_map[] = {
+ { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_FARMINGDALE) },
+ { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_GREENPORT) },
+ { RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD) },
{ .vendor_id = 0 /* sentinel */ }
};
static struct eth_driver sfc_efx_pmd = {
.pci_drv = {
.id_table = pci_id_sfc_efx_map,
- .drv_flags = 0,
+ .drv_flags =
+ RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
},
diff --git a/drivers/net/sfc/efx/sfc_mcdi.c b/drivers/net/sfc/efx/sfc_mcdi.c
new file mode 100644
index 0000000..bf641d9
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_mcdi.c
@@ -0,0 +1,197 @@
+/*-
+ * 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 <rte_cycles.h>
+
+#include "efx.h"
+#include "efx_mcdi.h"
+#include "efx_regs_mcdi.h"
+
+#include "sfc.h"
+#include "sfc_log.h"
+
+#define SFC_MCDI_POLL_INTERVAL_MIN_US 10 /* 10us in 1us units */
+#define SFC_MCDI_POLL_INTERVAL_MAX_US (US_PER_S / 10) /* 100ms in 1us units */
+#define SFC_MCDI_WATCHDOG_INTERVAL_US (10 * US_PER_S) /* 10s in 1us units */
+
+static void
+sfc_mcdi_timeout(struct sfc_adapter *sa)
+{
+ sfc_warn(sa, "MC TIMEOUT");
+
+ sfc_panic(sa, "MCDI timeout handling is not implemented\n");
+}
+
+static void
+sfc_mcdi_poll(struct sfc_adapter *sa)
+{
+ efx_nic_t *enp;
+ unsigned int delay_total;
+ unsigned int delay_us;
+ boolean_t aborted;
+
+ delay_total = 0;
+ delay_us = SFC_MCDI_POLL_INTERVAL_MIN_US;
+ enp = sa->nic;
+
+ do {
+ if (efx_mcdi_request_poll(enp))
+ return;
+
+ if (delay_total > SFC_MCDI_WATCHDOG_INTERVAL_US) {
+ aborted = efx_mcdi_request_abort(enp);
+ SFC_ASSERT(aborted);
+ sfc_mcdi_timeout(sa);
+ return;
+ }
+
+ rte_delay_us(delay_us);
+
+ delay_total += delay_us;
+
+ /* Exponentially back off the poll frequency */
+ RTE_BUILD_BUG_ON(SFC_MCDI_POLL_INTERVAL_MAX_US > UINT_MAX / 2);
+ delay_us *= 2;
+ if (delay_us > SFC_MCDI_POLL_INTERVAL_MAX_US)
+ delay_us = SFC_MCDI_POLL_INTERVAL_MAX_US;
+
+ } while (1);
+}
+
+static void
+sfc_mcdi_execute(void *arg, efx_mcdi_req_t *emrp)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)arg;
+ struct sfc_mcdi *mcdi = &sa->mcdi;
+
+ rte_spinlock_lock(&mcdi->lock);
+
+ SFC_ASSERT(mcdi->state == SFC_MCDI_INITIALIZED);
+
+ efx_mcdi_request_start(sa->nic, emrp, B_FALSE);
+ sfc_mcdi_poll(sa);
+
+ rte_spinlock_unlock(&mcdi->lock);
+}
+
+static void
+sfc_mcdi_ev_cpl(void *arg)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)arg;
+ struct sfc_mcdi *mcdi = &sa->mcdi;
+
+ SFC_ASSERT(mcdi->state == SFC_MCDI_INITIALIZED);
+
+ /* MCDI is polled, completions are not expected */
+ SFC_ASSERT(0);
+}
+
+static void
+sfc_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
+{
+ struct sfc_adapter *sa = (struct sfc_adapter *)arg;
+
+ sfc_warn(sa, "MC %s",
+ (eme == EFX_MCDI_EXCEPTION_MC_REBOOT) ? "REBOOT" :
+ (eme == EFX_MCDI_EXCEPTION_MC_BADASSERT) ? "BADASSERT" : "UNKNOWN");
+
+ sfc_panic(sa, "MCDI exceptions handling is not implemented\n");
+}
+
+int
+sfc_mcdi_init(struct sfc_adapter *sa)
+{
+ struct sfc_mcdi *mcdi;
+ size_t max_msg_size;
+ efx_mcdi_transport_t *emtp;
+ int rc;
+
+ sfc_log_init(sa, "entry");
+
+ mcdi = &sa->mcdi;
+
+ SFC_ASSERT(mcdi->state == SFC_MCDI_UNINITIALIZED);
+
+ rte_spinlock_init(&mcdi->lock);
+
+ mcdi->state = SFC_MCDI_INITIALIZED;
+
+ max_msg_size = sizeof(uint32_t) + MCDI_CTL_SDU_LEN_MAX_V2;
+ rc = sfc_dma_alloc(sa, "mcdi", 0, max_msg_size, sa->socket_id,
+ &mcdi->mem);
+ if (rc != 0)
+ goto fail_dma_alloc;
+
+ emtp = &mcdi->transport;
+ emtp->emt_context = sa;
+ emtp->emt_dma_mem = &mcdi->mem;
+ emtp->emt_execute = sfc_mcdi_execute;
+ emtp->emt_ev_cpl = sfc_mcdi_ev_cpl;
+ emtp->emt_exception = sfc_mcdi_exception;
+
+ sfc_log_init(sa, "init MCDI");
+ rc = efx_mcdi_init(sa->nic, emtp);
+ if (rc != 0)
+ goto fail_mcdi_init;
+
+ return 0;
+
+fail_mcdi_init:
+ memset(emtp, 0, sizeof(*emtp));
+ sfc_dma_free(sa, &mcdi->mem);
+
+fail_dma_alloc:
+ mcdi->state = SFC_MCDI_UNINITIALIZED;
+ return rc;
+}
+
+void
+sfc_mcdi_fini(struct sfc_adapter *sa)
+{
+ struct sfc_mcdi *mcdi;
+ efx_mcdi_transport_t *emtp;
+
+ sfc_log_init(sa, "entry");
+
+ mcdi = &sa->mcdi;
+ emtp = &mcdi->transport;
+
+ rte_spinlock_lock(&mcdi->lock);
+
+ SFC_ASSERT(mcdi->state == SFC_MCDI_INITIALIZED);
+ mcdi->state = SFC_MCDI_UNINITIALIZED;
+
+ sfc_log_init(sa, "fini MCDI");
+ efx_mcdi_fini(sa->nic);
+ memset(emtp, 0, sizeof(*emtp));
+
+ rte_spinlock_unlock(&mcdi->lock);
+
+ sfc_dma_free(sa, &mcdi->mem);
+}
--
2.5.5
next prev parent reply other threads:[~2016-11-21 15:01 UTC|newest]
Thread overview: 149+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-21 15:00 [dpdk-dev] [PATCH 00/56] Solarflare libefx-based PMD Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 01/56] net/sfc: libefx-based PMD stub sufficient to build and init Andrew Rybchenko
2016-11-23 15:26 ` Ferruh Yigit
2016-11-24 15:59 ` Andrew Rybchenko
2016-11-25 10:17 ` Ferruh Yigit
2016-11-25 14:22 ` Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 02/56] net/sfc: import libefx base Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 03/56] net/sfc: import libefx register definitions Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 04/56] net/sfc: import libefx filters support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 05/56] net/sfc: import libefx MCDI definition Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 06/56] net/sfc: import libefx MCDI implementation Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 07/56] net/sfc: import libefx MCDI logging support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 08/56] net/sfc: import libefx MCDI proxy authorization support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 09/56] net/sfc: import libefx 5xxx/6xxx family support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 10/56] net/sfc: import libefx SFN7xxx " Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 11/56] net/sfc: import libefx SFN8xxx " Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 12/56] net/sfc: import libefx diagnostics support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 13/56] net/sfc: import libefx built-in selftest support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 14/56] net/sfc: import libefx software per-queue statistics support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 15/56] net/sfc: import libefx PHY flags control support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 16/56] net/sfc: import libefx PHY statistics support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 17/56] net/sfc: import libefx PHY LEDs control support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 18/56] net/sfc: import libefx MAC statistics support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 19/56] net/sfc: import libefx event prefetch support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 20/56] net/sfc: import libefx Rx scatter support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 21/56] net/sfc: import libefx RSS support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 22/56] net/sfc: import libefx loopback control support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 23/56] net/sfc: import libefx monitors statistics support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 24/56] net/sfc: import libefx support to access monitors via MCDI Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 25/56] net/sfc: import libefx support for Rx packed stream mode Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 26/56] net/sfc: import libefx NVRAM support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 27/56] net/sfc: import libefx VPD support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 28/56] net/sfc: import libefx bootrom configuration support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 29/56] net/sfc: import libefx licensing support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 30/56] net/sfc: include libefx in build Andrew Rybchenko
2016-11-23 15:26 ` Ferruh Yigit
2016-11-24 15:44 ` Andrew Rybchenko
2016-11-25 10:24 ` Ferruh Yigit
2016-11-25 15:05 ` Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 31/56] net/sfc: implement dummy callback to get device information Andrew Rybchenko
2016-11-23 15:26 ` Ferruh Yigit
2016-11-24 15:05 ` Andrew Rybchenko
2016-11-21 15:00 ` Andrew Rybchenko [this message]
2016-11-23 15:26 ` [dpdk-dev] [PATCH 32/56] net/sfc: implement driver operation to init device on attach Ferruh Yigit
2016-11-24 14:58 ` Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 33/56] net/sfc: add device configure and close stubs Andrew Rybchenko
2016-11-23 15:26 ` Ferruh Yigit
2016-11-24 14:46 ` Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 34/56] net/sfc: add device configuration checks Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 35/56] net/sfc: implement device start and stop operations Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 36/56] net/sfc: make available resources estimation and allocation Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 37/56] net/sfc: interrupts support sufficient for event queue init Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 38/56] net/sfc: implement event queue support Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 39/56] net/sfc: implement EVQ dummy exception handling Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 40/56] net/sfc: maintain management event queue Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 41/56] net/sfc: periodic management EVQ polling using alarm Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 42/56] net/sfc: minimum port control sufficient to receive traffic Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 43/56] net/sfc: implement device operation to retrieve link info Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 44/56] net/sfc: implement Rx subsystem stubs Andrew Rybchenko
2016-11-21 15:00 ` [dpdk-dev] [PATCH 45/56] net/sfc: check configured rxmode Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 46/56] net/sfc: implement Rx queue setup release operations Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 47/56] net/sfc: calculate Rx buffer size which may be used Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 48/56] net/sfc: validate Rx queue buffers setup Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 49/56] net/sfc: implement Rx queue start and stop operations Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 50/56] net/sfc: implement device callback to Rx burst of packets Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 51/56] net/sfc: discard scattered packet on Rx correctly Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 52/56] net/sfc: provide basic stubs for Tx subsystem Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 53/56] net/sfc: add function to check configured Tx mode Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 54/56] net/sfc: add callbacks to set up and release Tx queues Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 55/56] net/sfc: implement transmit path start / stop Andrew Rybchenko
2016-11-21 15:01 ` [dpdk-dev] [PATCH 56/56] net/sfc: add callback to send bursts of packets Andrew Rybchenko
2016-11-23 0:02 ` [dpdk-dev] [PATCH 00/56] Solarflare libefx-based PMD Ferruh Yigit
2016-11-23 0:10 ` Ferruh Yigit
2016-11-23 7:49 ` Andrew Rybchenko
2016-11-23 9:57 ` Mcnamara, John
2016-11-23 13:34 ` Thomas Monjalon
2016-11-23 19:21 ` Stephen Hemminger
2016-11-24 10:59 ` Andrew Rybchenko
2016-11-25 10:24 ` Ferruh Yigit
2016-11-25 12:02 ` Andrew Rybchenko
2016-11-25 12:43 ` Ferruh Yigit
2016-11-25 13:00 ` Thomas Monjalon
2016-11-25 13:23 ` Andrew Rybchenko
2016-11-25 12:44 ` Andrew Rybchenko
2016-11-23 15:29 ` Ferruh Yigit
2016-11-24 16:15 ` Andrew Rybchenko
2016-11-25 10:25 ` Ferruh Yigit
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 00/55] " Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 01/55] net/sfc: libefx-based PMD stub sufficient to build and init Andrew Rybchenko
2016-12-02 14:54 ` Ferruh Yigit
2016-12-02 15:03 ` Andrew Rybchenko
2016-12-02 15:08 ` Ferruh Yigit
2016-12-02 15:11 ` Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 02/55] net/sfc: import libefx base Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 03/55] net/sfc: import libefx register definitions Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 04/55] net/sfc: import libefx filters support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 05/55] net/sfc: import libefx MCDI definition Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 06/55] net/sfc: import libefx MCDI implementation Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 07/55] net/sfc: import libefx MCDI logging support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 08/55] net/sfc: import libefx MCDI proxy authorization support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 09/55] net/sfc: import libefx 5xxx/6xxx family support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 10/55] net/sfc: import libefx SFN7xxx " Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 11/55] net/sfc: import libefx SFN8xxx " Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 12/55] net/sfc: import libefx diagnostics support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 13/55] net/sfc: import libefx built-in selftest support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 14/55] net/sfc: import libefx software per-queue statistics support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 15/55] net/sfc: import libefx PHY flags control support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 16/55] net/sfc: import libefx PHY statistics support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 17/55] net/sfc: import libefx PHY LEDs control support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 18/55] net/sfc: import libefx MAC statistics support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 19/55] net/sfc: import libefx event prefetch support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 20/55] net/sfc: import libefx Rx scatter support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 21/55] net/sfc: import libefx RSS support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 22/55] net/sfc: import libefx loopback control support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 23/55] net/sfc: import libefx monitors statistics support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 24/55] net/sfc: import libefx support to access monitors via MCDI Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 25/55] net/sfc: import libefx support for Rx packed stream mode Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 26/55] net/sfc: import libefx NVRAM support Andrew Rybchenko
2016-11-29 16:18 ` [dpdk-dev] [PATCH v2 27/55] net/sfc: import libefx VPD support Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 28/55] net/sfc: import libefx bootrom configuration support Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 29/55] net/sfc: import libefx licensing support Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 30/55] net/sfc: include libefx in build Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 31/55] net/sfc: implement driver operation to init device on attach Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 32/55] net/sfc: add device configure and close stubs Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 33/55] net/sfc: add device configuration checks Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 34/55] net/sfc: implement device start and stop operations Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 35/55] net/sfc: make available resources estimation and allocation Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 36/55] net/sfc: interrupts support sufficient for event queue init Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 37/55] net/sfc: implement event queue support Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 38/55] net/sfc: implement EVQ dummy exception handling Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 39/55] net/sfc: maintain management event queue Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 40/55] net/sfc: periodic management EVQ polling using alarm Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 41/55] net/sfc: minimum port control sufficient to receive traffic Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 42/55] net/sfc: implement device operation to retrieve link info Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 43/55] net/sfc: implement Rx subsystem stubs Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 44/55] net/sfc: check configured rxmode Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 45/55] net/sfc: implement Rx queue setup release operations Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 46/55] net/sfc: calculate Rx buffer size which may be used Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 47/55] net/sfc: validate Rx queue buffers setup Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 48/55] net/sfc: implement Rx queue start and stop operations Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 49/55] net/sfc: implement device callback to Rx burst of packets Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 50/55] net/sfc: discard scattered packet on Rx correctly Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 51/55] net/sfc: provide basic stubs for Tx subsystem Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 52/55] net/sfc: add function to check configured Tx mode Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 53/55] net/sfc: add callbacks to set up and release Tx queues Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 54/55] net/sfc: implement transmit path start / stop Andrew Rybchenko
2016-11-29 16:19 ` [dpdk-dev] [PATCH v2 55/55] net/sfc: add callback to send bursts of packets Andrew Rybchenko
2016-12-02 14:55 ` [dpdk-dev] [PATCH v2 00/55] Solarflare libefx-based PMD Ferruh Yigit
2016-12-05 13:38 ` Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1479740470-6723-33-git-send-email-arybchenko@solarflare.com \
--to=arybchenko@solarflare.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).