From: Alfredo Cardigliano <cardigliano@ntop.org>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 06/17] net/ionic: add basic lif support
Date: Sat, 12 Oct 2019 02:26:57 +0200 [thread overview]
Message-ID: <157084001706.11524.13694428931628528417.stgit@devele> (raw)
In-Reply-To: <157083994018.11524.11276616720287263690.stgit@devele>
Initialize LIFs (Logical Interfaces) which represents
external connections. The NIC can multiplex many LIFs
to a single port, but in most setups, LIF0 is the
primary control for the port.
Create a device for each LIF.
Signed-off-by: Alfredo Cardigliano <cardigliano@ntop.org>
Reviewed-by: Shannon Nelson <snelson@pensando.io>
---
drivers/net/ionic/Makefile | 2 +
drivers/net/ionic/ionic.h | 5 +
drivers/net/ionic/ionic_dev.c | 38 ++++++++++
drivers/net/ionic/ionic_dev.h | 8 ++
drivers/net/ionic/ionic_ethdev.c | 119 ++++++++++++++++++++++++++++++++
drivers/net/ionic/ionic_ethdev.h | 14 ++++
drivers/net/ionic/ionic_lif.c | 142 ++++++++++++++++++++++++++++++++++++++
drivers/net/ionic/ionic_lif.h | 49 +++++++++++++
drivers/net/ionic/meson.build | 4 +
9 files changed, 378 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/ionic/ionic_ethdev.h
create mode 100644 drivers/net/ionic/ionic_lif.c
create mode 100644 drivers/net/ionic/ionic_lif.h
diff --git a/drivers/net/ionic/Makefile b/drivers/net/ionic/Makefile
index 4d42e3778..a1378bdbe 100644
--- a/drivers/net/ionic/Makefile
+++ b/drivers/net/ionic/Makefile
@@ -37,6 +37,7 @@ ifeq ($(shell test $(GCC_VERSION) -ge 44 && echo 1), 1)
CFLAGS += -Wno-deprecated -Wno-unused-parameter -Wno-unused-value
CFLAGS += -Wno-strict-aliasing -Wno-format-extra-args
CFLAGS += -Wno-missing-field-initializers -Wno-pointer-arith
+CFLAGS += -Wno-deprecated-declarations
endif
ifeq ($(shell test $(GCC_VERSION) -ge 70 && echo 1), 1)
@@ -55,6 +56,7 @@ LDLIBS += -lrte_bus_pci
SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_mac_api.c
SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_dev.c
SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_lif.c
SRCS-$(CONFIG_RTE_LIBRTE_IONIC_PMD) += ionic_main.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/ionic/ionic.h b/drivers/net/ionic/ionic.h
index c15dc6b44..a30e1cf20 100644
--- a/drivers/net/ionic/ionic.h
+++ b/drivers/net/ionic/ionic.h
@@ -49,7 +49,12 @@ struct ionic_adapter {
struct ionic_dev idev;
struct ionic_dev_bar bars[IONIC_BARS_MAX];
struct ionic_identity ident;
+ struct ionic_lif *lifs[IONIC_LIFS_MAX];
uint32_t num_bars;
+ uint32_t nlifs;
+ uint32_t max_ntxqs_per_lif;
+ uint32_t max_nrxqs_per_lif;
+ uint32_t nintrs;
bool is_mgmt_nic;
struct rte_pci_device *pci_dev;
LIST_ENTRY(ionic_adapter) pci_adapters;
diff --git a/drivers/net/ionic/ionic_dev.c b/drivers/net/ionic/ionic_dev.c
index 7a9890175..9d25c5e15 100644
--- a/drivers/net/ionic/ionic_dev.c
+++ b/drivers/net/ionic/ionic_dev.c
@@ -253,3 +253,41 @@ ionic_dev_cmd_port_loopback(struct ionic_dev *idev, uint8_t loopback_mode)
ionic_dev_cmd_go(idev, &cmd);
}
+
+/* LIF commands */
+
+void
+ionic_dev_cmd_lif_identify(struct ionic_dev *idev, uint8_t type, uint8_t ver)
+{
+ union ionic_dev_cmd cmd = {
+ .lif_identify.opcode = IONIC_CMD_LIF_IDENTIFY,
+ .lif_identify.type = type,
+ .lif_identify.ver = ver,
+ };
+
+ ionic_dev_cmd_go(idev, &cmd);
+}
+
+void
+ionic_dev_cmd_lif_init(struct ionic_dev *idev, uint16_t lif_index,
+ rte_iova_t info_pa)
+{
+ union ionic_dev_cmd cmd = {
+ .lif_init.opcode = IONIC_CMD_LIF_INIT,
+ .lif_init.index = lif_index,
+ .lif_init.info_pa = info_pa,
+ };
+
+ ionic_dev_cmd_go(idev, &cmd);
+}
+
+void
+ionic_dev_cmd_lif_reset(struct ionic_dev *idev, uint16_t lif_index)
+{
+ union ionic_dev_cmd cmd = {
+ .lif_init.opcode = IONIC_CMD_LIF_RESET,
+ .lif_init.index = lif_index,
+ };
+
+ ionic_dev_cmd_go(idev, &cmd);
+}
diff --git a/drivers/net/ionic/ionic_dev.h b/drivers/net/ionic/ionic_dev.h
index aaa031980..9ab482c8a 100644
--- a/drivers/net/ionic/ionic_dev.h
+++ b/drivers/net/ionic/ionic_dev.h
@@ -20,6 +20,8 @@
*/
#define IONIC_API_VERSION "3"
+#define IONIC_LIFS_MAX 1024
+
#define IONIC_DEVCMD_TIMEOUT 30 /* devcmd_timeout */
#define IONIC_ALIGN 4096
@@ -153,4 +155,10 @@ void ionic_dev_cmd_port_pause(struct ionic_dev *idev, uint8_t pause_type);
void ionic_dev_cmd_port_loopback(struct ionic_dev *idev,
uint8_t loopback_mode);
+void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, uint8_t type,
+ uint8_t ver);
+void ionic_dev_cmd_lif_init(struct ionic_dev *idev, uint16_t lif_index,
+ rte_iova_t addr);
+void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, uint16_t lif_index);
+
#endif /* _IONIC_DEV_H_ */
diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index 61999bf1d..a0a788ab3 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -7,11 +7,17 @@
#include <rte_ethdev.h>
#include <rte_ethdev_driver.h>
#include <rte_malloc.h>
+#include <rte_ethdev_pci.h>
#include "ionic_logs.h"
#include "ionic.h"
#include "ionic_dev.h"
#include "ionic_mac_api.h"
+#include "ionic_lif.h"
+#include "ionic_ethdev.h"
+
+static int eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params);
+static int eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev);
int ionic_logtype_init;
int ionic_logtype_driver;
@@ -23,6 +29,9 @@ static const struct rte_pci_id pci_id_ionic_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static const struct eth_dev_ops ionic_eth_dev_ops = {
+};
+
/*
* There is no room in struct rte_pci_driver to keep a reference
* to the adapter, using a static list for the time being.
@@ -31,10 +40,75 @@ static LIST_HEAD(ionic_pci_adapters_list, ionic_adapter) ionic_pci_adapters =
LIST_HEAD_INITIALIZER(ionic_pci_adapters);
static rte_spinlock_t ionic_pci_adapters_lock = RTE_SPINLOCK_INITIALIZER;
+static int
+eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = (struct ionic_adapter *)init_params;
+ int err;
+
+ ionic_init_print_call();
+
+ eth_dev->dev_ops = &ionic_eth_dev_ops;
+
+ /* Multi-process not supported, primary does initialization anyway */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+ lif->index = adapter->nlifs;
+ lif->eth_dev = eth_dev;
+ lif->adapter = adapter;
+ adapter->lifs[adapter->nlifs] = lif;
+
+ err = ionic_lif_alloc(lif);
+
+ if (err) {
+ ionic_init_print(ERR, "Cannot allocate LIFs: %d, aborting",
+ err);
+ return err;
+ }
+
+ err = ionic_lif_init(lif);
+
+ if (err) {
+ ionic_init_print(ERR, "Cannot init LIFs: %d, aborting", err);
+ return err;
+ }
+
+ ionic_init_print(DEBUG, "Port %u initialized", eth_dev->data->port_id);
+
+ return 0;
+}
+
+static int
+eth_ionic_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+
+ ionic_init_print_call();
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return 0;
+
+ adapter->lifs[lif->index] = NULL;
+
+ ionic_lif_deinit(lif);
+ ionic_lif_free(lif);
+
+ eth_dev->dev_ops = NULL;
+
+ return 0;
+}
+
static int
eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
{
+ char name[RTE_ETH_NAME_MAX_LEN];
struct rte_mem_resource *resource;
struct ionic_adapter *adapter;
struct ionic_hw *hw;
@@ -119,6 +193,41 @@ eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
return err;
}
+ /* Configure LIFs */
+ err = ionic_lif_identify(adapter);
+
+ if (err) {
+ ionic_init_print(ERR, "Cannot identify lif: %d, aborting", err);
+ return err;
+ }
+
+ /* Allocate and init LIFs */
+ err = ionic_lifs_size(adapter);
+
+ if (err) {
+ ionic_init_print(ERR, "Cannot size LIFs: %d, aborting", err);
+ return err;
+ }
+
+ adapter->nlifs = 0;
+ for (i = 0; i < adapter->ident.dev.nlifs; i++) {
+ snprintf(name, sizeof(name), "net_%s_lif_%lu",
+ pci_dev->device.name, i);
+
+ err = rte_eth_dev_create(&pci_dev->device, name,
+ sizeof(struct ionic_lif),
+ NULL, NULL,
+ eth_ionic_dev_init, adapter);
+
+ if (err) {
+ ionic_init_print(ERR, "Cannot create eth device for "
+ "ionic lif %s", name);
+ break;
+ }
+
+ adapter->nlifs++;
+ }
+
rte_spinlock_lock(&ionic_pci_adapters_lock);
LIST_INSERT_HEAD(&ionic_pci_adapters, adapter, pci_adapters);
rte_spinlock_unlock(&ionic_pci_adapters_lock);
@@ -130,6 +239,8 @@ static int
eth_ionic_pci_remove(struct rte_pci_device *pci_dev)
{
struct ionic_adapter *adapter = NULL;
+ struct ionic_lif *lif;
+ uint32_t i;
rte_spinlock_lock(&ionic_pci_adapters_lock);
LIST_FOREACH(adapter, &ionic_pci_adapters, pci_adapters) {
@@ -142,8 +253,14 @@ eth_ionic_pci_remove(struct rte_pci_device *pci_dev)
LIST_REMOVE(adapter, pci_adapters);
rte_spinlock_unlock(&ionic_pci_adapters_lock);
- if (adapter)
+ if (adapter) {
+ for (i = 0; i < adapter->nlifs; i++) {
+ lif = adapter->lifs[i];
+ rte_eth_dev_destroy(lif->eth_dev, eth_ionic_dev_uninit);
+ }
+
rte_free(adapter);
+ }
return 0;
}
diff --git a/drivers/net/ionic/ionic_ethdev.h b/drivers/net/ionic/ionic_ethdev.h
new file mode 100644
index 000000000..9f1c0320d
--- /dev/null
+++ b/drivers/net/ionic/ionic_ethdev.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#ifndef _IONIC_ETHDEV_H_
+#define _IONIC_ETHDEV_H_
+
+#define IONIC_ETH_DEV_TO_LIF(eth_dev) ((struct ionic_lif *) \
+ eth_dev->data->dev_private)
+#define IONIC_ETH_DEV_TO_ADAPTER(eth_dev) \
+ (IONIC_ETH_DEV_TO_LIF(eth_dev)->adapter)
+
+#endif /* _IONIC_ETHDEV_H_ */
+
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
new file mode 100644
index 000000000..c67619d85
--- /dev/null
+++ b/drivers/net/ionic/ionic_lif.c
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#include <rte_malloc.h>
+#include <rte_ethdev_driver.h>
+
+#include "ionic.h"
+#include "ionic_logs.h"
+#include "ionic_lif.h"
+#include "ionic_ethdev.h"
+
+int
+ionic_lif_alloc(struct ionic_lif *lif)
+{
+ uint32_t socket_id = rte_socket_id();
+
+ snprintf(lif->name, sizeof(lif->name), "lif%u", lif->index);
+
+ ionic_init_print(DEBUG, "Allocating Lif Info");
+
+ lif->info_sz = RTE_ALIGN(sizeof(*lif->info), PAGE_SIZE);
+
+ lif->info_z = rte_eth_dma_zone_reserve(lif->eth_dev,
+ "lif_info", 0 /* queue_idx*/,
+ lif->info_sz, IONIC_ALIGN, socket_id);
+
+ if (!lif->info_z) {
+ ionic_init_print(ERR, "Cannot allocate lif info memory");
+ return -ENOMEM;
+ }
+
+ lif->info = lif->info_z->addr;
+ lif->info_pa = lif->info_z->iova;
+
+ return 0;
+}
+
+void
+ionic_lif_free(struct ionic_lif *lif)
+{
+ if (lif->info)
+ rte_memzone_free(lif->info_z);
+}
+
+int
+ionic_lif_init(struct ionic_lif *lif)
+{
+ struct ionic_dev *idev = &lif->adapter->idev;
+ struct ionic_q_init_comp comp;
+ int err;
+
+ ionic_dev_cmd_lif_init(idev, lif->index, lif->info_pa);
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ ionic_dev_cmd_comp(idev, &comp);
+ if (err)
+ return err;
+
+ lif->hw_index = comp.hw_index;
+
+ lif->state |= IONIC_LIF_F_INITED;
+
+ return 0;
+}
+
+void
+ionic_lif_deinit(struct ionic_lif *lif)
+{
+ if (!(lif->state & IONIC_LIF_F_INITED))
+ return;
+
+ lif->state &= ~IONIC_LIF_F_INITED;
+}
+
+int
+ionic_lif_identify(struct ionic_adapter *adapter)
+{
+ struct ionic_dev *idev = &adapter->idev;
+ struct ionic_identity *ident = &adapter->ident;
+ int err;
+ unsigned int i;
+ unsigned int lif_words = sizeof(ident->lif.words) /
+ sizeof(ident->lif.words[0]);
+ unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
+ sizeof(idev->dev_cmd->data[0]);
+ unsigned int nwords;
+
+ ionic_dev_cmd_lif_identify(idev, IONIC_LIF_TYPE_CLASSIC,
+ IONIC_IDENTITY_VERSION_1);
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ if (err)
+ return (err);
+
+ nwords = RTE_MIN(lif_words, cmd_words);
+ for (i = 0; i < nwords; i++)
+ ident->lif.words[i] = ioread32(&idev->dev_cmd->data[i]);
+
+ ionic_init_print(INFO, "capabilities 0x%lx ", ident->lif.capabilities);
+
+ ionic_init_print(INFO, "eth.max_ucast_filters 0x%x ",
+ ident->lif.eth.max_ucast_filters);
+ ionic_init_print(INFO, "eth.max_mcast_filters 0x%x ",
+ ident->lif.eth.max_mcast_filters);
+
+ ionic_init_print(INFO, "eth.features 0x%lx ",
+ ident->lif.eth.config.features);
+ ionic_init_print(INFO, "eth.queue_count[IONIC_QTYPE_ADMINQ] 0x%x ",
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_ADMINQ]);
+ ionic_init_print(INFO, "eth.queue_count[IONIC_QTYPE_NOTIFYQ] 0x%x ",
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_NOTIFYQ]);
+ ionic_init_print(INFO, "eth.queue_count[IONIC_QTYPE_RXQ] 0x%x ",
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]);
+ ionic_init_print(INFO, "eth.queue_count[IONIC_QTYPE_TXQ] 0x%x ",
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]);
+
+ return 0;
+}
+
+int
+ionic_lifs_size(struct ionic_adapter *adapter)
+{
+ struct ionic_identity *ident = &adapter->ident;
+ uint32_t nlifs = ident->dev.nlifs;
+ uint32_t nintrs, dev_nintrs = ident->dev.nintrs;
+
+ adapter->max_ntxqs_per_lif =
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
+ adapter->max_nrxqs_per_lif =
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
+
+ nintrs = nlifs * 1 /* notifyq */;
+
+ if (nintrs > dev_nintrs) {
+ ionic_init_print(ERR, "At most %d intr queues supported, minimum required is %u",
+ dev_nintrs, nintrs);
+ return -ENOSPC;
+ }
+
+ adapter->nintrs = nintrs;
+
+ return 0;
+}
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
new file mode 100644
index 000000000..374cebd05
--- /dev/null
+++ b/drivers/net/ionic/ionic_lif.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
+ */
+
+#ifndef _IONIC_LIF_H_
+#define _IONIC_LIF_H_
+
+#include <inttypes.h>
+
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+
+#include "ionic_osdep.h"
+#include "ionic_dev.h"
+
+#define IONIC_LIF_F_INITED BIT(0)
+
+#define IONIC_LIF_NAME_MAX_SZ (32)
+
+struct ionic_lif {
+ struct ionic_adapter *adapter;
+ struct rte_eth_dev *eth_dev;
+ uint16_t port_id; /**< Device port identifier */
+ uint32_t index;
+ uint32_t hw_index;
+ char name[IONIC_LIF_NAME_MAX_SZ];
+ uint32_t state;
+ uint32_t info_sz;
+ struct ionic_lif_info *info;
+ rte_iova_t info_pa;
+ const struct rte_memzone *info_z;
+};
+
+int ionic_lif_identify(struct ionic_adapter *adapter);
+int ionic_lifs_size(struct ionic_adapter *ionic);
+
+int ionic_lif_alloc(struct ionic_lif *lif);
+void ionic_lif_free(struct ionic_lif *lif);
+
+int ionic_lif_init(struct ionic_lif *lif);
+void ionic_lif_deinit(struct ionic_lif *lif);
+
+int ionic_lif_start(struct ionic_lif *lif);
+int ionic_lif_stop(struct ionic_lif *lif);
+
+int ionic_lif_configure(struct ionic_lif *lif);
+void ionic_lif_reset(struct ionic_lif *lif);
+
+#endif /* _IONIC_LIF_H_ */
diff --git a/drivers/net/ionic/meson.build b/drivers/net/ionic/meson.build
index bd63e6136..0cf5a0cc7 100644
--- a/drivers/net/ionic/meson.build
+++ b/drivers/net/ionic/meson.build
@@ -7,7 +7,7 @@ sources = files(
'ionic_mac_api.c',
'ionic_dev.c',
'ionic_ethdev.c',
- 'ionic_main.c',
- 'ionic_ethdev.c'
+ 'ionic_lif.c',
+ 'ionic_main.c'
)
next prev parent reply other threads:[~2019-10-12 0:27 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-12 0:26 [dpdk-dev] [PATCH 00/17] Series short description Alfredo Cardigliano
2019-10-12 0:26 ` [dpdk-dev] [PATCH 01/17] net/ionic: add skeleton Alfredo Cardigliano
2019-10-12 0:26 ` [dpdk-dev] [PATCH 02/17] net/ionic: add hardware structures definitions Alfredo Cardigliano
2019-10-12 0:26 ` [dpdk-dev] [PATCH 03/17] net/ionic: add log Alfredo Cardigliano
2019-10-12 15:23 ` Stephen Hemminger
2019-10-12 0:26 ` [dpdk-dev] [PATCH 04/17] net/ionic: register and initialize the adapter Alfredo Cardigliano
2019-10-12 0:26 ` [dpdk-dev] [PATCH 05/17] net/ionic: add port management commands Alfredo Cardigliano
2019-10-12 0:26 ` Alfredo Cardigliano [this message]
2019-10-12 15:26 ` [dpdk-dev] [PATCH 06/17] net/ionic: add basic lif support Stephen Hemminger
2019-10-12 0:27 ` [dpdk-dev] [PATCH 07/17] net/ionic: add doorbells Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 08/17] net/ionic: add adminq support Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 09/17] net/ionic: add notifyq support Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 10/17] net/ionic: add basic port operations Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 11/17] net/ionic: add RX filters support Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 12/17] net/ionic: net-ionic-add-flow-control-support Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 13/17] net/ionic: add RSS support Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 14/17] net/ionic: add RX and TX handling Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 15/17] net/ionic: add stats Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 16/17] net/ionic: add TX checksum support Alfredo Cardigliano
2019-10-12 0:27 ` [dpdk-dev] [PATCH 17/17] net/ionic: read fw version Alfredo Cardigliano
2019-10-12 15:28 ` [dpdk-dev] [PATCH 00/17] Series short description Stephen Hemminger
2019-10-14 7:16 ` Alfredo Cardigliano
2019-10-14 7:56 ` Andrew Rybchenko
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=157084001706.11524.13694428931628528417.stgit@devele \
--to=cardigliano@ntop.org \
--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).