All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alfredo Cardigliano <cardigliano@ntop.org>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 10/17] net/ionic: add basic port operations
Date: Sat, 12 Oct 2019 02:27:17 +0200	[thread overview]
Message-ID: <157084003725.11524.17090681919991122444.stgit@devele> (raw)
In-Reply-To: <157083994018.11524.11276616720287263690.stgit@devele>

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   |  315 ++++++++++++++++++++++++++++++++++++
 drivers/net/ionic/ionic_lif.c      |  268 +++++++++++++++++++++++++++++++
 drivers/net/ionic/ionic_lif.h      |    9 +
 drivers/net/ionic/ionic_osdep.h    |    2 
 7 files changed, 602 insertions(+)

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 53836be64..05f1df061 100644
--- a/drivers/net/ionic/ionic.h
+++ b/drivers/net/ionic/ionic.h
@@ -54,6 +54,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 ada07edff..02fcfdee8 100644
--- a/drivers/net/ionic/ionic_dev.h
+++ b/drivers/net/ionic/ionic_dev.h
@@ -20,6 +20,9 @@
  */
 #define IONIC_API_VERSION		"3"
 
+#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 6e435fe89..fed332750 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_init;
 int ionic_logtype_driver;
@@ -30,6 +41,15 @@ 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,
 };
 
 /*
@@ -40,6 +60,104 @@ 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;
 
+/*
+ * 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_init_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_init_print(WARNING, "Failed to bring port UP\n");
+		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_init_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_init_print(WARNING, "Failed to bring port DOWN\n");
+		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_init_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.
@@ -64,6 +182,183 @@ 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);
+	/*
+	 * Size = MTU + Ethernet header + VLAN + QinQ
+	 * Also add ETHER_CRC_LEN if the adapter is able to keep CRC
+	 */
+	uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + 4 + 4;
+	int err;
+
+	ionic_init_print_call();
+
+	/* Check that mtu is within the allowed range */
+	if (mtu < IONIC_MIN_MTU || mtu > IONIC_MAX_MTU)
+		return -EINVAL;
+
+	err = ionic_lif_change_mtu(lif, mtu);
+
+	if (err)
+		return err;
+
+	/* Update max frame size */
+	eth_dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+
+	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_init_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->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_init_print_call();
+
+	err = ionic_lif_configure(lif);
+
+	if (err) {
+		ionic_drv_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 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_init_print_call();
+
+	err = ionic_lif_start(lif);
+
+	if (err) {
+		ionic_drv_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(eth_dev->data->dev_conf.link_speeds);
+
+		if (speed)
+			ionic_dev_cmd_port_speed(idev, speed);
+	}
+
+	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 (eth_dev->data->dev_conf.link_speeds & ~allowed_speeds) {
+		ionic_init_print(ERR, "Invalid link setting");
+		return -EINVAL;
+	}
+
+	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_init_print_call();
+
+	err = ionic_lif_stop(lif);
+
+	if (err) {
+		ionic_drv_print(ERR, "Cannot stop LIF: %d", err);
+		return;
+	}
+}
+
+/*
+ * 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_init_print_call();
+
+	err = ionic_lif_stop(lif);
+
+	if (err) {
+		ionic_drv_print(ERR, "Cannot stop LIF: %d", err);
+		return;
+	}
+}
+
 static int
 eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
 {
@@ -87,6 +382,20 @@ eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
 	lif->adapter = adapter;
 	adapter->lifs[adapter->nlifs] = lif;
 
+	ionic_init_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_init_print(ERR, "Failed to allocate %u bytes needed to "
+				"store MAC addresses",
+				RTE_ETHER_ADDR_LEN * adapter->max_mac_addrs);
+		return -ENOMEM;
+	}
+
 	err = ionic_lif_alloc(lif);
 
 	if (err) {
@@ -102,6 +411,10 @@ eth_ionic_dev_init(struct rte_eth_dev *eth_dev, void *init_params)
 		return err;
 	}
 
+	/* Copy the MAC address */
+	rte_ether_addr_copy((struct rte_ether_addr *)lif->mac_addr,
+			&eth_dev->data->mac_addrs[0]);
+
 	ionic_init_print(DEBUG, "Port %u initialized", eth_dev->data->port_id);
 
 	return 0;
@@ -297,6 +610,8 @@ eth_ionic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 		return err;
 	}
 
+	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 491db56d4..b6b730cef 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)
+{
+	/* Carrier OFF here */
+
+	return 0;
+}
+
+void
+ionic_lif_reset(struct ionic_lif *lif)
+{
+	struct ionic_dev *idev = &lif->adapter->idev;
+
+	ionic_drv_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, const uint8_t *addr)
+{
+	ionic_init_print(INFO, "%s: stubbed\n", __func__);
+
+	return 0;
+}
+
+static int
+ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr)
+{
+	ionic_init_print(INFO, "%s: stubbed\n", __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_init_print(DEBUG, "rx_mode IONIC_RX_MODE_F_UNICAST");
+	if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
+		ionic_init_print(DEBUG, "rx_mode IONIC_RX_MODE_F_MULTICAST");
+	if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
+		ionic_init_print(DEBUG, "rx_mode IONIC_RX_MODE_F_BROADCAST");
+	if (rx_mode & IONIC_RX_MODE_F_PROMISC)
+		ionic_init_print(DEBUG, "rx_mode IONIC_RX_MODE_F_PROMISC");
+	if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
+		ionic_init_print(DEBUG, "rx_mode IONIC_RX_MODE_F_ALLMULTI");
+
+	err = ionic_adminq_post_wait(lif, &ctx);
+
+	if (err)
+		ionic_init_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)
 {
@@ -595,6 +697,124 @@ 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_init_print(DEBUG, "feature IONIC_ETH_HW_VLAN_TX_TAG");
+	if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_STRIP)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_STRIP");
+	if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_FILTER)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_FILTER");
+	if (lif->hw_features & IONIC_ETH_HW_RX_HASH)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_RX_HASH");
+	if (lif->hw_features & IONIC_ETH_HW_TX_SG)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TX_SG");
+	if (lif->hw_features & IONIC_ETH_HW_RX_SG)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_RX_SG");
+	if (lif->hw_features & IONIC_ETH_HW_TX_CSUM)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TX_CSUM");
+	if (lif->hw_features & IONIC_ETH_HW_RX_CSUM)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_RX_CSUM");
+	if (lif->hw_features & IONIC_ETH_HW_TSO)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_IPV6)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO_IPV6");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_ECN)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO_ECN");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_GRE)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO_GRE");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_GRE_CSUM)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO_GRE_CSUM");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP4)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP4");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP6)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP6");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_UDP)
+		ionic_init_print(DEBUG, "feature IONIC_ETH_HW_TSO_UDP");
+	if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
+		ionic_init_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_init_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_init_print(INFO, "deleting station MAC addr");
+
+		ionic_lif_addr_del(lif, lif->mac_addr);
+	}
+
+	memcpy(lif->mac_addr, ctx.comp.lif_getattr.mac, ETH_ALEN);
+
+	if (rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
+		ionic_init_print(NOTICE, "empty MAC addr (VF?)");
+		return 0;
+	}
+
+	ionic_init_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)
 {
@@ -620,10 +840,27 @@ 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);
 
@@ -642,6 +879,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_init_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 326cb17d5..f7c51c9ec 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[ETH_ALEN];
 	uint32_t info_sz;
 	struct ionic_lif_info *info;
 	rte_iova_t info_pa;
@@ -84,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_ */
diff --git a/drivers/net/ionic/ionic_osdep.h b/drivers/net/ionic/ionic_osdep.h
index 5b8baa67b..39a9cefa9 100644
--- a/drivers/net/ionic/ionic_osdep.h
+++ b/drivers/net/ionic/ionic_osdep.h
@@ -28,6 +28,8 @@
 #define BIT_ULL(nr)        (1ULL << (nr))
 #define BITS_TO_LONGS(nr)  div_round_up(nr, 8 * sizeof(long))
 
+#define ETH_ALEN        6
+
 #ifndef PAGE_SHIFT
 #define PAGE_SHIFT      12
 #define PAGE_SIZE       (1 << PAGE_SHIFT)


  parent reply	other threads:[~2019-10-12  0:28 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 ` [dpdk-dev] [PATCH 06/17] net/ionic: add basic lif support Alfredo Cardigliano
2019-10-12 15:26   ` 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 ` Alfredo Cardigliano [this message]
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=157084003725.11524.17090681919991122444.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.