[v2,16/18] bus/dpaa: add ONIC port mode for the DPAA eth

Message ID 20240823073240.3708320-17-hemant.agrawal@nxp.com (mailing list archive)
State Changes Requested
Delegated to: Ferruh Yigit
Headers
Series NXP DPAA ETH driver enhancement and fixes |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Hemant Agrawal Aug. 23, 2024, 7:32 a.m. UTC
From: Rohit Raj <rohit.raj@nxp.com>

The OH ports can also be used by two application, processing contexts
to communicate to each other.
This patch enables this mode for dpaa-eth OH port as ONIC port,
so that application can use the dpaa-eth to communicate to each
other on the same SoC.

Again,this properties is driven by the system device-tree variables.

Signed-off-by: Rohit Raj <rohit.raj@nxp.com>
---
 doc/guides/nics/dpaa.rst                  |  33 ++-
 drivers/bus/dpaa/base/fman/fman.c         | 299 +++++++++++++++++++++-
 drivers/bus/dpaa/base/fman/fman_hw.c      |  20 +-
 drivers/bus/dpaa/base/fman/netcfg_layer.c |   4 +-
 drivers/bus/dpaa/dpaa_bus.c               |  10 +-
 drivers/bus/dpaa/include/fman.h           |  15 +-
 drivers/net/dpaa/dpaa_ethdev.c            | 114 +++++++--
 drivers/net/dpaa/dpaa_flow.c              |  28 +-
 drivers/net/dpaa/dpaa_fmc.c               |   3 +-
 9 files changed, 467 insertions(+), 59 deletions(-)
  

Patch

diff --git a/doc/guides/nics/dpaa.rst b/doc/guides/nics/dpaa.rst
index 47dcce334c..529d5b74f4 100644
--- a/doc/guides/nics/dpaa.rst
+++ b/doc/guides/nics/dpaa.rst
@@ -136,7 +136,7 @@  RTE framework and DPAA internal components/drivers.
   The Ethernet driver is bound to a FMAN port and implements the interfaces
   needed to connect the DPAA network interface to the network stack.
   Each FMAN Port corresponds to a DPDK network interface.
-- PMD also support OH mode, where the port works as a HW assisted
+- PMD also support OH/ONIC mode, where the port works as a HW assisted
   virtual port without actually connecting to a Physical MAC.
 
 
@@ -152,7 +152,7 @@  Features
   - Promiscuous mode
   - IEEE1588 PTP
   - OH Port for inter application communication
-
+  - ONIC virtual port support
 
 DPAA Mempool Driver
 ~~~~~~~~~~~~~~~~~~~
@@ -350,6 +350,35 @@  OH Port
 		--------      Rx Packets      ---------
 
 
+ONIC
+~~~~
+   To use OH port to communicate between two applications, we can assign Rx port
+   of an O/H port to Application 1 and Tx port to Application 2 so that
+   Application 1 can send packets to Application 2. Similarly, we can assign Tx
+   port of another O/H port to Application 1 and Rx port to Application 2 so that
+   Applicaiton 2 can send packets to Application 1.
+
+   ONIC is logically defined to achieve it. Internally it will use one Rx queue
+   of an O/H port and one Tx queue of another O/H port.
+   For application, it will behave as single O/H port.
+
+   +------+         +------+        +------+        +------+        +------+
+   |      |   Tx    |      |   Rx   | O/H  |   Tx   |      |   Rx   |      |
+   |      | - - - > |      | -  - > | Port | -  - > |      | -  - > |      |
+   |      |         |      |        |  1   |        |      |        |      |
+   |      |         |      |        +------+        |      |        |      |
+   | App  |         | ONIC |                        | ONIC |        | App  |
+   |  1   |         | Port |                        | Port |        |  2   |
+   |      |         |  1   |        +------+        |  2   |        |      |
+   |      |   Rx    |      |   Tx   | O/H  |   Rx   |      |   Tx   |      |
+   |      | < - - - |      | < - - -| Port | < - - -|      | < - - -|      |
+   |      |         |      |        |  2   |        |      |        |      |
+   +------+         +------+        +------+        +------+        +------+
+
+   All the packets received by ONIC port 1 will be send to ONIC port 2 and vice
+   versa. These ports can be used by DPDK applications just like physical ports.
+
+
 VSP (Virtual Storage Profile)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The storage profiled are means to provide virtualized interface. A ranges of
diff --git a/drivers/bus/dpaa/base/fman/fman.c b/drivers/bus/dpaa/base/fman/fman.c
index f817305ab7..efe6eab4a9 100644
--- a/drivers/bus/dpaa/base/fman/fman.c
+++ b/drivers/bus/dpaa/base/fman/fman.c
@@ -43,7 +43,7 @@  if_destructor(struct __fman_if *__if)
 	if (!__if)
 		return;
 
-	if (__if->__if.mac_type == fman_offline)
+	if (__if->__if.mac_type == fman_offline_internal)
 		goto cleanup;
 
 	list_for_each_entry_safe(bp, tmpbp, &__if->__if.bpool_list, node) {
@@ -465,7 +465,7 @@  fman_if_init(const struct device_node *dpa_node)
 	__if->__if.is_memac = 0;
 
 	if (is_offline)
-		__if->__if.mac_type = fman_offline;
+		__if->__if.mac_type = fman_offline_internal;
 	else if (of_device_is_compatible(mac_node, "fsl,fman-1g-mac"))
 		__if->__if.mac_type = fman_mac_1g;
 	else if (of_device_is_compatible(mac_node, "fsl,fman-10g-mac"))
@@ -791,6 +791,292 @@  fman_if_init(const struct device_node *dpa_node)
 		    dname, __if->__if.tx_channel_id, __if->__if.fman_idx,
 		    __if->__if.mac_idx);
 
+	/* Don't add OH port to the port list since they will be used by ONIC
+	 * ports.
+	 */
+	if (!is_offline)
+		list_add_tail(&__if->__if.node, &__ifs);
+
+	return 0;
+err:
+	if_destructor(__if);
+	return _errno;
+}
+
+static int fman_if_init_onic(const struct device_node *dpa_node)
+{
+	struct __fman_if *__if;
+	struct fman_if_bpool *bpool;
+	const phandle *tx_pools_phandle;
+	const phandle *tx_channel_id, *mac_addr, *cell_idx;
+	const phandle *rx_phandle;
+	const struct device_node *pool_node;
+	size_t lenp;
+	int _errno;
+	const phandle *p_onic_oh_nodes = NULL;
+	const struct device_node *rx_oh_node = NULL;
+	const struct device_node *tx_oh_node = NULL;
+	const phandle *p_fman_rx_oh_node = NULL, *p_fman_tx_oh_node = NULL;
+	const struct device_node *fman_rx_oh_node = NULL;
+	const struct device_node *fman_tx_oh_node = NULL;
+	const struct device_node *fman_node;
+	uint32_t na = OF_DEFAULT_NA;
+	uint64_t rx_phandle_host[4] = {0};
+	uint64_t cell_idx_host = 0;
+
+	if (of_device_is_available(dpa_node) == false)
+		return 0;
+
+	if (!of_device_is_compatible(dpa_node, "fsl,dpa-ethernet-generic"))
+		return 0;
+
+	/* Allocate an object for this network interface */
+	__if = rte_malloc(NULL, sizeof(*__if), RTE_CACHE_LINE_SIZE);
+	if (!__if) {
+		FMAN_ERR(-ENOMEM, "malloc(%zu)\n", sizeof(*__if));
+		goto err;
+	}
+	memset(__if, 0, sizeof(*__if));
+
+	INIT_LIST_HEAD(&__if->__if.bpool_list);
+
+	strlcpy(__if->node_name, dpa_node->name, IF_NAME_MAX_LEN - 1);
+	__if->node_name[IF_NAME_MAX_LEN - 1] = '\0';
+
+	strlcpy(__if->node_path, dpa_node->full_name, PATH_MAX - 1);
+	__if->node_path[PATH_MAX - 1] = '\0';
+
+	/* Mac node is onic */
+	__if->__if.is_memac = 0;
+	__if->__if.mac_type = fman_onic;
+
+	/* Extract the MAC address for linux peer */
+	mac_addr = of_get_property(dpa_node, "local-mac-address", &lenp);
+	if (!mac_addr) {
+		FMAN_ERR(-EINVAL, "%s: no local-mac-address\n",
+			 dpa_node->full_name);
+		goto err;
+	}
+
+	memcpy(&__if->__if.onic_info.peer_mac, mac_addr, ETHER_ADDR_LEN);
+
+	/* Extract the Rx port (it's the first of the two port handles)
+	 * and get its channel ID.
+	 */
+	p_onic_oh_nodes = of_get_property(dpa_node, "fsl,oh-ports", &lenp);
+	if (!p_onic_oh_nodes) {
+		FMAN_ERR(-EINVAL, "%s: couldn't get p_onic_oh_nodes\n",
+			 dpa_node->full_name);
+		goto err;
+	}
+
+	rx_oh_node = of_find_node_by_phandle(p_onic_oh_nodes[0]);
+	if (!rx_oh_node) {
+		FMAN_ERR(-EINVAL, "%s: couldn't get rx_oh_node\n",
+			 dpa_node->full_name);
+		goto err;
+	}
+
+	p_fman_rx_oh_node = of_get_property(rx_oh_node, "fsl,fman-oh-port",
+					    &lenp);
+	if (!p_fman_rx_oh_node) {
+		FMAN_ERR(-EINVAL, "%s: couldn't get p_fman_rx_oh_node\n",
+			 rx_oh_node->full_name);
+		goto err;
+	}
+
+	fman_rx_oh_node = of_find_node_by_phandle(*p_fman_rx_oh_node);
+	if (!fman_rx_oh_node) {
+		FMAN_ERR(-EINVAL, "%s: couldn't get fman_rx_oh_node\n",
+			 rx_oh_node->full_name);
+		goto err;
+	}
+
+	tx_channel_id = of_get_property(fman_rx_oh_node, "fsl,qman-channel-id",
+					&lenp);
+	if (!tx_channel_id) {
+		FMAN_ERR(-EINVAL, "%s: no fsl-qman-channel-id\n",
+			 rx_oh_node->full_name);
+		goto err;
+	}
+	assert(lenp == sizeof(*tx_channel_id));
+
+	__if->__if.tx_channel_id = of_read_number(tx_channel_id, na);
+
+	/* Extract the FQs from which oNIC driver in Linux is dequeuing */
+	rx_phandle = of_get_property(rx_oh_node, "fsl,qman-frame-queues-oh",
+				     &lenp);
+	if (!rx_phandle) {
+		FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-oh\n",
+			 rx_oh_node->full_name);
+		goto err;
+	}
+	assert(lenp == (4 * sizeof(phandle)));
+
+	__if->__if.onic_info.rx_start = of_read_number(&rx_phandle[2], na);
+	__if->__if.onic_info.rx_count = of_read_number(&rx_phandle[3], na);
+
+	/* Extract the Rx FQIDs */
+	tx_oh_node = of_find_node_by_phandle(p_onic_oh_nodes[1]);
+	if (!tx_oh_node) {
+		FMAN_ERR(-EINVAL, "%s: couldn't get tx_oh_node\n",
+			 dpa_node->full_name);
+		goto err;
+	}
+
+	p_fman_tx_oh_node = of_get_property(tx_oh_node, "fsl,fman-oh-port",
+					    &lenp);
+	if (!p_fman_tx_oh_node) {
+		FMAN_ERR(-EINVAL, "%s: couldn't get p_fman_tx_oh_node\n",
+			 tx_oh_node->full_name);
+		goto err;
+	}
+
+	fman_tx_oh_node = of_find_node_by_phandle(*p_fman_tx_oh_node);
+	if (!fman_tx_oh_node) {
+		FMAN_ERR(-EINVAL, "%s: couldn't get fman_tx_oh_node\n",
+			 tx_oh_node->full_name);
+		goto err;
+	}
+
+	cell_idx = of_get_property(fman_tx_oh_node, "cell-index", &lenp);
+	if (!cell_idx) {
+		FMAN_ERR(-ENXIO, "%s: no cell-index)\n", tx_oh_node->full_name);
+		goto err;
+	}
+	assert(lenp == sizeof(*cell_idx));
+
+	cell_idx_host = of_read_number(cell_idx, lenp / sizeof(phandle));
+	__if->__if.mac_idx = cell_idx_host;
+
+	fman_node = of_get_parent(fman_tx_oh_node);
+	cell_idx = of_get_property(fman_node, "cell-index", &lenp);
+	if (!cell_idx) {
+		FMAN_ERR(-ENXIO, "%s: no cell-index)\n", tx_oh_node->full_name);
+		goto err;
+	}
+	assert(lenp == sizeof(*cell_idx));
+
+	cell_idx_host = of_read_number(cell_idx, lenp / sizeof(phandle));
+	__if->__if.fman_idx = cell_idx_host;
+
+	rx_phandle = of_get_property(tx_oh_node, "fsl,qman-frame-queues-oh",
+				     &lenp);
+	if (!rx_phandle) {
+		FMAN_ERR(-EINVAL, "%s: no fsl,qman-frame-queues-oh\n",
+			 dpa_node->full_name);
+		goto err;
+	}
+	assert(lenp == (4 * sizeof(phandle)));
+
+	rx_phandle_host[0] = of_read_number(&rx_phandle[0], na);
+	rx_phandle_host[1] = of_read_number(&rx_phandle[1], na);
+	rx_phandle_host[2] = of_read_number(&rx_phandle[2], na);
+	rx_phandle_host[3] = of_read_number(&rx_phandle[3], na);
+
+	assert((rx_phandle_host[1] == 1) && (rx_phandle_host[3] == 1));
+
+	__if->__if.fqid_rx_err = rx_phandle_host[0];
+	__if->__if.fqid_rx_def = rx_phandle_host[2];
+
+	/* Don't Extract the Tx FQIDs */
+	__if->__if.fqid_tx_err = 0;
+	__if->__if.fqid_tx_confirm = 0;
+
+	/* Obtain the buffer pool nodes used by Tx OH port */
+	tx_pools_phandle = of_get_property(tx_oh_node, "fsl,bman-buffer-pools",
+			&lenp);
+	if (!tx_pools_phandle) {
+		FMAN_ERR(-EINVAL, "%s: no fsl,bman-buffer-pools\n",
+			 tx_oh_node->full_name);
+		goto err;
+	}
+	assert(lenp && !(lenp % sizeof(phandle)));
+
+	/* For each pool, parse the corresponding node and add a pool object to
+	 * the interface's "bpool_list".
+	 */
+
+	while (lenp) {
+		size_t proplen;
+		const phandle *prop;
+		uint64_t bpool_host[6] = {0};
+
+		/* Allocate an object for the pool */
+		bpool = rte_malloc(NULL, sizeof(*bpool), RTE_CACHE_LINE_SIZE);
+		if (!bpool) {
+			FMAN_ERR(-ENOMEM, "malloc(%zu)\n", sizeof(*bpool));
+			goto err;
+		}
+
+		/* Find the pool node */
+		pool_node = of_find_node_by_phandle(*tx_pools_phandle);
+		if (!pool_node) {
+			FMAN_ERR(-ENXIO, "%s: bad fsl,bman-buffer-pools\n",
+				 tx_oh_node->full_name);
+			rte_free(bpool);
+			goto err;
+		}
+
+		/* Extract the BPID property */
+		prop = of_get_property(pool_node, "fsl,bpid", &proplen);
+		if (!prop) {
+			FMAN_ERR(-EINVAL, "%s: no fsl,bpid\n",
+				 pool_node->full_name);
+			rte_free(bpool);
+			goto err;
+		}
+		assert(proplen == sizeof(*prop));
+
+		bpool->bpid = of_read_number(prop, na);
+
+		/* Extract the cfg property (count/size/addr). "fsl,bpool-cfg"
+		 * indicates for the Bman driver to seed the pool.
+		 * "fsl,bpool-ethernet-cfg" is used by the network driver. The
+		 * two are mutually exclusive, so check for either of them.
+		 */
+
+		prop = of_get_property(pool_node, "fsl,bpool-cfg", &proplen);
+		if (!prop)
+			prop = of_get_property(pool_node,
+					       "fsl,bpool-ethernet-cfg",
+					       &proplen);
+		if (!prop) {
+			/* It's OK for there to be no bpool-cfg */
+			bpool->count = bpool->size = bpool->addr = 0;
+		} else {
+			assert(proplen == (6 * sizeof(*prop)));
+
+			bpool_host[0] = of_read_number(&prop[0], na);
+			bpool_host[1] = of_read_number(&prop[1], na);
+			bpool_host[2] = of_read_number(&prop[2], na);
+			bpool_host[3] = of_read_number(&prop[3], na);
+			bpool_host[4] = of_read_number(&prop[4], na);
+			bpool_host[5] = of_read_number(&prop[5], na);
+
+			bpool->count = ((uint64_t)bpool_host[0] << 32) |
+				       bpool_host[1];
+			bpool->size = ((uint64_t)bpool_host[2] << 32) |
+				      bpool_host[3];
+			bpool->addr = ((uint64_t)bpool_host[4] << 32) |
+				      bpool_host[5];
+		}
+
+		/* Parsing of the pool is complete, add it to the interface
+		 * list.
+		 */
+		list_add_tail(&bpool->node, &__if->__if.bpool_list);
+		lenp -= sizeof(phandle);
+		tx_pools_phandle++;
+	}
+
+	fman_if_vsp_init(__if);
+
+	/* Parsing of the network interface is complete, add it to the list. */
+	DPAA_BUS_DEBUG("Found %s, Tx Channel = %x, FMAN = %x, Port ID = %x",
+		       dpa_node->full_name, __if->__if.tx_channel_id,
+		       __if->__if.fman_idx, __if->__if.mac_idx);
+
 	list_add_tail(&__if->__if.node, &__ifs);
 	return 0;
 err:
@@ -830,6 +1116,13 @@  fman_init(void)
 		}
 	}
 
+	for_each_compatible_node(dpa_node, NULL, "fsl,dpa-ethernet-generic") {
+		/* it is a oNIC interface */
+		_errno = fman_if_init_onic(dpa_node);
+		if (_errno)
+			FMAN_ERR(_errno, "if_init(%s)\n", dpa_node->full_name);
+	}
+
 	return 0;
 err:
 	fman_finish();
@@ -847,7 +1140,7 @@  fman_finish(void)
 		int _errno;
 
 		/* No need to disable Offline port */
-		if (__if->__if.mac_type == fman_offline)
+		if (__if->__if.mac_type == fman_offline_internal)
 			continue;
 
 		/* disable Rx and Tx */
diff --git a/drivers/bus/dpaa/base/fman/fman_hw.c b/drivers/bus/dpaa/base/fman/fman_hw.c
index 1f61ae406b..cbb0491d70 100644
--- a/drivers/bus/dpaa/base/fman/fman_hw.c
+++ b/drivers/bus/dpaa/base/fman/fman_hw.c
@@ -88,8 +88,9 @@  fman_if_add_hash_mac_addr(struct fman_if *p, uint8_t *eth)
 
 	struct __fman_if *__if = container_of(p, struct __fman_if, __if);
 
-	/* Add hash mac addr not supported on Offline port */
-	if (__if->__if.mac_type == fman_offline)
+	/* Add hash mac addr not supported on Offline port and onic port */
+	if (__if->__if.mac_type == fman_offline_internal ||
+	    __if->__if.mac_type == fman_onic)
 		return 0;
 
 	eth_addr = ETH_ADDR_TO_UINT64(eth);
@@ -115,9 +116,10 @@  fman_if_get_primary_mac_addr(struct fman_if *p, uint8_t *eth)
 	u32 val = in_be32(mac_reg);
 	int i;
 
-	/* Get mac addr not supported on Offline port */
+	/* Get mac addr not supported on Offline port and onic port */
 	/* Return NULL mac address */
-	if (__if->__if.mac_type == fman_offline) {
+	if (__if->__if.mac_type == fman_offline_internal ||
+	    __if->__if.mac_type == fman_onic) {
 		for (i = 0; i < 6; i++)
 			eth[i] = 0x0;
 		return 0;
@@ -143,8 +145,9 @@  fman_if_clear_mac_addr(struct fman_if *p, uint8_t addr_num)
 	struct __fman_if *m = container_of(p, struct __fman_if, __if);
 	void *reg;
 
-	/* Clear mac addr not supported on Offline port */
-	if (m->__if.mac_type == fman_offline)
+	/* Clear mac addr not supported on Offline port and onic port */
+	if (m->__if.mac_type == fman_offline_internal ||
+	    m->__if.mac_type == fman_onic)
 		return;
 
 	if (addr_num) {
@@ -169,8 +172,9 @@  fman_if_add_mac_addr(struct fman_if *p, uint8_t *eth, uint8_t addr_num)
 	void *reg;
 	u32 val;
 
-	/* Set mac addr not supported on Offline port */
-	if (m->__if.mac_type == fman_offline)
+	/* Set mac addr not supported on Offline port and onic port */
+	if (m->__if.mac_type == fman_offline_internal ||
+	    m->__if.mac_type == fman_onic)
 		return 0;
 
 	memcpy(&m->__if.mac_addr, eth, ETHER_ADDR_LEN);
diff --git a/drivers/bus/dpaa/base/fman/netcfg_layer.c b/drivers/bus/dpaa/base/fman/netcfg_layer.c
index e6a6ed1eb6..ffb37825c2 100644
--- a/drivers/bus/dpaa/base/fman/netcfg_layer.c
+++ b/drivers/bus/dpaa/base/fman/netcfg_layer.c
@@ -44,7 +44,7 @@  dump_netcfg(struct netcfg_info *cfg_ptr, FILE *f)
 
 		fprintf(f, "\n+ Fman %d, MAC %d (%s);\n",
 		       __if->fman_idx, __if->mac_idx,
-		       (__if->mac_type == fman_offline) ? "OFFLINE" :
+		       (__if->mac_type == fman_offline_internal) ? "OFFLINE" :
 		       (__if->mac_type == fman_mac_1g) ? "1G" :
 		       (__if->mac_type == fman_mac_2_5g) ? "2.5G" : "10G");
 
@@ -57,7 +57,7 @@  dump_netcfg(struct netcfg_info *cfg_ptr, FILE *f)
 		fprintf(f, "\tfqid_rx_def: 0x%x\n", p_cfg->rx_def);
 		fprintf(f, "\tfqid_rx_err: 0x%x\n", __if->fqid_rx_err);
 
-		if (__if->mac_type != fman_offline) {
+		if (__if->mac_type != fman_offline_internal) {
 			fprintf(f, "\tfqid_tx_err: 0x%x\n", __if->fqid_tx_err);
 			fprintf(f, "\tfqid_tx_confirm: 0x%x\n", __if->fqid_tx_confirm);
 			fman_if_for_each_bpool(bpool, __if)
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 6e4ec90670..a6c89c4514 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -204,9 +204,12 @@  dpaa_create_device_list(void)
 
 		/* Create device name */
 		memset(dev->name, 0, RTE_ETH_NAME_MAX_LEN);
-		if (fman_intf->mac_type == fman_offline)
+		if (fman_intf->mac_type == fman_offline_internal)
 			sprintf(dev->name, "fm%d-oh%d",
 				(fman_intf->fman_idx + 1), fman_intf->mac_idx);
+		else if (fman_intf->mac_type == fman_onic)
+			sprintf(dev->name, "fm%d-onic%d",
+				(fman_intf->fman_idx + 1), fman_intf->mac_idx);
 		else
 			sprintf(dev->name, "fm%d-mac%d",
 				(fman_intf->fman_idx + 1), fman_intf->mac_idx);
@@ -477,6 +480,11 @@  rte_dpaa_bus_parse(const char *name, void *out)
 				i >= 2 || j >= 16)
 			return -EINVAL;
 		max_name_len = sizeof("fm.-oh..") - 1;
+	} else if (strncmp("onic", &name[dev_delta], 4) == 0) {
+		if (sscanf(&name[delta], "fm%u-onic%u", &i, &j) != 2 ||
+				i >= 2 || j >= 16)
+			return -EINVAL;
+		max_name_len = sizeof("fm.-onic..") - 1;
 	} else {
 		if (sscanf(&name[delta], "fm%u-mac%u", &i, &j) != 2 ||
 				i >= 2 || j >= 16)
diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h
index 377f73bf0d..01556cf2a8 100644
--- a/drivers/bus/dpaa/include/fman.h
+++ b/drivers/bus/dpaa/include/fman.h
@@ -78,7 +78,7 @@  TAILQ_HEAD(rte_fman_if_list, __fman_if);
 
 /* Represents the different flavour of network interface */
 enum fman_mac_type {
-	fman_offline = 0,
+	fman_offline_internal = 0,
 	fman_mac_1g,
 	fman_mac_10g,
 	fman_mac_2_5g,
@@ -366,6 +366,16 @@  struct fman_port_qmi_regs {
 	uint32_t fmqm_pndcc;		/**< PortID n Dequeue Confirm Counter */
 };
 
+struct onic_port_cfg {
+	char macless_name[IF_NAME_MAX_LEN];
+	uint32_t rx_start;
+	uint32_t rx_count;
+	uint32_t tx_start;
+	uint32_t tx_count;
+	struct rte_ether_addr src_mac;
+	struct rte_ether_addr peer_mac;
+};
+
 /* This struct exports parameters about an Fman network interface, determined
  * from the device-tree.
  */
@@ -401,6 +411,9 @@  struct fman_if {
 	uint32_t fqid_tx_err;
 	uint32_t fqid_tx_confirm;
 
+	/* oNIC port info */
+	struct onic_port_cfg onic_info;
+
 	struct list_head bpool_list;
 	/* The node for linking this interface into "fman_if_list" */
 	struct list_head node;
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index f8196ddd14..133fbd5bc9 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -295,7 +295,8 @@  dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 		max_rx_pktlen = DPAA_MAX_RX_PKT_LEN;
 	}
 
-	if (fif->mac_type != fman_offline)
+	if (!fif->is_shared_mac && fif->mac_type != fman_offline_internal &&
+	    fif->mac_type != fman_onic)
 		fman_if_set_maxfrm(dev->process_private, max_rx_pktlen);
 
 	if (rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER) {
@@ -315,7 +316,8 @@  dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 	}
 
 	/* Disable interrupt support on offline port*/
-	if (fif->mac_type == fman_offline)
+	if (fif->mac_type == fman_offline_internal ||
+	    fif->mac_type == fman_onic)
 		return 0;
 
 	/* if the interrupts were configured on this devices*/
@@ -467,10 +469,11 @@  static int dpaa_eth_dev_start(struct rte_eth_dev *dev)
 	else
 		dev->tx_pkt_burst = dpaa_eth_queue_tx;
 
-	fman_if_bmi_stats_enable(fif);
-	fman_if_bmi_stats_reset(fif);
-	fman_if_enable_rx(fif);
-
+	if (fif->mac_type != fman_onic) {
+		fman_if_bmi_stats_enable(fif);
+		fman_if_bmi_stats_reset(fif);
+		fman_if_enable_rx(fif);
+	}
 	for (i = 0; i < dev->data->nb_rx_queues; i++)
 		dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
 	for (i = 0; i < dev->data->nb_tx_queues; i++)
@@ -535,7 +538,8 @@  static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
 
 	ret = dpaa_eth_dev_stop(dev);
 
-	if (fif->mac_type == fman_offline)
+	if (fif->mac_type == fman_offline_internal ||
+	    fif->mac_type == fman_onic)
 		return 0;
 
 	/* Reset link to autoneg */
@@ -651,11 +655,14 @@  static int dpaa_eth_dev_info(struct rte_eth_dev *dev,
 					| RTE_ETH_LINK_SPEED_1G
 					| RTE_ETH_LINK_SPEED_2_5G
 					| RTE_ETH_LINK_SPEED_10G;
-	} else if (fif->mac_type == fman_offline) {
+	} else if (fif->mac_type == fman_offline_internal ||
+		   fif->mac_type == fman_onic) {
 		dev_info->speed_capa = RTE_ETH_LINK_SPEED_10M_HD
 					| RTE_ETH_LINK_SPEED_10M
 					| RTE_ETH_LINK_SPEED_100M_HD
-					| RTE_ETH_LINK_SPEED_100M;
+					| RTE_ETH_LINK_SPEED_100M
+					| RTE_ETH_LINK_SPEED_1G
+					| RTE_ETH_LINK_SPEED_2_5G;
 	} else {
 		DPAA_PMD_ERR("invalid link_speed: %s, %d",
 			     dpaa_intf->name, fif->mac_type);
@@ -757,7 +764,8 @@  static int dpaa_eth_link_update(struct rte_eth_dev *dev,
 	ioctl_version = dpaa_get_ioctl_version_number();
 
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC &&
-	    fif->mac_type != fman_offline) {
+	    fif->mac_type != fman_offline_internal &&
+	    fif->mac_type != fman_onic) {
 		for (count = 0; count <= MAX_REPEAT_TIME; count++) {
 			ret = dpaa_get_link_status(__fif->node_name, link);
 			if (ret)
@@ -770,7 +778,8 @@  static int dpaa_eth_link_update(struct rte_eth_dev *dev,
 		}
 	} else {
 		link->link_status = dpaa_intf->valid;
-		if (fif->mac_type == fman_offline) {
+		if (fif->mac_type == fman_offline_internal ||
+		    fif->mac_type == fman_onic) {
 			/*Max supported rate for O/H port is 3.75Mpps*/
 			link->link_speed = RTE_ETH_SPEED_NUM_2_5G;
 			link->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
@@ -933,8 +942,16 @@  dpaa_xstats_get_names_by_id(
 
 static int dpaa_eth_promiscuous_enable(struct rte_eth_dev *dev)
 {
+	struct fman_if *fif = dev->process_private;
+
 	PMD_INIT_FUNC_TRACE();
 
+	if (fif->mac_type == fman_onic) {
+		DPAA_PMD_INFO("Enable promiscuous mode not supported on ONIC "
+			      "port");
+		return 0;
+	}
+
 	fman_if_promiscuous_enable(dev->process_private);
 
 	return 0;
@@ -942,8 +959,16 @@  static int dpaa_eth_promiscuous_enable(struct rte_eth_dev *dev)
 
 static int dpaa_eth_promiscuous_disable(struct rte_eth_dev *dev)
 {
+	struct fman_if *fif = dev->process_private;
+
 	PMD_INIT_FUNC_TRACE();
 
+	if (fif->mac_type == fman_onic) {
+		DPAA_PMD_INFO("Disable promiscuous mode not supported on ONIC "
+			      "port");
+		return 0;
+	}
+
 	fman_if_promiscuous_disable(dev->process_private);
 
 	return 0;
@@ -951,8 +976,15 @@  static int dpaa_eth_promiscuous_disable(struct rte_eth_dev *dev)
 
 static int dpaa_eth_multicast_enable(struct rte_eth_dev *dev)
 {
+	struct fman_if *fif = dev->process_private;
+
 	PMD_INIT_FUNC_TRACE();
 
+	if (fif->mac_type == fman_onic) {
+		DPAA_PMD_INFO("Enable Multicast not supported on ONIC port");
+		return 0;
+	}
+
 	fman_if_set_mcast_filter_table(dev->process_private);
 
 	return 0;
@@ -960,8 +992,15 @@  static int dpaa_eth_multicast_enable(struct rte_eth_dev *dev)
 
 static int dpaa_eth_multicast_disable(struct rte_eth_dev *dev)
 {
+	struct fman_if *fif = dev->process_private;
+
 	PMD_INIT_FUNC_TRACE();
 
+	if (fif->mac_type == fman_onic) {
+		DPAA_PMD_INFO("Disable Multicast not supported on ONIC port");
+		return 0;
+	}
+
 	fman_if_reset_mcast_filter_table(dev->process_private);
 
 	return 0;
@@ -1095,7 +1134,8 @@  int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	dpaa_intf->bp_info = DPAA_MEMPOOL_TO_POOL_INFO(mp);
 
 	/* For shared interface, it's done in kernel, skip.*/
-	if (!fif->is_shared_mac && fif->mac_type != fman_offline)
+	if (!fif->is_shared_mac && fif->mac_type != fman_offline_internal &&
+	    fif->mac_type != fman_onic)
 		dpaa_fman_if_pool_setup(dev);
 
 	if (fif->num_profiles) {
@@ -1126,8 +1166,9 @@  int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	}
 
 	dpaa_intf->valid = 1;
-	DPAA_PMD_DEBUG("if:%s sg_on = %d, max_frm =%d", dpaa_intf->name,
-		fman_if_get_sg_enable(fif), max_rx_pktlen);
+	if (fif->mac_type != fman_onic)
+		DPAA_PMD_DEBUG("if:%s sg_on = %d, max_frm =%d", dpaa_intf->name,
+			       fman_if_get_sg_enable(fif), max_rx_pktlen);
 	/* checking if push mode only, no error check for now */
 	if (!rxq->is_static &&
 	    dpaa_push_mode_max_queue > dpaa_push_queue_idx) {
@@ -1242,7 +1283,8 @@  int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
 	}
 
 	/* Enable main queue to receive error packets also by default */
-	if (fif->mac_type != fman_offline)
+	if (fif->mac_type != fman_offline_internal &&
+	    fif->mac_type != fman_onic)
 		fman_if_set_err_fqid(fif, rxq->fqid);
 
 	return 0;
@@ -1394,7 +1436,8 @@  static int dpaa_link_down(struct rte_eth_dev *dev)
 	__fif = container_of(fif, struct __fman_if, __if);
 
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC &&
-	    fif->mac_type != fman_offline)
+	    fif->mac_type != fman_offline_internal &&
+	    fif->mac_type != fman_onic)
 		dpaa_update_link_status(__fif->node_name, RTE_ETH_LINK_DOWN);
 	else
 		return dpaa_eth_dev_stop(dev);
@@ -1411,7 +1454,8 @@  static int dpaa_link_up(struct rte_eth_dev *dev)
 	__fif = container_of(fif, struct __fman_if, __if);
 
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC &&
-	    fif->mac_type != fman_offline)
+	    fif->mac_type != fman_offline_internal &&
+	    fif->mac_type != fman_onic)
 		dpaa_update_link_status(__fif->node_name, RTE_ETH_LINK_UP);
 	else
 		dpaa_eth_dev_start(dev);
@@ -1510,11 +1554,16 @@  dpaa_dev_add_mac_addr(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (fif->mac_type == fman_offline) {
+	if (fif->mac_type == fman_offline_internal) {
 		DPAA_PMD_DEBUG("Add MAC Address not supported on O/H port");
 		return 0;
 	}
 
+	if (fif->mac_type == fman_onic) {
+		DPAA_PMD_INFO("Add MAC Address not supported on ONIC port");
+		return 0;
+	}
+
 	ret = fman_if_add_mac_addr(dev->process_private,
 				   addr->addr_bytes, index);
 
@@ -1531,11 +1580,16 @@  dpaa_dev_remove_mac_addr(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (fif->mac_type == fman_offline) {
+	if (fif->mac_type == fman_offline_internal) {
 		DPAA_PMD_DEBUG("Remove MAC Address not supported on O/H port");
 		return;
 	}
 
+	if (fif->mac_type == fman_onic) {
+		DPAA_PMD_INFO("Remove MAC Address not supported on ONIC port");
+		return;
+	}
+
 	fman_if_clear_mac_addr(dev->process_private, index);
 }
 
@@ -1548,11 +1602,16 @@  dpaa_dev_set_mac_addr(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if (fif->mac_type == fman_offline) {
+	if (fif->mac_type == fman_offline_internal) {
 		DPAA_PMD_DEBUG("Set MAC Address not supported on O/H port");
 		return 0;
 	}
 
+	if (fif->mac_type == fman_onic) {
+		DPAA_PMD_INFO("Set MAC Address not supported on ONIC port");
+		return 0;
+	}
+
 	ret = fman_if_add_mac_addr(dev->process_private, addr->addr_bytes, 0);
 	if (ret)
 		DPAA_PMD_ERR("Setting the MAC ADDR failed %d", ret);
@@ -1903,7 +1962,8 @@  static int dpaa_tx_queue_init(struct qman_fq *fq,
 		/* Set B0V bit in contextA to set ASPID to 0 */
 		opts.fqd.context_a.hi |= DPAA_FQD_CTX_A_B0_FIELD_VALID;
 
-	if (fman_intf->mac_type == fman_offline) {
+	if (fman_intf->mac_type == fman_offline_internal ||
+	    fman_intf->mac_type == fman_onic) {
 		opts.fqd.context_a.lo |= DPAA_FQD_CTX_A2_VSPE_BIT;
 		opts.fqd.context_b = fm_default_vsp_id(fman_intf) <<
 				     DPAA_FQD_CTX_B_SHIFT_BITS;
@@ -2156,6 +2216,11 @@  dpaa_dev_init(struct rte_eth_dev *eth_dev)
 			goto free_rx;
 		}
 		if (!num_rx_fqs) {
+			if (fman_intf->mac_type == fman_offline_internal ||
+			    fman_intf->mac_type == fman_onic) {
+				ret = -ENODEV;
+				goto free_rx;
+			}
 			DPAA_PMD_WARN("%s is not configured by FMC.",
 				dpaa_intf->name);
 		}
@@ -2323,7 +2388,8 @@  dpaa_dev_init(struct rte_eth_dev *eth_dev)
 	DPAA_PMD_DEBUG("All frame queues created");
 
 	/* Get the initial configuration for flow control */
-	if (fman_intf->mac_type != fman_offline)
+	if (fman_intf->mac_type != fman_offline_internal &&
+	    fman_intf->mac_type != fman_onic)
 		dpaa_fc_set_default(dpaa_intf, fman_intf);
 
 	/* reset bpool list, initialize bpool dynamically */
@@ -2355,7 +2421,9 @@  dpaa_dev_init(struct rte_eth_dev *eth_dev)
 	DPAA_PMD_INFO("net: dpaa: %s: " RTE_ETHER_ADDR_PRT_FMT,
 		      dpaa_device->name, RTE_ETHER_ADDR_BYTES(&fman_intf->mac_addr));
 
-	if (!fman_intf->is_shared_mac && fman_intf->mac_type != fman_offline) {
+	if (!fman_intf->is_shared_mac &&
+	    fman_intf->mac_type != fman_offline_internal &&
+	    fman_intf->mac_type != fman_onic) {
 		/* Configure error packet handling */
 		fman_if_receive_rx_errors(fman_intf,
 					  FM_FD_RX_STATUS_ERR_MASK);
diff --git a/drivers/net/dpaa/dpaa_flow.c b/drivers/net/dpaa/dpaa_flow.c
index b43c3b1b86..810b187405 100644
--- a/drivers/net/dpaa/dpaa_flow.c
+++ b/drivers/net/dpaa/dpaa_flow.c
@@ -646,11 +646,15 @@  static inline int set_pcd_netenv_scheme(struct dpaa_if *dpaa_intf,
 
 static inline int get_rx_port_type(struct fman_if *fif)
 {
+	/* For onic ports, configure the VSP as offline ports so that
+	 * kernel can configure correct port.
+	 */
+	if (fif->mac_type == fman_offline_internal ||
+	    fif->mac_type == fman_onic)
+		return e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
 	/* For 1G fm-mac9 and fm-mac10 ports, configure the VSP as 10G
 	 * ports so that kernel can configure correct port.
 	 */
-	if (fif->mac_type == fman_offline)
-		return e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
 	else if (fif->mac_type == fman_mac_1g &&
 		fif->mac_idx >= DPAA_10G_MAC_START_IDX)
 		return e_FM_PORT_TYPE_RX_10G;
@@ -667,7 +671,8 @@  static inline int get_rx_port_type(struct fman_if *fif)
 
 static inline int get_tx_port_type(struct fman_if *fif)
 {
-	if (fif->mac_type == fman_offline)
+	if (fif->mac_type == fman_offline_internal ||
+	    fif->mac_type == fman_onic)
 		return e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
 	else if (fif->mac_type == fman_mac_1g)
 		return e_FM_PORT_TYPE_TX;
@@ -976,25 +981,12 @@  static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
 	memset(&vsp_params, 0, sizeof(vsp_params));
 	vsp_params.h_fm = fman_handle;
 	vsp_params.relative_profile_id = vsp_id;
-	if (fif->mac_type == fman_offline)
+	if (fif->mac_type == fman_offline_internal ||
+	    fif->mac_type == fman_onic)
 		vsp_params.port_params.port_id = fif->mac_idx;
 	else
 		vsp_params.port_params.port_id = idx;
 
-	if (fif->mac_type == fman_mac_1g) {
-		vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX;
-	} else if (fif->mac_type == fman_mac_2_5g) {
-		vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX_2_5G;
-	} else if (fif->mac_type == fman_mac_10g) {
-		vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX_10G;
-	} else if (fif->mac_type == fman_offline) {
-		vsp_params.port_params.port_type =
-				e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
-	} else {
-		DPAA_PMD_ERR("Mac type %d error", fif->mac_type);
-		return -1;
-	}
-
 	vsp_params.port_params.port_type = get_rx_port_type(fif);
 	if (vsp_params.port_params.port_type == e_FM_PORT_TYPE_DUMMY) {
 		DPAA_PMD_ERR("Mac type %d error", fif->mac_type);
diff --git a/drivers/net/dpaa/dpaa_fmc.c b/drivers/net/dpaa/dpaa_fmc.c
index c9a25a98db..7dc42f6e23 100644
--- a/drivers/net/dpaa/dpaa_fmc.c
+++ b/drivers/net/dpaa/dpaa_fmc.c
@@ -215,7 +215,8 @@  dpaa_port_fmc_port_parse(struct fman_if *fif,
 
 	if (pport->type == e_FM_PORT_TYPE_OH_OFFLINE_PARSING &&
 	    pport->number == fif->mac_idx &&
-	    fif->mac_type == fman_offline)
+	    (fif->mac_type == fman_offline_internal ||
+	     fif->mac_type == fman_onic))
 		return current_port;
 
 	if (fif->mac_type == fman_mac_1g) {