From: Alfredo Cardigliano <cardigliano@ntop.org>
To: Alfredo Cardigliano <cardigliano@ntop.org>,
John McNamara <john.mcnamara@intel.com>,
Marko Kovacevic <marko.kovacevic@intel.com>
Cc: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v5 10/17] net/ionic: add basic port operations
Date: Sun, 19 Jan 2020 16:53:48 +0100 [thread overview]
Message-ID: <20200119155356.20403-11-cardigliano@ntop.org> (raw)
In-Reply-To: <20200119155356.20403-1-cardigliano@ntop.org>
Add support for port start/stop and handle basic features
including mtu and link up/down.
Signed-off-by: Alfredo Cardigliano <cardigliano@ntop.org>
Reviewed-by: Shannon Nelson <snelson@pensando.io>
---
doc/guides/nics/features/ionic.ini | 4 +
drivers/net/ionic/ionic.h | 1 +
drivers/net/ionic/ionic_dev.h | 3 +
drivers/net/ionic/ionic_ethdev.c | 319 +++++++++++++++++++++++++++++
drivers/net/ionic/ionic_lif.c | 266 +++++++++++++++++++++++-
drivers/net/ionic/ionic_lif.h | 10 +
6 files changed, 602 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/features/ionic.ini b/doc/guides/nics/features/ionic.ini
index 6915d9c42..c69e5cbed 100644
--- a/doc/guides/nics/features/ionic.ini
+++ b/doc/guides/nics/features/ionic.ini
@@ -4,6 +4,10 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Speed capabilities = Y
+Link status = Y
+Link status event = Y
+MTU update = Y
Linux UIO = Y
Linux VFIO = Y
x86-64 = Y
diff --git a/drivers/net/ionic/ionic.h b/drivers/net/ionic/ionic.h
index 0243ee4ca..184fc6da0 100644
--- a/drivers/net/ionic/ionic.h
+++ b/drivers/net/ionic/ionic.h
@@ -55,6 +55,7 @@ struct ionic_adapter {
uint32_t nlifs;
uint32_t max_ntxqs_per_lif;
uint32_t max_nrxqs_per_lif;
+ uint32_t max_mac_addrs;
uint32_t link_speed;
uint32_t nintrs;
bool intrs[IONIC_INTR_CTRL_REGS_MAX];
diff --git a/drivers/net/ionic/ionic_dev.h b/drivers/net/ionic/ionic_dev.h
index a832ff405..61576621b 100644
--- a/drivers/net/ionic/ionic_dev.h
+++ b/drivers/net/ionic/ionic_dev.h
@@ -9,6 +9,9 @@
#include "ionic_if.h"
#include "ionic_regs.h"
+#define IONIC_MIN_MTU RTE_ETHER_MIN_MTU
+#define IONIC_MAX_MTU 9194
+
#define IONIC_MAX_RING_DESC 32768
#define IONIC_MIN_RING_DESC 16
diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c
index b57dce1e5..e2c9d1d68 100644
--- a/drivers/net/ionic/ionic_ethdev.c
+++ b/drivers/net/ionic/ionic_ethdev.c
@@ -18,6 +18,17 @@
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);
+static int ionic_dev_info_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_dev_info *dev_info);
+static int ionic_dev_configure(struct rte_eth_dev *dev);
+static int ionic_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
+static int ionic_dev_start(struct rte_eth_dev *dev);
+static void ionic_dev_stop(struct rte_eth_dev *dev);
+static void ionic_dev_close(struct rte_eth_dev *dev);
+static int ionic_dev_set_link_up(struct rte_eth_dev *dev);
+static int ionic_dev_set_link_down(struct rte_eth_dev *dev);
+static int ionic_dev_link_update(struct rte_eth_dev *eth_dev,
+ int wait_to_complete);
int ionic_logtype;
@@ -29,8 +40,113 @@ static const struct rte_pci_id pci_id_ionic_map[] = {
};
static const struct eth_dev_ops ionic_eth_dev_ops = {
+ .dev_infos_get = ionic_dev_info_get,
+ .dev_configure = ionic_dev_configure,
+ .mtu_set = ionic_dev_mtu_set,
+ .dev_start = ionic_dev_start,
+ .dev_stop = ionic_dev_stop,
+ .dev_close = ionic_dev_close,
+ .link_update = ionic_dev_link_update,
+ .dev_set_link_up = ionic_dev_set_link_up,
+ .dev_set_link_down = ionic_dev_set_link_down,
};
+/*
+ * Set device link up, enable tx.
+ */
+static int
+ionic_dev_set_link_up(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_dev *idev = &adapter->idev;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_UP);
+
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ if (err) {
+ IONIC_PRINT(WARNING, "Failed to bring port UP");
+ return err;
+ }
+
+ return 0;
+}
+
+/*
+ * Set device link down, disable tx.
+ */
+static int
+ionic_dev_set_link_down(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_dev *idev = &adapter->idev;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ ionic_dev_cmd_port_state(idev, IONIC_PORT_ADMIN_STATE_DOWN);
+
+ err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+ if (err) {
+ IONIC_PRINT(WARNING, "Failed to bring port DOWN");
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+ionic_dev_link_update(struct rte_eth_dev *eth_dev,
+ int wait_to_complete __rte_unused)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct rte_eth_link link;
+
+ IONIC_PRINT_CALL();
+
+ /* Initialize */
+ memset(&link, 0, sizeof(link));
+ link.link_autoneg = ETH_LINK_AUTONEG;
+
+ if (!adapter->link_up) {
+ /* Interface is down */
+ link.link_status = ETH_LINK_DOWN;
+ link.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link.link_speed = ETH_SPEED_NUM_NONE;
+ } else {
+ /* Interface is up */
+ link.link_status = ETH_LINK_UP;
+ link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ switch (adapter->link_speed) {
+ case 10000:
+ link.link_speed = ETH_SPEED_NUM_10G;
+ break;
+ case 25000:
+ link.link_speed = ETH_SPEED_NUM_25G;
+ break;
+ case 40000:
+ link.link_speed = ETH_SPEED_NUM_40G;
+ break;
+ case 50000:
+ link.link_speed = ETH_SPEED_NUM_50G;
+ break;
+ case 100000:
+ link.link_speed = ETH_SPEED_NUM_100G;
+ break;
+ default:
+ link.link_speed = ETH_SPEED_NUM_NONE;
+ break;
+ }
+ }
+
+ return rte_eth_linkstatus_set(eth_dev, &link);
+}
+
/**
* Interrupt handler triggered by NIC for handling
* specific interrupt.
@@ -55,6 +171,188 @@ ionic_dev_interrupt_handler(void *param)
}
}
+static int
+ionic_dev_mtu_set(struct rte_eth_dev *eth_dev, uint16_t mtu)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ uint32_t max_frame_size;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ /*
+ * Note: mtu check against IONIC_MIN_MTU, IONIC_MAX_MTU
+ * is done by the the API.
+ */
+
+ /*
+ * Max frame size is MTU + Ethernet header + VLAN + QinQ
+ * (plus ETHER_CRC_LEN if the adapter is able to keep CRC)
+ */
+ max_frame_size = mtu + RTE_ETHER_HDR_LEN + 4 + 4;
+
+ if (eth_dev->data->dev_conf.rxmode.max_rx_pkt_len < max_frame_size)
+ return -EINVAL;
+
+ err = ionic_lif_change_mtu(lif, mtu);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int
+ionic_dev_info_get(struct rte_eth_dev *eth_dev,
+ struct rte_eth_dev_info *dev_info)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_identity *ident = &adapter->ident;
+
+ IONIC_PRINT_CALL();
+
+ dev_info->max_rx_queues = (uint16_t)
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
+ dev_info->max_tx_queues = (uint16_t)
+ ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
+ /* Also add ETHER_CRC_LEN if the adapter is able to keep CRC */
+ dev_info->min_rx_bufsize = IONIC_MIN_MTU + RTE_ETHER_HDR_LEN;
+ dev_info->max_rx_pktlen = IONIC_MAX_MTU + RTE_ETHER_HDR_LEN;
+ dev_info->max_mac_addrs = adapter->max_mac_addrs;
+ dev_info->min_mtu = IONIC_MIN_MTU;
+ dev_info->max_mtu = IONIC_MAX_MTU;
+
+ dev_info->speed_capa =
+ ETH_LINK_SPEED_10G |
+ ETH_LINK_SPEED_25G |
+ ETH_LINK_SPEED_40G |
+ ETH_LINK_SPEED_50G |
+ ETH_LINK_SPEED_100G;
+
+ return 0;
+}
+
+static int
+ionic_dev_configure(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_lif_configure(lif);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot configure LIF: %d", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static inline uint32_t
+ionic_parse_link_speeds(uint16_t link_speeds)
+{
+ if (link_speeds & ETH_LINK_SPEED_100G)
+ return 100000;
+ else if (link_speeds & ETH_LINK_SPEED_50G)
+ return 50000;
+ else if (link_speeds & ETH_LINK_SPEED_40G)
+ return 40000;
+ else if (link_speeds & ETH_LINK_SPEED_25G)
+ return 25000;
+ else if (link_speeds & ETH_LINK_SPEED_10G)
+ return 10000;
+ else
+ return 0;
+}
+
+/*
+ * Configure device link speed and setup link.
+ * It returns 0 on success.
+ */
+static int
+ionic_dev_start(struct rte_eth_dev *eth_dev)
+{
+ struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf;
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ struct ionic_adapter *adapter = lif->adapter;
+ struct ionic_dev *idev = &adapter->idev;
+ uint32_t allowed_speeds;
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ allowed_speeds =
+ ETH_LINK_SPEED_FIXED |
+ ETH_LINK_SPEED_10G |
+ ETH_LINK_SPEED_25G |
+ ETH_LINK_SPEED_40G |
+ ETH_LINK_SPEED_50G |
+ ETH_LINK_SPEED_100G;
+
+ if (dev_conf->link_speeds & ~allowed_speeds) {
+ IONIC_PRINT(ERR, "Invalid link setting");
+ return -EINVAL;
+ }
+
+ err = ionic_lif_start(lif);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot start LIF: %d", err);
+ return err;
+ }
+
+ if (eth_dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+ uint32_t speed = ionic_parse_link_speeds(dev_conf->link_speeds);
+
+ if (speed)
+ ionic_dev_cmd_port_speed(idev, speed);
+ }
+
+ ionic_dev_link_update(eth_dev, 0);
+
+ return 0;
+}
+
+/*
+ * Stop device: disable rx and tx functions to allow for reconfiguring.
+ */
+static void
+ionic_dev_stop(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_lif_stop(lif);
+ if (err)
+ IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
+}
+
+/*
+ * Reset and stop device.
+ */
+static void
+ionic_dev_close(struct rte_eth_dev *eth_dev)
+{
+ struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_lif_stop(lif);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot stop LIF: %d", err);
+ return;
+ }
+
+ err = eth_ionic_dev_uninit(eth_dev);
+ if (err) {
+ IONIC_PRINT(ERR, "Cannot destroy LIF: %d", err);
+ return;
+ }
+}
+
static int
eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
{
@@ -78,6 +376,21 @@ eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
lif->adapter = adapter;
adapter->lifs[adapter->nlifs] = lif;
+ IONIC_PRINT(DEBUG, "Up to %u MAC addresses supported",
+ adapter->max_mac_addrs);
+
+ /* Allocate memory for storing MAC addresses */
+ eth_dev->data->mac_addrs = rte_zmalloc("ionic",
+ RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs, 0);
+
+ if (eth_dev->data->mac_addrs == NULL) {
+ IONIC_PRINT(ERR, "Failed to allocate %u bytes needed to "
+ "store MAC addresses",
+ RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs);
+ err = -ENOMEM;
+ goto err;
+ }
+
err = ionic_lif_alloc(lif);
if (err) {
IONIC_PRINT(ERR, "Cannot allocate LIFs: %d, aborting",
@@ -91,6 +404,10 @@ eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
goto err_free_lif;
}
+ /* Copy the MAC address */
+ rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr,
+ ð_dev->data->mac_addrs[0]);
+
IONIC_PRINT(DEBUG, "Port %u initialized", eth_dev->data->port_id);
return 0;
@@ -291,6 +608,8 @@ eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
goto err_free_adapter;
}
+ adapter->max_mac_addrs = adapter->ident.lif.eth.max_ucast_filters;
+
adapter->nlifs = 0;
for (i = 0; i < adapter->ident.dev.nlifs; i++) {
snprintf(name, sizeof(name), "net_%s_lif_%lu",
diff --git a/drivers/net/ionic/ionic_lif.c b/drivers/net/ionic/ionic_lif.c
index c831519b7..66038bbdb 100644
--- a/drivers/net/ionic/ionic_lif.c
+++ b/drivers/net/ionic/ionic_lif.c
@@ -10,6 +10,9 @@
#include "ionic_lif.h"
#include "ionic_ethdev.h"
+static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);
+static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);
+
int
ionic_qcq_enable(struct ionic_qcq *qcq)
{
@@ -60,6 +63,105 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
return ionic_adminq_post_wait(lif, &ctx);
}
+int
+ionic_lif_stop(struct ionic_lif *lif __rte_unused)
+{
+ /* Carrier OFF here */
+
+ return 0;
+}
+
+void
+ionic_lif_reset(struct ionic_lif *lif)
+{
+ struct ionic_dev *idev = &lif->adapter->idev;
+
+ IONIC_PRINT_CALL();
+
+ ionic_dev_cmd_lif_reset(idev, lif->index);
+ ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
+}
+
+static int
+ionic_lif_addr_add(struct ionic_lif *lif __rte_unused,
+ const uint8_t *addr __rte_unused)
+{
+ IONIC_PRINT(INFO, "%s: stubbed", __func__);
+
+ return 0;
+}
+
+static int
+ionic_lif_addr_del(struct ionic_lif *lif __rte_unused,
+ const uint8_t *addr __rte_unused)
+{
+ IONIC_PRINT(INFO, "%s: stubbed", __func__);
+
+ return 0;
+}
+
+static void
+ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.rx_mode_set = {
+ .opcode = IONIC_CMD_RX_MODE_SET,
+ .lif_index = lif->index,
+ .rx_mode = rx_mode,
+ },
+ };
+ int err;
+
+ if (rx_mode & IONIC_RX_MODE_F_UNICAST)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_UNICAST");
+ if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_MULTICAST");
+ if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_BROADCAST");
+ if (rx_mode & IONIC_RX_MODE_F_PROMISC)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_PROMISC");
+ if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
+ IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_ALLMULTI");
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ IONIC_PRINT(ERR, "Failure setting RX mode");
+}
+
+static void
+ionic_set_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
+{
+ if (lif->rx_mode != rx_mode) {
+ lif->rx_mode = rx_mode;
+ ionic_lif_rx_mode(lif, rx_mode);
+ }
+}
+
+
+int
+ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_setattr = {
+ .opcode = IONIC_CMD_LIF_SETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_MTU,
+ .mtu = new_mtu,
+ },
+ };
+ int err;
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ return err;
+
+ lif->mtu = new_mtu;
+
+ return 0;
+}
+
int
ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
{
@@ -319,7 +421,6 @@ ionic_lif_alloc(struct ionic_lif *lif)
IONIC_PRINT(DEBUG, "Allocating Notify Queue");
err = ionic_notify_qcq_alloc(lif);
-
if (err) {
IONIC_PRINT(ERR, "Cannot allocate notify queue");
return err;
@@ -593,6 +694,123 @@ ionic_lif_notifyq_init(struct ionic_lif *lif)
return 0;
}
+int
+ionic_lif_set_features(struct ionic_lif *lif)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_setattr = {
+ .opcode = IONIC_CMD_LIF_SETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_FEATURES,
+ .features = lif->features,
+ },
+ };
+ int err;
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ return err;
+
+ lif->hw_features = (ctx.cmd.lif_setattr.features &
+ ctx.comp.lif_setattr.features);
+
+ if (lif->hw_features & IONIC_ETH_HW_VLAN_TX_TAG)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_TX_TAG");
+ if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_STRIP)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_STRIP");
+ if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_FILTER)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_FILTER");
+ if (lif->hw_features & IONIC_ETH_HW_RX_HASH)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_HASH");
+ if (lif->hw_features & IONIC_ETH_HW_TX_SG)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_SG");
+ if (lif->hw_features & IONIC_ETH_HW_RX_SG)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_SG");
+ if (lif->hw_features & IONIC_ETH_HW_TX_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_CSUM");
+ if (lif->hw_features & IONIC_ETH_HW_RX_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_CSUM");
+ if (lif->hw_features & IONIC_ETH_HW_TSO)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_IPV6)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPV6");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_ECN)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_ECN");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_GRE)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_GRE_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE_CSUM");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP4)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP4");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP6)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP6");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_UDP)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP");
+ if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
+ IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP_CSUM");
+
+ return 0;
+}
+
+static int
+ionic_station_set(struct ionic_lif *lif)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_getattr = {
+ .opcode = IONIC_CMD_LIF_GETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_MAC,
+ },
+ };
+ int err;
+
+ IONIC_PRINT_CALL();
+
+ err = ionic_adminq_post_wait(lif, &ctx);
+ if (err)
+ return err;
+
+ if (!rte_is_zero_ether_addr((struct rte_ether_addr *)
+ lif->mac_addr)) {
+ IONIC_PRINT(INFO, "deleting station MAC addr");
+
+ ionic_lif_addr_del(lif, lif->mac_addr);
+ }
+
+ memcpy(lif->mac_addr, ctx.comp.lif_getattr.mac, RTE_ETHER_ADDR_LEN);
+
+ if (rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
+ IONIC_PRINT(NOTICE, "empty MAC addr (VF?)");
+ return 0;
+ }
+
+ IONIC_PRINT(DEBUG, "adding station MAC addr");
+
+ ionic_lif_addr_add(lif, lif->mac_addr);
+
+ return 0;
+}
+
+static void
+ionic_lif_set_name(struct ionic_lif *lif)
+{
+ struct ionic_admin_ctx ctx = {
+ .pending_work = true,
+ .cmd.lif_setattr = {
+ .opcode = IONIC_CMD_LIF_SETATTR,
+ .index = lif->index,
+ .attr = IONIC_LIF_ATTR_NAME,
+ },
+ };
+
+ snprintf(ctx.cmd.lif_setattr.name, sizeof(ctx.cmd.lif_setattr.name),
+ "%d", lif->port_id);
+
+ ionic_adminq_post_wait(lif, &ctx);
+}
+
int
ionic_lif_init(struct ionic_lif *lif)
{
@@ -616,10 +834,25 @@ ionic_lif_init(struct ionic_lif *lif)
if (err)
goto err_out_adminq_deinit;
+ lif->features = 0;
+
+ err = ionic_lif_set_features(lif);
+ if (err)
+ goto err_out_notifyq_deinit;
+
+ err = ionic_station_set(lif);
+ if (err)
+ goto err_out_notifyq_deinit;
+
+ ionic_lif_set_name(lif);
+
lif->state |= IONIC_LIF_F_INITED;
return 0;
+err_out_notifyq_deinit:
+ ionic_lif_qcq_deinit(lif, lif->notifyqcq);
+
err_out_adminq_deinit:
ionic_lif_qcq_deinit(lif, lif->adminqcq);
@@ -638,6 +871,37 @@ ionic_lif_deinit(struct ionic_lif *lif)
lif->state &= ~IONIC_LIF_F_INITED;
}
+int
+ionic_lif_configure(struct ionic_lif *lif)
+{
+ lif->port_id = lif->eth_dev->data->port_id;
+
+ return 0;
+}
+
+int
+ionic_lif_start(struct ionic_lif *lif)
+{
+ uint32_t rx_mode = 0;
+
+ IONIC_PRINT(DEBUG, "Setting RX mode on port %u",
+ lif->port_id);
+
+ rx_mode |= IONIC_RX_MODE_F_UNICAST;
+ rx_mode |= IONIC_RX_MODE_F_MULTICAST;
+ rx_mode |= IONIC_RX_MODE_F_BROADCAST;
+
+ lif->rx_mode = 0; /* set by ionic_set_rx_mode */
+
+ ionic_set_rx_mode(lif, rx_mode);
+
+ ionic_link_status_check(lif);
+
+ /* Carrier ON here */
+
+ return 0;
+}
+
int
ionic_lif_identify(struct ionic_adapter *adapter)
{
diff --git a/drivers/net/ionic/ionic_lif.h b/drivers/net/ionic/ionic_lif.h
index 78cf92db8..9dbc54e27 100644
--- a/drivers/net/ionic/ionic_lif.h
+++ b/drivers/net/ionic/ionic_lif.h
@@ -44,6 +44,7 @@ struct ionic_lif {
struct ionic_adapter *adapter;
struct rte_eth_dev *eth_dev;
uint16_t port_id; /**< Device port identifier */
+ uint16_t mtu;
uint32_t index;
uint32_t hw_index;
uint32_t state;
@@ -54,7 +55,11 @@ struct ionic_lif {
struct ionic_qcq *notifyqcq;
struct ionic_doorbell __iomem *kern_dbpage;
uint64_t last_eid;
+ uint64_t features;
+ uint32_t hw_features;
+ uint32_t rx_mode;
char name[IONIC_LIF_NAME_MAX_SZ];
+ uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
uint32_t info_sz;
struct ionic_lif_info *info;
rte_iova_t info_pa;
@@ -71,6 +76,7 @@ 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);
@@ -83,11 +89,15 @@ bool ionic_adminq_service(struct ionic_cq *cq, uint32_t cq_desc_index,
int ionic_qcq_service(struct ionic_qcq *qcq, int budget, ionic_cq_cb cb,
void *cb_arg);
+int ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu);
+
void ionic_qcq_free(struct ionic_qcq *qcq);
int ionic_qcq_enable(struct ionic_qcq *qcq);
int ionic_qcq_disable(struct ionic_qcq *qcq);
+int ionic_lif_set_features(struct ionic_lif *lif);
+
int ionic_notifyq_handler(struct ionic_lif *lif, int budget);
#endif /* _IONIC_LIF_H_ */
--
2.17.1
next prev parent reply other threads:[~2020-01-19 15:56 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-19 15:53 [dpdk-dev] [PATCH v5 00/17] Introduces net/ionic PMD Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 01/17] net/ionic: add skeleton Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 02/17] net/ionic: add hardware structures definitions Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 03/17] net/ionic: add log Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 04/17] net/ionic: register and initialize the adapter Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 05/17] net/ionic: add port management commands Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 06/17] net/ionic: add basic lif support Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 07/17] net/ionic: add doorbells Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 08/17] net/ionic: add adminq support Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 09/17] net/ionic: add notifyq support Alfredo Cardigliano
2020-01-19 15:53 ` Alfredo Cardigliano [this message]
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 11/17] net/ionic: add Rx filters support Alfredo Cardigliano
2020-01-20 16:57 ` Ferruh Yigit
2020-01-21 7:43 ` Raslan Darawsheh
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 12/17] net/ionic: add Flow Control support Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 13/17] net/ionic: add Rx and Tx handling Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 14/17] net/ionic: add RSS support Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 15/17] net/ionic: add stats Alfredo Cardigliano
2020-01-20 12:10 ` Ferruh Yigit
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 16/17] net/ionic: add Tx checksum support Alfredo Cardigliano
2020-01-19 15:53 ` [dpdk-dev] [PATCH v5 17/17] net/ionic: read Fw version Alfredo Cardigliano
2020-01-20 13:05 ` [dpdk-dev] [PATCH v5 00/17] Introduces net/ionic PMD Ferruh Yigit
2020-01-20 13:38 ` Thomas Monjalon
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=20200119155356.20403-11-cardigliano@ntop.org \
--to=cardigliano@ntop.org \
--cc=dev@dpdk.org \
--cc=john.mcnamara@intel.com \
--cc=marko.kovacevic@intel.com \
/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).