183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2c517771aSPrabhakar Kushwaha /*
3a6f2a6eaSYogesh Gaur  * Copyright 2014-2016 Freescale Semiconductor, Inc.
42557c5a9SYogesh Gaur  * Copyright 2017 NXP
5c517771aSPrabhakar Kushwaha  */
6c517771aSPrabhakar Kushwaha 
7c517771aSPrabhakar Kushwaha #include <common.h>
8c517771aSPrabhakar Kushwaha #include <asm/io.h>
9c517771aSPrabhakar Kushwaha #include <asm/types.h>
10c517771aSPrabhakar Kushwaha #include <malloc.h>
11c517771aSPrabhakar Kushwaha #include <net.h>
12c517771aSPrabhakar Kushwaha #include <hwconfig.h>
13c517771aSPrabhakar Kushwaha #include <phy.h>
14c517771aSPrabhakar Kushwaha #include <linux/compat.h>
15c919ab9eSPrabhakar Kushwaha #include <fsl-mc/fsl_dpmac.h>
16c517771aSPrabhakar Kushwaha 
176c2b520aSPrabhakar Kushwaha #include <fsl-mc/ldpaa_wriop.h>
18c517771aSPrabhakar Kushwaha #include "ldpaa_eth.h"
19c517771aSPrabhakar Kushwaha 
206c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
init_phy(struct eth_device * dev)21c517771aSPrabhakar Kushwaha static int init_phy(struct eth_device *dev)
22c517771aSPrabhakar Kushwaha {
236c2b520aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
246c2b520aSPrabhakar Kushwaha 	struct phy_device *phydev = NULL;
256c2b520aSPrabhakar Kushwaha 	struct mii_dev *bus;
261a048cd6SPankaj Bansal 	int phy_addr, phy_num;
271a048cd6SPankaj Bansal 	int ret = 0;
28c517771aSPrabhakar Kushwaha 
296c2b520aSPrabhakar Kushwaha 	bus = wriop_get_mdio(priv->dpmac_id);
306c2b520aSPrabhakar Kushwaha 	if (bus == NULL)
31c517771aSPrabhakar Kushwaha 		return 0;
326c2b520aSPrabhakar Kushwaha 
331a048cd6SPankaj Bansal 	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
341a048cd6SPankaj Bansal 		phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num);
351a048cd6SPankaj Bansal 		if (phy_addr < 0)
361a048cd6SPankaj Bansal 			continue;
371a048cd6SPankaj Bansal 
381a048cd6SPankaj Bansal 		phydev = phy_connect(bus, phy_addr, dev,
391a048cd6SPankaj Bansal 				     wriop_get_enet_if(priv->dpmac_id));
406c2b520aSPrabhakar Kushwaha 		if (!phydev) {
416c2b520aSPrabhakar Kushwaha 			printf("Failed to connect\n");
421a048cd6SPankaj Bansal 			ret = -ENODEV;
431a048cd6SPankaj Bansal 			break;
441a048cd6SPankaj Bansal 		}
451a048cd6SPankaj Bansal 		wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev);
461a048cd6SPankaj Bansal 		ret = phy_config(phydev);
471a048cd6SPankaj Bansal 		if (ret)
481a048cd6SPankaj Bansal 			break;
49c517771aSPrabhakar Kushwaha 	}
50c517771aSPrabhakar Kushwaha 
51f259c43dSPankaj Bansal 	if (ret) {
521a048cd6SPankaj Bansal 		for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
531a048cd6SPankaj Bansal 			phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
541a048cd6SPankaj Bansal 			if (!phydev)
551a048cd6SPankaj Bansal 				continue;
561a048cd6SPankaj Bansal 
57f259c43dSPankaj Bansal 			free(phydev);
581a048cd6SPankaj Bansal 			wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL);
591a048cd6SPankaj Bansal 		}
60f259c43dSPankaj Bansal 	}
61f259c43dSPankaj Bansal 
62f259c43dSPankaj Bansal 	return ret;
636c2b520aSPrabhakar Kushwaha }
646c2b520aSPrabhakar Kushwaha #endif
656c2b520aSPrabhakar Kushwaha 
665038d3e5SPrabhakar Kushwaha #ifdef DEBUG
672557c5a9SYogesh Gaur 
682557c5a9SYogesh Gaur #define DPNI_STATS_PER_PAGE 6
692557c5a9SYogesh Gaur 
702557c5a9SYogesh Gaur static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = {
712557c5a9SYogesh Gaur 	{
722557c5a9SYogesh Gaur 	"DPNI_CNT_ING_ALL_FRAMES",
732557c5a9SYogesh Gaur 	"DPNI_CNT_ING_ALL_BYTES",
742557c5a9SYogesh Gaur 	"DPNI_CNT_ING_MCAST_FRAMES",
752557c5a9SYogesh Gaur 	"DPNI_CNT_ING_MCAST_BYTES",
762557c5a9SYogesh Gaur 	"DPNI_CNT_ING_BCAST_FRAMES",
772557c5a9SYogesh Gaur 	"DPNI_CNT_ING_BCAST_BYTES",
782557c5a9SYogesh Gaur 	}, {
792557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_ALL_FRAMES",
802557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_ALL_BYTES",
812557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_MCAST_FRAMES",
822557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_MCAST_BYTES",
832557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_BCAST_FRAMES",
842557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_BCAST_BYTES",
852557c5a9SYogesh Gaur 	}, {
862557c5a9SYogesh Gaur 	"DPNI_CNT_ING_FILTERED_FRAMES",
872557c5a9SYogesh Gaur 	"DPNI_CNT_ING_DISCARDED_FRAMES",
882557c5a9SYogesh Gaur 	"DPNI_CNT_ING_NOBUFFER_DISCARDS",
892557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_DISCARDED_FRAMES",
902557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_CNF_FRAMES",
912557c5a9SYogesh Gaur 	""
922557c5a9SYogesh Gaur 	},
932557c5a9SYogesh Gaur };
942557c5a9SYogesh Gaur 
print_dpni_stats(const char * strings[],struct dpni_statistics dpni_stats)952557c5a9SYogesh Gaur static void print_dpni_stats(const char *strings[],
962557c5a9SYogesh Gaur 			     struct dpni_statistics dpni_stats)
972557c5a9SYogesh Gaur {
982557c5a9SYogesh Gaur 	uint64_t *stat;
992557c5a9SYogesh Gaur 	int i;
1002557c5a9SYogesh Gaur 
1012557c5a9SYogesh Gaur 	stat = (uint64_t *)&dpni_stats;
1022557c5a9SYogesh Gaur 	for (i = 0; i < DPNI_STATS_PER_PAGE; i++) {
1032557c5a9SYogesh Gaur 		if (strcmp(strings[i], "\0") == 0)
1042557c5a9SYogesh Gaur 			break;
1052557c5a9SYogesh Gaur 		printf("%s= %llu\n", strings[i], *stat);
1062557c5a9SYogesh Gaur 		stat++;
1072557c5a9SYogesh Gaur 	}
1082557c5a9SYogesh Gaur }
1092557c5a9SYogesh Gaur 
ldpaa_eth_get_dpni_counter(void)1105038d3e5SPrabhakar Kushwaha static void ldpaa_eth_get_dpni_counter(void)
1115038d3e5SPrabhakar Kushwaha {
1125038d3e5SPrabhakar Kushwaha 	int err = 0;
1132557c5a9SYogesh Gaur 	unsigned int page = 0;
1142557c5a9SYogesh Gaur 	struct dpni_statistics dpni_stats;
1155038d3e5SPrabhakar Kushwaha 
1162557c5a9SYogesh Gaur 	printf("DPNI counters ..\n");
1172557c5a9SYogesh Gaur 	for (page = 0; page < 3; page++) {
1182557c5a9SYogesh Gaur 		err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS,
1192557c5a9SYogesh Gaur 					  dflt_dpni->dpni_handle, page,
1202557c5a9SYogesh Gaur 					  &dpni_stats);
1215038d3e5SPrabhakar Kushwaha 		if (err < 0) {
1222557c5a9SYogesh Gaur 			printf("dpni_get_statistics: failed:");
1232557c5a9SYogesh Gaur 			printf("%d for page[%d]\n", err, page);
1245038d3e5SPrabhakar Kushwaha 			return;
1255038d3e5SPrabhakar Kushwaha 		}
1262557c5a9SYogesh Gaur 		print_dpni_stats(dpni_statistics[page], dpni_stats);
1275038d3e5SPrabhakar Kushwaha 	}
1285038d3e5SPrabhakar Kushwaha }
12944b2036eSPrabhakar Kushwaha 
ldpaa_eth_get_dpmac_counter(struct eth_device * net_dev)13044b2036eSPrabhakar Kushwaha static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev)
13144b2036eSPrabhakar Kushwaha {
13244b2036eSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
13344b2036eSPrabhakar Kushwaha 	int err = 0;
13444b2036eSPrabhakar Kushwaha 	u64 value;
13544b2036eSPrabhakar Kushwaha 
13644b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
13744b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
13844b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_BYTE,
13944b2036eSPrabhakar Kushwaha 		     &value);
14044b2036eSPrabhakar Kushwaha 	if (err < 0) {
14144b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
14244b2036eSPrabhakar Kushwaha 		return;
14344b2036eSPrabhakar Kushwaha 	}
1442557c5a9SYogesh Gaur 	printf("\nDPMAC counters ..\n");
14544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
14644b2036eSPrabhakar Kushwaha 
14744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
14844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
14944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_FRAME_DISCARD,
15044b2036eSPrabhakar Kushwaha 		     &value);
15144b2036eSPrabhakar Kushwaha 	if (err < 0) {
15244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
15344b2036eSPrabhakar Kushwaha 		return;
15444b2036eSPrabhakar Kushwaha 	}
15544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value);
15644b2036eSPrabhakar Kushwaha 
15744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
15844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
15944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_ALIGN_ERR,
16044b2036eSPrabhakar Kushwaha 		     &value);
16144b2036eSPrabhakar Kushwaha 	if (err < 0) {
16244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
16344b2036eSPrabhakar Kushwaha 		return;
16444b2036eSPrabhakar Kushwaha 	}
16544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value);
16644b2036eSPrabhakar Kushwaha 
16744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
16844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
16944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_BYTE,
17044b2036eSPrabhakar Kushwaha 		     &value);
17144b2036eSPrabhakar Kushwaha 	if (err < 0) {
17244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
17344b2036eSPrabhakar Kushwaha 		return;
17444b2036eSPrabhakar Kushwaha 	}
17544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
17644b2036eSPrabhakar Kushwaha 
17744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
17844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
17944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_ERR_FRAME,
18044b2036eSPrabhakar Kushwaha 		     &value);
18144b2036eSPrabhakar Kushwaha 	if (err < 0) {
18244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
18344b2036eSPrabhakar Kushwaha 		return;
18444b2036eSPrabhakar Kushwaha 	}
18544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value);
18644b2036eSPrabhakar Kushwaha 
18744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
18844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
18944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_EGR_BYTE ,
19044b2036eSPrabhakar Kushwaha 		     &value);
19144b2036eSPrabhakar Kushwaha 	if (err < 0) {
19244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
19344b2036eSPrabhakar Kushwaha 		return;
19444b2036eSPrabhakar Kushwaha 	}
19544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_EGR_BYTE =%lld\n", value);
19644b2036eSPrabhakar Kushwaha 
19744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
19844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
19944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_EGR_ERR_FRAME ,
20044b2036eSPrabhakar Kushwaha 		     &value);
20144b2036eSPrabhakar Kushwaha 	if (err < 0) {
20244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
20344b2036eSPrabhakar Kushwaha 		return;
20444b2036eSPrabhakar Kushwaha 	}
20544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
20644b2036eSPrabhakar Kushwaha }
2075038d3e5SPrabhakar Kushwaha #endif
2085038d3e5SPrabhakar Kushwaha 
ldpaa_eth_rx(struct ldpaa_eth_priv * priv,const struct dpaa_fd * fd)209c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
210c517771aSPrabhakar Kushwaha 			 const struct dpaa_fd *fd)
211c517771aSPrabhakar Kushwaha {
212c517771aSPrabhakar Kushwaha 	u64 fd_addr;
213c517771aSPrabhakar Kushwaha 	uint16_t fd_offset;
214c517771aSPrabhakar Kushwaha 	uint32_t fd_length;
215c517771aSPrabhakar Kushwaha 	struct ldpaa_fas *fas;
216c517771aSPrabhakar Kushwaha 	uint32_t status, err;
21756c57cf7SPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
21856c57cf7SPrabhakar Kushwaha 	u32 time_start;
219c517771aSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
220c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
221c517771aSPrabhakar Kushwaha 
222c517771aSPrabhakar Kushwaha 	fd_addr = ldpaa_fd_get_addr(fd);
223c517771aSPrabhakar Kushwaha 	fd_offset = ldpaa_fd_get_offset(fd);
224c517771aSPrabhakar Kushwaha 	fd_length = ldpaa_fd_get_len(fd);
225c517771aSPrabhakar Kushwaha 
226c517771aSPrabhakar Kushwaha 	debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
227c517771aSPrabhakar Kushwaha 
228c517771aSPrabhakar Kushwaha 	if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
229c517771aSPrabhakar Kushwaha 		/* Read the frame annotation status word and check for errors */
230c517771aSPrabhakar Kushwaha 		fas = (struct ldpaa_fas *)
231c517771aSPrabhakar Kushwaha 				((uint8_t *)(fd_addr) +
232c919ab9eSPrabhakar Kushwaha 				dflt_dpni->buf_layout.private_data_size);
233c517771aSPrabhakar Kushwaha 		status = le32_to_cpu(fas->status);
234c517771aSPrabhakar Kushwaha 		if (status & LDPAA_ETH_RX_ERR_MASK) {
235c517771aSPrabhakar Kushwaha 			printf("Rx frame error(s): 0x%08x\n",
236c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_ERR_MASK);
237c517771aSPrabhakar Kushwaha 			goto error;
238c517771aSPrabhakar Kushwaha 		} else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
239c517771aSPrabhakar Kushwaha 			printf("Unsupported feature in bitmask: 0x%08x\n",
240c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_UNSUPP_MASK);
241c517771aSPrabhakar Kushwaha 			goto error;
242c517771aSPrabhakar Kushwaha 		}
243c517771aSPrabhakar Kushwaha 	}
244c517771aSPrabhakar Kushwaha 
245c517771aSPrabhakar Kushwaha 	debug("Rx frame: To Upper layer\n");
246c517771aSPrabhakar Kushwaha 	net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
247c517771aSPrabhakar Kushwaha 				    fd_length);
248c517771aSPrabhakar Kushwaha 
249c517771aSPrabhakar Kushwaha error:
2505753b0f1SPrabhakar Kushwaha 	flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
251c517771aSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
252c517771aSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
25356c57cf7SPrabhakar Kushwaha 	time_start = get_timer(0);
254c517771aSPrabhakar Kushwaha 	do {
255c517771aSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
256c517771aSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
25756c57cf7SPrabhakar Kushwaha 	} while (get_timer(time_start) < timeo && err == -EBUSY);
25856c57cf7SPrabhakar Kushwaha 
25956c57cf7SPrabhakar Kushwaha 	if (err == -EBUSY)
26056c57cf7SPrabhakar Kushwaha 		printf("Rx frame: QBMAN buffer release fails\n");
26156c57cf7SPrabhakar Kushwaha 
262c517771aSPrabhakar Kushwaha 	return;
263c517771aSPrabhakar Kushwaha }
264c517771aSPrabhakar Kushwaha 
ldpaa_eth_pull_dequeue_rx(struct eth_device * dev)265c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
266c517771aSPrabhakar Kushwaha {
267c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
268c517771aSPrabhakar Kushwaha 	const struct ldpaa_dq *dq;
269c517771aSPrabhakar Kushwaha 	const struct dpaa_fd *fd;
270b4c3a35dSPrabhakar Kushwaha 	int i = 5, err = 0, status;
271b4c3a35dSPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
272b4c3a35dSPrabhakar Kushwaha 	u32 time_start;
273c517771aSPrabhakar Kushwaha 	static struct qbman_pull_desc pulldesc;
274c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
275c517771aSPrabhakar Kushwaha 
2765753b0f1SPrabhakar Kushwaha 	while (--i) {
277c517771aSPrabhakar Kushwaha 		qbman_pull_desc_clear(&pulldesc);
278c517771aSPrabhakar Kushwaha 		qbman_pull_desc_set_numframes(&pulldesc, 1);
279c517771aSPrabhakar Kushwaha 		qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
280c517771aSPrabhakar Kushwaha 
281c517771aSPrabhakar Kushwaha 		err = qbman_swp_pull(swp, &pulldesc);
282c517771aSPrabhakar Kushwaha 		if (err < 0) {
283c517771aSPrabhakar Kushwaha 			printf("Dequeue frames error:0x%08x\n", err);
284c517771aSPrabhakar Kushwaha 			continue;
285c517771aSPrabhakar Kushwaha 		}
286c517771aSPrabhakar Kushwaha 
287b4c3a35dSPrabhakar Kushwaha 		time_start = get_timer(0);
2885753b0f1SPrabhakar Kushwaha 
289b4c3a35dSPrabhakar Kushwaha 		 do {
290b4c3a35dSPrabhakar Kushwaha 			dq = qbman_swp_dqrr_next(swp);
291b4c3a35dSPrabhakar Kushwaha 		} while (get_timer(time_start) < timeo && !dq);
2925753b0f1SPrabhakar Kushwaha 
293c517771aSPrabhakar Kushwaha 		if (dq) {
294c517771aSPrabhakar Kushwaha 			/* Check for valid frame. If not sent a consume
295c517771aSPrabhakar Kushwaha 			 * confirmation to QBMAN otherwise give it to NADK
296c517771aSPrabhakar Kushwaha 			 * application and then send consume confirmation to
297c517771aSPrabhakar Kushwaha 			 * QBMAN.
298c517771aSPrabhakar Kushwaha 			 */
299c517771aSPrabhakar Kushwaha 			status = (uint8_t)ldpaa_dq_flags(dq);
300c517771aSPrabhakar Kushwaha 			if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
301c517771aSPrabhakar Kushwaha 				debug("Dequeue RX frames:");
302c517771aSPrabhakar Kushwaha 				debug("No frame delivered\n");
303c517771aSPrabhakar Kushwaha 
304c517771aSPrabhakar Kushwaha 				qbman_swp_dqrr_consume(swp, dq);
3050c7c87a4SPrabhakar Kushwaha 				continue;
306c517771aSPrabhakar Kushwaha 			}
307c517771aSPrabhakar Kushwaha 
308c517771aSPrabhakar Kushwaha 			fd = ldpaa_dq_fd(dq);
309c517771aSPrabhakar Kushwaha 
310c517771aSPrabhakar Kushwaha 			/* Obtain FD and process it */
311c517771aSPrabhakar Kushwaha 			ldpaa_eth_rx(priv, fd);
312c517771aSPrabhakar Kushwaha 			qbman_swp_dqrr_consume(swp, dq);
313c517771aSPrabhakar Kushwaha 			break;
314b4c3a35dSPrabhakar Kushwaha 		} else {
315b4c3a35dSPrabhakar Kushwaha 			err = -ENODATA;
316b4c3a35dSPrabhakar Kushwaha 			debug("No DQRR entries\n");
317b4c3a35dSPrabhakar Kushwaha 			break;
318c517771aSPrabhakar Kushwaha 		}
319c517771aSPrabhakar Kushwaha 	}
320c517771aSPrabhakar Kushwaha 
321c517771aSPrabhakar Kushwaha 	return err;
322c517771aSPrabhakar Kushwaha }
323c517771aSPrabhakar Kushwaha 
ldpaa_eth_tx(struct eth_device * net_dev,void * buf,int len)324c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
325c517771aSPrabhakar Kushwaha {
326c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
327c517771aSPrabhakar Kushwaha 	struct dpaa_fd fd;
328c517771aSPrabhakar Kushwaha 	u64 buffer_start;
329c517771aSPrabhakar Kushwaha 	int data_offset, err;
330e48df52bSPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
331e48df52bSPrabhakar Kushwaha 	u32 time_start;
332c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
333c517771aSPrabhakar Kushwaha 	struct qbman_eq_desc ed;
334e48df52bSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
335c517771aSPrabhakar Kushwaha 
336c517771aSPrabhakar Kushwaha 	/* Setup the FD fields */
337c517771aSPrabhakar Kushwaha 	memset(&fd, 0, sizeof(fd));
338c517771aSPrabhakar Kushwaha 
339c517771aSPrabhakar Kushwaha 	data_offset = priv->tx_data_offset;
340c517771aSPrabhakar Kushwaha 
341c517771aSPrabhakar Kushwaha 	do {
342c517771aSPrabhakar Kushwaha 		err = qbman_swp_acquire(dflt_dpio->sw_portal,
343c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
344c517771aSPrabhakar Kushwaha 					&buffer_start, 1);
345c517771aSPrabhakar Kushwaha 	} while (err == -EBUSY);
346c517771aSPrabhakar Kushwaha 
3475e9445daSAshish Kumar 	if (err <= 0) {
348c517771aSPrabhakar Kushwaha 		printf("qbman_swp_acquire() failed\n");
349c517771aSPrabhakar Kushwaha 		return -ENOMEM;
350c517771aSPrabhakar Kushwaha 	}
351c517771aSPrabhakar Kushwaha 
352c517771aSPrabhakar Kushwaha 	debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
353c517771aSPrabhakar Kushwaha 
354c517771aSPrabhakar Kushwaha 	memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
355c517771aSPrabhakar Kushwaha 
3565753b0f1SPrabhakar Kushwaha 	flush_dcache_range(buffer_start, buffer_start +
3575753b0f1SPrabhakar Kushwaha 					LDPAA_ETH_RX_BUFFER_SIZE);
358c517771aSPrabhakar Kushwaha 
359c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_addr(&fd, (u64)buffer_start);
360c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
361c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
362c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_len(&fd, len);
363c517771aSPrabhakar Kushwaha 
364c517771aSPrabhakar Kushwaha 	fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
365c517771aSPrabhakar Kushwaha 				LDPAA_FD_CTRL_PTV1;
366c517771aSPrabhakar Kushwaha 
367c517771aSPrabhakar Kushwaha 	qbman_eq_desc_clear(&ed);
368c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_no_orp(&ed, 0);
369c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
370e48df52bSPrabhakar Kushwaha 
371e48df52bSPrabhakar Kushwaha 	time_start = get_timer(0);
372e48df52bSPrabhakar Kushwaha 
373e48df52bSPrabhakar Kushwaha 	while (get_timer(time_start) < timeo) {
374e48df52bSPrabhakar Kushwaha 		err = qbman_swp_enqueue(swp, &ed,
375e48df52bSPrabhakar Kushwaha 				(const struct qbman_fd *)(&fd));
376e48df52bSPrabhakar Kushwaha 		if (err != -EBUSY)
377e48df52bSPrabhakar Kushwaha 			break;
378e48df52bSPrabhakar Kushwaha 	}
379e48df52bSPrabhakar Kushwaha 
380e48df52bSPrabhakar Kushwaha 	if (err < 0) {
381c517771aSPrabhakar Kushwaha 		printf("error enqueueing Tx frame\n");
382e48df52bSPrabhakar Kushwaha 		goto error;
383e48df52bSPrabhakar Kushwaha 	}
384c517771aSPrabhakar Kushwaha 
385c517771aSPrabhakar Kushwaha 	return err;
386e48df52bSPrabhakar Kushwaha 
387e48df52bSPrabhakar Kushwaha error:
388e48df52bSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
389e48df52bSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
390e48df52bSPrabhakar Kushwaha 	time_start = get_timer(0);
391e48df52bSPrabhakar Kushwaha 	do {
392e48df52bSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
393e48df52bSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
394e48df52bSPrabhakar Kushwaha 	} while (get_timer(time_start) < timeo && err == -EBUSY);
395e48df52bSPrabhakar Kushwaha 
396e48df52bSPrabhakar Kushwaha 	if (err == -EBUSY)
397e48df52bSPrabhakar Kushwaha 		printf("TX data: QBMAN buffer release fails\n");
398e48df52bSPrabhakar Kushwaha 
399e48df52bSPrabhakar Kushwaha 	return err;
400c517771aSPrabhakar Kushwaha }
401c517771aSPrabhakar Kushwaha 
ldpaa_get_dpmac_state(struct ldpaa_eth_priv * priv,struct dpmac_link_state * state)402a3cb5340SPankaj Bansal static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
403a3cb5340SPankaj Bansal 				 struct dpmac_link_state *state)
404a3cb5340SPankaj Bansal {
405a3cb5340SPankaj Bansal 	phy_interface_t enet_if;
406*15f22ac2STom Rini 	int phys_detected;
407*15f22ac2STom Rini #ifdef CONFIG_PHYLIB
408*15f22ac2STom Rini 	struct phy_device *phydev = NULL;
409*15f22ac2STom Rini 	int err, phy_num;
410*15f22ac2STom Rini #endif
411a3cb5340SPankaj Bansal 
4121a048cd6SPankaj Bansal 	/* let's start off with maximum capabilities */
413a3cb5340SPankaj Bansal 	enet_if = wriop_get_enet_if(priv->dpmac_id);
414a3cb5340SPankaj Bansal 	switch (enet_if) {
415a3cb5340SPankaj Bansal 	case PHY_INTERFACE_MODE_XGMII:
416a3cb5340SPankaj Bansal 		state->rate = SPEED_10000;
417a3cb5340SPankaj Bansal 		break;
418a3cb5340SPankaj Bansal 	default:
419a3cb5340SPankaj Bansal 		state->rate = SPEED_1000;
420a3cb5340SPankaj Bansal 		break;
421a3cb5340SPankaj Bansal 	}
422a3cb5340SPankaj Bansal 	state->up = 1;
423a3cb5340SPankaj Bansal 
4241a048cd6SPankaj Bansal 	phys_detected = 0;
425a3cb5340SPankaj Bansal #ifdef CONFIG_PHYLIB
426a3cb5340SPankaj Bansal 	state->options |= DPMAC_LINK_OPT_AUTONEG;
427a3cb5340SPankaj Bansal 
4281a048cd6SPankaj Bansal 	/* start the phy devices one by one and update the dpmac state */
4291a048cd6SPankaj Bansal 	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
4301a048cd6SPankaj Bansal 		phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
4311a048cd6SPankaj Bansal 		if (!phydev)
4321a048cd6SPankaj Bansal 			continue;
4331a048cd6SPankaj Bansal 
4341a048cd6SPankaj Bansal 		phys_detected++;
435a3cb5340SPankaj Bansal 		err = phy_startup(phydev);
436a3cb5340SPankaj Bansal 		if (err) {
437a3cb5340SPankaj Bansal 			printf("%s: Could not initialize\n", phydev->dev->name);
438a3cb5340SPankaj Bansal 			state->up = 0;
4391a048cd6SPankaj Bansal 			break;
440a3cb5340SPankaj Bansal 		}
441a3cb5340SPankaj Bansal 		if (phydev->link) {
442a3cb5340SPankaj Bansal 			state->rate = min(state->rate, (uint32_t)phydev->speed);
443a3cb5340SPankaj Bansal 			if (!phydev->duplex)
444a3cb5340SPankaj Bansal 				state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
445a3cb5340SPankaj Bansal 			if (!phydev->autoneg)
446a3cb5340SPankaj Bansal 				state->options &= ~DPMAC_LINK_OPT_AUTONEG;
447a3cb5340SPankaj Bansal 		} else {
4481a048cd6SPankaj Bansal 			/* break out of loop even if one phy is down */
449a3cb5340SPankaj Bansal 			state->up = 0;
4501a048cd6SPankaj Bansal 			break;
451a3cb5340SPankaj Bansal 		}
452a3cb5340SPankaj Bansal 	}
453a3cb5340SPankaj Bansal #endif
4541a048cd6SPankaj Bansal 	if (!phys_detected)
455a3cb5340SPankaj Bansal 		state->options &= ~DPMAC_LINK_OPT_AUTONEG;
456a3cb5340SPankaj Bansal 
457a3cb5340SPankaj Bansal 	if (!state->up) {
458a3cb5340SPankaj Bansal 		state->rate = 0;
459a3cb5340SPankaj Bansal 		state->options = 0;
460a3cb5340SPankaj Bansal 		return -ENOLINK;
461a3cb5340SPankaj Bansal 	}
462a3cb5340SPankaj Bansal 
463a3cb5340SPankaj Bansal 	return 0;
464a3cb5340SPankaj Bansal }
465a3cb5340SPankaj Bansal 
ldpaa_eth_open(struct eth_device * net_dev,bd_t * bd)466c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
467c517771aSPrabhakar Kushwaha {
468c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
469c919ab9eSPrabhakar Kushwaha 	struct dpmac_link_state	dpmac_link_state = { 0 };
4705038d3e5SPrabhakar Kushwaha #ifdef DEBUG
4715038d3e5SPrabhakar Kushwaha 	struct dpni_link_state link_state;
4725038d3e5SPrabhakar Kushwaha #endif
4736c2b520aSPrabhakar Kushwaha 	int err = 0;
4742557c5a9SYogesh Gaur 	struct dpni_queue d_queue;
475c517771aSPrabhakar Kushwaha 
476c517771aSPrabhakar Kushwaha 	if (net_dev->state == ETH_STATE_ACTIVE)
477c517771aSPrabhakar Kushwaha 		return 0;
478c517771aSPrabhakar Kushwaha 
479c919ab9eSPrabhakar Kushwaha 	if (get_mc_boot_status() != 0) {
480c919ab9eSPrabhakar Kushwaha 		printf("ERROR (MC is not booted)\n");
481c919ab9eSPrabhakar Kushwaha 		return -ENODEV;
482c919ab9eSPrabhakar Kushwaha 	}
483c919ab9eSPrabhakar Kushwaha 
484c919ab9eSPrabhakar Kushwaha 	if (get_dpl_apply_status() == 0) {
485c919ab9eSPrabhakar Kushwaha 		printf("ERROR (DPL is deployed. No device available)\n");
486c919ab9eSPrabhakar Kushwaha 		return -ENODEV;
487c919ab9eSPrabhakar Kushwaha 	}
4886c2b520aSPrabhakar Kushwaha 
489c919ab9eSPrabhakar Kushwaha 	/* DPMAC initialization */
490c919ab9eSPrabhakar Kushwaha 	err = ldpaa_dpmac_setup(priv);
491c919ab9eSPrabhakar Kushwaha 	if (err < 0)
492c919ab9eSPrabhakar Kushwaha 		goto err_dpmac_setup;
493c919ab9eSPrabhakar Kushwaha 
494a3cb5340SPankaj Bansal 	err = ldpaa_get_dpmac_state(priv, &dpmac_link_state);
495a3cb5340SPankaj Bansal 	if (err < 0)
496afd6c6b4SPankaj Bansal 		goto err_dpmac_bind;
4976c2b520aSPrabhakar Kushwaha 
498c919ab9eSPrabhakar Kushwaha 	/* DPMAC binding DPNI */
499c919ab9eSPrabhakar Kushwaha 	err = ldpaa_dpmac_bind(priv);
500c919ab9eSPrabhakar Kushwaha 	if (err)
501afd6c6b4SPankaj Bansal 		goto err_dpmac_bind;
502c919ab9eSPrabhakar Kushwaha 
503c517771aSPrabhakar Kushwaha 	/* DPNI initialization */
504c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_setup(priv);
505c517771aSPrabhakar Kushwaha 	if (err < 0)
506c517771aSPrabhakar Kushwaha 		goto err_dpni_setup;
507c517771aSPrabhakar Kushwaha 
508c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_setup();
509c517771aSPrabhakar Kushwaha 	if (err < 0)
510c517771aSPrabhakar Kushwaha 		goto err_dpbp_setup;
511c517771aSPrabhakar Kushwaha 
512c517771aSPrabhakar Kushwaha 	/* DPNI binding DPBP */
513c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_bind(priv);
514c517771aSPrabhakar Kushwaha 	if (err)
515c919ab9eSPrabhakar Kushwaha 		goto err_dpni_bind;
516c517771aSPrabhakar Kushwaha 
5177b2edb8bSPrabhakar Kushwaha 	err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
518c919ab9eSPrabhakar Kushwaha 				dflt_dpni->dpni_handle, net_dev->enetaddr);
519c517771aSPrabhakar Kushwaha 	if (err) {
5207b2edb8bSPrabhakar Kushwaha 		printf("dpni_add_mac_addr() failed\n");
521c517771aSPrabhakar Kushwaha 		return err;
522c517771aSPrabhakar Kushwaha 	}
523c517771aSPrabhakar Kushwaha 
524c919ab9eSPrabhakar Kushwaha 	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
525c517771aSPrabhakar Kushwaha 	if (err < 0) {
526c517771aSPrabhakar Kushwaha 		printf("dpni_enable() failed\n");
527c517771aSPrabhakar Kushwaha 		return err;
528c517771aSPrabhakar Kushwaha 	}
529c517771aSPrabhakar Kushwaha 
530c919ab9eSPrabhakar Kushwaha 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
531c919ab9eSPrabhakar Kushwaha 				  priv->dpmac_handle, &dpmac_link_state);
532c919ab9eSPrabhakar Kushwaha 	if (err < 0) {
533c919ab9eSPrabhakar Kushwaha 		printf("dpmac_set_link_state() failed\n");
534c919ab9eSPrabhakar Kushwaha 		return err;
535c919ab9eSPrabhakar Kushwaha 	}
5365038d3e5SPrabhakar Kushwaha 
5375038d3e5SPrabhakar Kushwaha #ifdef DEBUG
5382557c5a9SYogesh Gaur 	printf("DPMAC link status: %d - ", dpmac_link_state.up);
5392557c5a9SYogesh Gaur 	dpmac_link_state.up == 0 ? printf("down\n") :
5402557c5a9SYogesh Gaur 	dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n");
5412557c5a9SYogesh Gaur 
5425038d3e5SPrabhakar Kushwaha 	err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
5435038d3e5SPrabhakar Kushwaha 				  dflt_dpni->dpni_handle, &link_state);
5445038d3e5SPrabhakar Kushwaha 	if (err < 0) {
5455038d3e5SPrabhakar Kushwaha 		printf("dpni_get_link_state() failed\n");
5465038d3e5SPrabhakar Kushwaha 		return err;
5475038d3e5SPrabhakar Kushwaha 	}
5485038d3e5SPrabhakar Kushwaha 
5492557c5a9SYogesh Gaur 	printf("DPNI link status: %d - ", link_state.up);
5505038d3e5SPrabhakar Kushwaha 	link_state.up == 0 ? printf("down\n") :
5515038d3e5SPrabhakar Kushwaha 	link_state.up == 1 ? printf("up\n") : printf("error state\n");
5525038d3e5SPrabhakar Kushwaha #endif
5535038d3e5SPrabhakar Kushwaha 
5542557c5a9SYogesh Gaur 	memset(&d_queue, 0, sizeof(struct dpni_queue));
5552557c5a9SYogesh Gaur 	err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
5562557c5a9SYogesh Gaur 			     dflt_dpni->dpni_handle, DPNI_QUEUE_RX,
5572557c5a9SYogesh Gaur 			     0, 0, &d_queue);
558c517771aSPrabhakar Kushwaha 	if (err) {
5592557c5a9SYogesh Gaur 		printf("dpni_get_queue failed\n");
5602557c5a9SYogesh Gaur 		goto err_get_queue;
561c517771aSPrabhakar Kushwaha 	}
562c517771aSPrabhakar Kushwaha 
5632557c5a9SYogesh Gaur 	priv->rx_dflt_fqid = d_queue.fqid;
564c517771aSPrabhakar Kushwaha 
565c919ab9eSPrabhakar Kushwaha 	err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
56687457d11SPrabhakar Kushwaha 			    &priv->tx_qdid);
567c517771aSPrabhakar Kushwaha 	if (err) {
568c517771aSPrabhakar Kushwaha 		printf("dpni_get_qdid() failed\n");
569c517771aSPrabhakar Kushwaha 		goto err_qdid;
570c517771aSPrabhakar Kushwaha 	}
571c517771aSPrabhakar Kushwaha 
572a3cb5340SPankaj Bansal 	return dpmac_link_state.up;
573c517771aSPrabhakar Kushwaha 
574c517771aSPrabhakar Kushwaha err_qdid:
5752557c5a9SYogesh Gaur err_get_queue:
576c919ab9eSPrabhakar Kushwaha 	dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
577c919ab9eSPrabhakar Kushwaha err_dpni_bind:
578c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
579c517771aSPrabhakar Kushwaha err_dpbp_setup:
580c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
581c517771aSPrabhakar Kushwaha err_dpni_setup:
582afd6c6b4SPankaj Bansal err_dpmac_bind:
5832557c5a9SYogesh Gaur 	dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
5842557c5a9SYogesh Gaur 	dpmac_destroy(dflt_mc_io,
5852557c5a9SYogesh Gaur 		      dflt_dprc_handle,
5862557c5a9SYogesh Gaur 		      MC_CMD_NO_FLAGS, priv->dpmac_id);
587c919ab9eSPrabhakar Kushwaha err_dpmac_setup:
588c517771aSPrabhakar Kushwaha 	return err;
589c517771aSPrabhakar Kushwaha }
590c517771aSPrabhakar Kushwaha 
ldpaa_eth_stop(struct eth_device * net_dev)591c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev)
592c517771aSPrabhakar Kushwaha {
593c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
594c517771aSPrabhakar Kushwaha 	int err = 0;
595*15f22ac2STom Rini #ifdef CONFIG_PHYLIB
596d75e81d9SPankaj Bansal 	struct phy_device *phydev = NULL;
5971a048cd6SPankaj Bansal 	int phy_num;
598*15f22ac2STom Rini #endif
599c517771aSPrabhakar Kushwaha 
6005753b0f1SPrabhakar Kushwaha 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
6015753b0f1SPrabhakar Kushwaha 	    (net_dev->state == ETH_STATE_INIT))
602c517771aSPrabhakar Kushwaha 		return;
603c919ab9eSPrabhakar Kushwaha 
6045038d3e5SPrabhakar Kushwaha #ifdef DEBUG
6055038d3e5SPrabhakar Kushwaha 	ldpaa_eth_get_dpni_counter();
60644b2036eSPrabhakar Kushwaha 	ldpaa_eth_get_dpmac_counter(net_dev);
6075038d3e5SPrabhakar Kushwaha #endif
6085038d3e5SPrabhakar Kushwaha 
609c919ab9eSPrabhakar Kushwaha 	err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
610c919ab9eSPrabhakar Kushwaha 			      dflt_dprc_handle, &dpmac_endpoint);
611c919ab9eSPrabhakar Kushwaha 	if (err < 0)
612c919ab9eSPrabhakar Kushwaha 		printf("dprc_disconnect() failed dpmac_endpoint\n");
613c919ab9eSPrabhakar Kushwaha 
6142557c5a9SYogesh Gaur 	err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
6152557c5a9SYogesh Gaur 	if (err < 0)
6162557c5a9SYogesh Gaur 		printf("dpmac_close() failed\n");
6172557c5a9SYogesh Gaur 
6182557c5a9SYogesh Gaur 	err = dpmac_destroy(dflt_mc_io,
6192557c5a9SYogesh Gaur 			    dflt_dprc_handle,
6202557c5a9SYogesh Gaur 			    MC_CMD_NO_FLAGS,
6212557c5a9SYogesh Gaur 			    priv->dpmac_id);
622c919ab9eSPrabhakar Kushwaha 	if (err < 0)
623c919ab9eSPrabhakar Kushwaha 		printf("dpmac_destroy() failed\n");
624c919ab9eSPrabhakar Kushwaha 
625c517771aSPrabhakar Kushwaha 	/* Stop Tx and Rx traffic */
626c919ab9eSPrabhakar Kushwaha 	err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
627c517771aSPrabhakar Kushwaha 	if (err < 0)
628c517771aSPrabhakar Kushwaha 		printf("dpni_disable() failed\n");
629c517771aSPrabhakar Kushwaha 
630c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
6311a048cd6SPankaj Bansal 	for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
6321a048cd6SPankaj Bansal 		phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
633a3cb5340SPankaj Bansal 		if (phydev)
634d75e81d9SPankaj Bansal 			phy_shutdown(phydev);
6351a048cd6SPankaj Bansal 	}
636c517771aSPrabhakar Kushwaha #endif
637c517771aSPrabhakar Kushwaha 
6382557c5a9SYogesh Gaur 	/* Free DPBP handle and reset. */
639c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
6402557c5a9SYogesh Gaur 
641c919ab9eSPrabhakar Kushwaha 	dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
6422557c5a9SYogesh Gaur 	if (err < 0)
6432557c5a9SYogesh Gaur 		printf("dpni_reset() failed\n");
6442557c5a9SYogesh Gaur 
645c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
6462557c5a9SYogesh Gaur 	if (err < 0)
6472557c5a9SYogesh Gaur 		printf("dpni_close() failed\n");
648c517771aSPrabhakar Kushwaha }
649c517771aSPrabhakar Kushwaha 
ldpaa_dpbp_drain_cnt(int count)650c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count)
651c517771aSPrabhakar Kushwaha {
652c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
653c517771aSPrabhakar Kushwaha 	void *addr;
654c517771aSPrabhakar Kushwaha 	int ret, i;
655c517771aSPrabhakar Kushwaha 
656c517771aSPrabhakar Kushwaha 	BUG_ON(count > 7);
657c517771aSPrabhakar Kushwaha 
658c517771aSPrabhakar Kushwaha 	do {
659c517771aSPrabhakar Kushwaha 		ret = qbman_swp_acquire(dflt_dpio->sw_portal,
660c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
661c517771aSPrabhakar Kushwaha 					buf_array, count);
662c517771aSPrabhakar Kushwaha 		if (ret < 0) {
663c517771aSPrabhakar Kushwaha 			printf("qbman_swp_acquire() failed\n");
664c517771aSPrabhakar Kushwaha 			return;
665c517771aSPrabhakar Kushwaha 		}
666c517771aSPrabhakar Kushwaha 		for (i = 0; i < ret; i++) {
667c517771aSPrabhakar Kushwaha 			addr = (void *)buf_array[i];
668c517771aSPrabhakar Kushwaha 			debug("Free: buffer addr =0x%p\n", addr);
669c517771aSPrabhakar Kushwaha 			free(addr);
670c517771aSPrabhakar Kushwaha 		}
671c517771aSPrabhakar Kushwaha 	} while (ret);
672c517771aSPrabhakar Kushwaha }
673c517771aSPrabhakar Kushwaha 
ldpaa_dpbp_drain(void)674c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void)
675c517771aSPrabhakar Kushwaha {
676c517771aSPrabhakar Kushwaha 	int i;
677c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
678c517771aSPrabhakar Kushwaha 		ldpaa_dpbp_drain_cnt(7);
679c517771aSPrabhakar Kushwaha }
680c517771aSPrabhakar Kushwaha 
ldpaa_bp_add_7(uint16_t bpid)681c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid)
682c517771aSPrabhakar Kushwaha {
683c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
684c517771aSPrabhakar Kushwaha 	u8 *addr;
685c517771aSPrabhakar Kushwaha 	int i;
686c517771aSPrabhakar Kushwaha 	struct qbman_release_desc rd;
687c517771aSPrabhakar Kushwaha 
688c517771aSPrabhakar Kushwaha 	for (i = 0; i < 7; i++) {
68914480454SPrabhakar Kushwaha 		addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
690c517771aSPrabhakar Kushwaha 		if (!addr) {
691c517771aSPrabhakar Kushwaha 			printf("addr allocation failed\n");
692c517771aSPrabhakar Kushwaha 			goto err_alloc;
693c517771aSPrabhakar Kushwaha 		}
694c517771aSPrabhakar Kushwaha 		memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
6955753b0f1SPrabhakar Kushwaha 		flush_dcache_range((u64)addr,
6965753b0f1SPrabhakar Kushwaha 				   (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
697c517771aSPrabhakar Kushwaha 
698c517771aSPrabhakar Kushwaha 		buf_array[i] = (uint64_t)addr;
699c517771aSPrabhakar Kushwaha 		debug("Release: buffer addr =0x%p\n", addr);
700c517771aSPrabhakar Kushwaha 	}
701c517771aSPrabhakar Kushwaha 
702c517771aSPrabhakar Kushwaha release_bufs:
703c517771aSPrabhakar Kushwaha 	/* In case the portal is busy, retry until successful.
704c517771aSPrabhakar Kushwaha 	 * This function is guaranteed to succeed in a reasonable amount
705c517771aSPrabhakar Kushwaha 	 * of time.
706c517771aSPrabhakar Kushwaha 	 */
707c517771aSPrabhakar Kushwaha 
708c517771aSPrabhakar Kushwaha 	do {
709c517771aSPrabhakar Kushwaha 		mdelay(1);
710c517771aSPrabhakar Kushwaha 		qbman_release_desc_clear(&rd);
711c517771aSPrabhakar Kushwaha 		qbman_release_desc_set_bpid(&rd, bpid);
712c517771aSPrabhakar Kushwaha 	} while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
713c517771aSPrabhakar Kushwaha 
714c517771aSPrabhakar Kushwaha 	return i;
715c517771aSPrabhakar Kushwaha 
716c517771aSPrabhakar Kushwaha err_alloc:
717c517771aSPrabhakar Kushwaha 	if (i)
718c517771aSPrabhakar Kushwaha 		goto release_bufs;
719c517771aSPrabhakar Kushwaha 
720c517771aSPrabhakar Kushwaha 	return 0;
721c517771aSPrabhakar Kushwaha }
722c517771aSPrabhakar Kushwaha 
ldpaa_dpbp_seed(uint16_t bpid)723c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid)
724c517771aSPrabhakar Kushwaha {
725c517771aSPrabhakar Kushwaha 	int i;
726c517771aSPrabhakar Kushwaha 	int count;
727c517771aSPrabhakar Kushwaha 
728c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
729c517771aSPrabhakar Kushwaha 		count = ldpaa_bp_add_7(bpid);
730c517771aSPrabhakar Kushwaha 		if (count < 7)
731c517771aSPrabhakar Kushwaha 			printf("Buffer Seed= %d\n", count);
732c517771aSPrabhakar Kushwaha 	}
733c517771aSPrabhakar Kushwaha 
734c517771aSPrabhakar Kushwaha 	return 0;
735c517771aSPrabhakar Kushwaha }
736c517771aSPrabhakar Kushwaha 
ldpaa_dpbp_setup(void)737c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void)
738c517771aSPrabhakar Kushwaha {
739c517771aSPrabhakar Kushwaha 	int err;
740c517771aSPrabhakar Kushwaha 
74187457d11SPrabhakar Kushwaha 	err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
742c517771aSPrabhakar Kushwaha 			&dflt_dpbp->dpbp_handle);
743c517771aSPrabhakar Kushwaha 	if (err) {
744c517771aSPrabhakar Kushwaha 		printf("dpbp_open() failed\n");
745c517771aSPrabhakar Kushwaha 		goto err_open;
746c517771aSPrabhakar Kushwaha 	}
747c517771aSPrabhakar Kushwaha 
74887457d11SPrabhakar Kushwaha 	err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
749c517771aSPrabhakar Kushwaha 	if (err) {
750c517771aSPrabhakar Kushwaha 		printf("dpbp_enable() failed\n");
751c517771aSPrabhakar Kushwaha 		goto err_enable;
752c517771aSPrabhakar Kushwaha 	}
753c517771aSPrabhakar Kushwaha 
75487457d11SPrabhakar Kushwaha 	err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
75587457d11SPrabhakar Kushwaha 				  dflt_dpbp->dpbp_handle,
756c517771aSPrabhakar Kushwaha 				  &dflt_dpbp->dpbp_attr);
757c517771aSPrabhakar Kushwaha 	if (err) {
758c517771aSPrabhakar Kushwaha 		printf("dpbp_get_attributes() failed\n");
759c517771aSPrabhakar Kushwaha 		goto err_get_attr;
760c517771aSPrabhakar Kushwaha 	}
761c517771aSPrabhakar Kushwaha 
762c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
7632557c5a9SYogesh Gaur 
764c517771aSPrabhakar Kushwaha 	if (err) {
765c517771aSPrabhakar Kushwaha 		printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
766c517771aSPrabhakar Kushwaha 		       dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
767c517771aSPrabhakar Kushwaha 		goto err_seed;
768c517771aSPrabhakar Kushwaha 	}
769c517771aSPrabhakar Kushwaha 
770c517771aSPrabhakar Kushwaha 	return 0;
771c517771aSPrabhakar Kushwaha 
772c517771aSPrabhakar Kushwaha err_seed:
773c517771aSPrabhakar Kushwaha err_get_attr:
77487457d11SPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
775c517771aSPrabhakar Kushwaha err_enable:
77687457d11SPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
777c517771aSPrabhakar Kushwaha err_open:
778c517771aSPrabhakar Kushwaha 	return err;
779c517771aSPrabhakar Kushwaha }
780c517771aSPrabhakar Kushwaha 
ldpaa_dpbp_free(void)781c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void)
782c517771aSPrabhakar Kushwaha {
783c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_drain();
78487457d11SPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
78587457d11SPrabhakar Kushwaha 	dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
78687457d11SPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
787c517771aSPrabhakar Kushwaha }
788c517771aSPrabhakar Kushwaha 
ldpaa_dpmac_version_check(struct fsl_mc_io * mc_io,struct ldpaa_eth_priv * priv)7899a696f56SPrabhakar Kushwaha static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
7909a696f56SPrabhakar Kushwaha 				     struct ldpaa_eth_priv *priv)
7919a696f56SPrabhakar Kushwaha {
7929a696f56SPrabhakar Kushwaha 	int error;
7932557c5a9SYogesh Gaur 	uint16_t major_ver, minor_ver;
7949a696f56SPrabhakar Kushwaha 
7952557c5a9SYogesh Gaur 	error = dpmac_get_api_version(dflt_mc_io, 0,
7962557c5a9SYogesh Gaur 					&major_ver,
7972557c5a9SYogesh Gaur 					&minor_ver);
7982557c5a9SYogesh Gaur 	if ((major_ver < DPMAC_VER_MAJOR) ||
7992557c5a9SYogesh Gaur 	    (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) {
8009a696f56SPrabhakar Kushwaha 		printf("DPMAC version mismatch found %u.%u,",
8012557c5a9SYogesh Gaur 		       major_ver, minor_ver);
8029a696f56SPrabhakar Kushwaha 		printf("supported version is %u.%u\n",
8039a696f56SPrabhakar Kushwaha 		       DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
8042557c5a9SYogesh Gaur 		return error;
8059a696f56SPrabhakar Kushwaha 	}
8069a696f56SPrabhakar Kushwaha 
8079a696f56SPrabhakar Kushwaha 	return error;
8089a696f56SPrabhakar Kushwaha }
8099a696f56SPrabhakar Kushwaha 
ldpaa_dpmac_setup(struct ldpaa_eth_priv * priv)810c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
811c919ab9eSPrabhakar Kushwaha {
812c919ab9eSPrabhakar Kushwaha 	int err = 0;
813c919ab9eSPrabhakar Kushwaha 	struct dpmac_cfg dpmac_cfg;
814c919ab9eSPrabhakar Kushwaha 
815c919ab9eSPrabhakar Kushwaha 	dpmac_cfg.mac_id = priv->dpmac_id;
8162557c5a9SYogesh Gaur 
8172557c5a9SYogesh Gaur 	err = dpmac_create(dflt_mc_io,
8182557c5a9SYogesh Gaur 			   dflt_dprc_handle,
8192557c5a9SYogesh Gaur 			   MC_CMD_NO_FLAGS, &dpmac_cfg,
8202557c5a9SYogesh Gaur 			   &priv->dpmac_id);
821c919ab9eSPrabhakar Kushwaha 	if (err)
822c919ab9eSPrabhakar Kushwaha 		printf("dpmac_create() failed\n");
8239a696f56SPrabhakar Kushwaha 
8249a696f56SPrabhakar Kushwaha 	err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
8252557c5a9SYogesh Gaur 	if (err < 0) {
8269a696f56SPrabhakar Kushwaha 		printf("ldpaa_dpmac_version_check() failed: %d\n", err);
8272557c5a9SYogesh Gaur 		goto err_version_check;
8282557c5a9SYogesh Gaur 	}
8292557c5a9SYogesh Gaur 
8302557c5a9SYogesh Gaur 	err = dpmac_open(dflt_mc_io,
8312557c5a9SYogesh Gaur 			 MC_CMD_NO_FLAGS,
8322557c5a9SYogesh Gaur 			 priv->dpmac_id,
8332557c5a9SYogesh Gaur 			 &priv->dpmac_handle);
8342557c5a9SYogesh Gaur 	if (err < 0) {
8352557c5a9SYogesh Gaur 		printf("dpmac_open() failed: %d\n", err);
8362557c5a9SYogesh Gaur 		goto err_open;
8372557c5a9SYogesh Gaur 	}
8382557c5a9SYogesh Gaur 
8392557c5a9SYogesh Gaur 	return err;
8402557c5a9SYogesh Gaur 
8412557c5a9SYogesh Gaur err_open:
8422557c5a9SYogesh Gaur err_version_check:
8432557c5a9SYogesh Gaur 	dpmac_destroy(dflt_mc_io,
8442557c5a9SYogesh Gaur 		      dflt_dprc_handle,
8452557c5a9SYogesh Gaur 		      MC_CMD_NO_FLAGS, priv->dpmac_id);
8469a696f56SPrabhakar Kushwaha 
847c919ab9eSPrabhakar Kushwaha 	return err;
848c919ab9eSPrabhakar Kushwaha }
849c919ab9eSPrabhakar Kushwaha 
ldpaa_dpmac_bind(struct ldpaa_eth_priv * priv)850c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
851c919ab9eSPrabhakar Kushwaha {
852c919ab9eSPrabhakar Kushwaha 	int err = 0;
853c919ab9eSPrabhakar Kushwaha 	struct dprc_connection_cfg dprc_connection_cfg = {
854c919ab9eSPrabhakar Kushwaha 		/* If both rates are zero the connection */
855c919ab9eSPrabhakar Kushwaha 		/* will be configured in "best effort" mode. */
856c919ab9eSPrabhakar Kushwaha 		.committed_rate = 0,
857c919ab9eSPrabhakar Kushwaha 		.max_rate = 0
858c919ab9eSPrabhakar Kushwaha 	};
859c919ab9eSPrabhakar Kushwaha 
8605038d3e5SPrabhakar Kushwaha #ifdef DEBUG
8615038d3e5SPrabhakar Kushwaha 	struct dprc_endpoint dbg_endpoint;
8625038d3e5SPrabhakar Kushwaha 	int state = 0;
8635038d3e5SPrabhakar Kushwaha #endif
8645038d3e5SPrabhakar Kushwaha 
865c919ab9eSPrabhakar Kushwaha 	memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
866192bc694SBen Whitten 	strcpy(dpmac_endpoint.type, "dpmac");
867c919ab9eSPrabhakar Kushwaha 	dpmac_endpoint.id = priv->dpmac_id;
868c919ab9eSPrabhakar Kushwaha 
869c919ab9eSPrabhakar Kushwaha 	memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
870192bc694SBen Whitten 	strcpy(dpni_endpoint.type, "dpni");
871c919ab9eSPrabhakar Kushwaha 	dpni_endpoint.id = dflt_dpni->dpni_id;
872c919ab9eSPrabhakar Kushwaha 
873c919ab9eSPrabhakar Kushwaha 	err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
874c919ab9eSPrabhakar Kushwaha 			     dflt_dprc_handle,
875c919ab9eSPrabhakar Kushwaha 			     &dpmac_endpoint,
876c919ab9eSPrabhakar Kushwaha 			     &dpni_endpoint,
877c919ab9eSPrabhakar Kushwaha 			     &dprc_connection_cfg);
8785038d3e5SPrabhakar Kushwaha 	if (err)
8795038d3e5SPrabhakar Kushwaha 		printf("dprc_connect() failed\n");
8805038d3e5SPrabhakar Kushwaha 
8815038d3e5SPrabhakar Kushwaha #ifdef DEBUG
8825038d3e5SPrabhakar Kushwaha 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
8835038d3e5SPrabhakar Kushwaha 				    dflt_dprc_handle, &dpni_endpoint,
8845038d3e5SPrabhakar Kushwaha 				    &dbg_endpoint, &state);
8855038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
8865038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
8875038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC State= %d\n", __func__, state);
8885038d3e5SPrabhakar Kushwaha 
8895038d3e5SPrabhakar Kushwaha 	memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
8905038d3e5SPrabhakar Kushwaha 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
8915038d3e5SPrabhakar Kushwaha 				    dflt_dprc_handle, &dpmac_endpoint,
8925038d3e5SPrabhakar Kushwaha 				    &dbg_endpoint, &state);
8935038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
8945038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
8955038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI State= %d\n", __func__, state);
8965038d3e5SPrabhakar Kushwaha #endif
897c919ab9eSPrabhakar Kushwaha 	return err;
898c919ab9eSPrabhakar Kushwaha }
899c919ab9eSPrabhakar Kushwaha 
ldpaa_dpni_setup(struct ldpaa_eth_priv * priv)900c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
901c517771aSPrabhakar Kushwaha {
902c517771aSPrabhakar Kushwaha 	int err;
903c517771aSPrabhakar Kushwaha 
904c517771aSPrabhakar Kushwaha 	/* and get a handle for the DPNI this interface is associate with */
905c919ab9eSPrabhakar Kushwaha 	err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
906c919ab9eSPrabhakar Kushwaha 			&dflt_dpni->dpni_handle);
907c517771aSPrabhakar Kushwaha 	if (err) {
908c517771aSPrabhakar Kushwaha 		printf("dpni_open() failed\n");
909c517771aSPrabhakar Kushwaha 		goto err_open;
910c517771aSPrabhakar Kushwaha 	}
91187457d11SPrabhakar Kushwaha 	err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
912c919ab9eSPrabhakar Kushwaha 				  dflt_dpni->dpni_handle,
913c919ab9eSPrabhakar Kushwaha 				  &dflt_dpni->dpni_attrs);
914c517771aSPrabhakar Kushwaha 	if (err) {
915c517771aSPrabhakar Kushwaha 		printf("dpni_get_attributes() failed (err=%d)\n", err);
916c517771aSPrabhakar Kushwaha 		goto err_get_attr;
917c517771aSPrabhakar Kushwaha 	}
918c517771aSPrabhakar Kushwaha 
919c517771aSPrabhakar Kushwaha 	/* Configure our buffers' layout */
920c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
921c517771aSPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
92214480454SPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
92314480454SPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
924c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.pass_parser_result = true;
925c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.pass_frame_status = true;
926c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
92714480454SPrabhakar Kushwaha 	/* HW erratum mandates data alignment in multiples of 256 */
92814480454SPrabhakar Kushwaha 	dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
9292557c5a9SYogesh Gaur 
930c517771aSPrabhakar Kushwaha 	/* ...rx, ... */
9312557c5a9SYogesh Gaur 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
932c919ab9eSPrabhakar Kushwaha 				     dflt_dpni->dpni_handle,
9332557c5a9SYogesh Gaur 				     &dflt_dpni->buf_layout, DPNI_QUEUE_RX);
934c517771aSPrabhakar Kushwaha 	if (err) {
9352557c5a9SYogesh Gaur 		printf("dpni_set_buffer_layout() failed");
936c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
937c517771aSPrabhakar Kushwaha 	}
938c517771aSPrabhakar Kushwaha 
939c517771aSPrabhakar Kushwaha 	/* ... tx, ... */
94014480454SPrabhakar Kushwaha 	/* remove Rx-only options */
94114480454SPrabhakar Kushwaha 	dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
94214480454SPrabhakar Kushwaha 				      DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
9432557c5a9SYogesh Gaur 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
944c919ab9eSPrabhakar Kushwaha 				     dflt_dpni->dpni_handle,
9452557c5a9SYogesh Gaur 				     &dflt_dpni->buf_layout, DPNI_QUEUE_TX);
946c517771aSPrabhakar Kushwaha 	if (err) {
9472557c5a9SYogesh Gaur 		printf("dpni_set_buffer_layout() failed");
948c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
949c517771aSPrabhakar Kushwaha 	}
950c517771aSPrabhakar Kushwaha 
951c517771aSPrabhakar Kushwaha 	/* ... tx-confirm. */
952c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
9532557c5a9SYogesh Gaur 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
954c919ab9eSPrabhakar Kushwaha 				     dflt_dpni->dpni_handle,
9552557c5a9SYogesh Gaur 				     &dflt_dpni->buf_layout,
9562557c5a9SYogesh Gaur 				     DPNI_QUEUE_TX_CONFIRM);
957c517771aSPrabhakar Kushwaha 	if (err) {
9582557c5a9SYogesh Gaur 		printf("dpni_set_buffer_layout() failed");
959c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
960c517771aSPrabhakar Kushwaha 	}
961c517771aSPrabhakar Kushwaha 
962c517771aSPrabhakar Kushwaha 	/* Now that we've set our tx buffer layout, retrieve the minimum
963c517771aSPrabhakar Kushwaha 	 * required tx data offset.
964c517771aSPrabhakar Kushwaha 	 */
96587457d11SPrabhakar Kushwaha 	err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
966c919ab9eSPrabhakar Kushwaha 				      dflt_dpni->dpni_handle,
967c919ab9eSPrabhakar Kushwaha 				      &priv->tx_data_offset);
968c517771aSPrabhakar Kushwaha 	if (err) {
969c517771aSPrabhakar Kushwaha 		printf("dpni_get_tx_data_offset() failed\n");
970c517771aSPrabhakar Kushwaha 		goto err_data_offset;
971c517771aSPrabhakar Kushwaha 	}
972c517771aSPrabhakar Kushwaha 
973c517771aSPrabhakar Kushwaha 	/* Warn in case TX data offset is not multiple of 64 bytes. */
974c517771aSPrabhakar Kushwaha 	WARN_ON(priv->tx_data_offset % 64);
975c517771aSPrabhakar Kushwaha 
976c517771aSPrabhakar Kushwaha 	/* Accomodate SWA space. */
977c517771aSPrabhakar Kushwaha 	priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
978c517771aSPrabhakar Kushwaha 	debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
979c517771aSPrabhakar Kushwaha 
980c517771aSPrabhakar Kushwaha 	return 0;
981c517771aSPrabhakar Kushwaha 
982c517771aSPrabhakar Kushwaha err_data_offset:
983c517771aSPrabhakar Kushwaha err_buf_layout:
984c517771aSPrabhakar Kushwaha err_get_attr:
985c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
986c517771aSPrabhakar Kushwaha err_open:
987c517771aSPrabhakar Kushwaha 	return err;
988c517771aSPrabhakar Kushwaha }
989c517771aSPrabhakar Kushwaha 
ldpaa_dpni_bind(struct ldpaa_eth_priv * priv)990c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
991c517771aSPrabhakar Kushwaha {
992c517771aSPrabhakar Kushwaha 	struct dpni_pools_cfg pools_params;
9932557c5a9SYogesh Gaur 	struct dpni_queue tx_queue;
994c517771aSPrabhakar Kushwaha 	int err = 0;
995c517771aSPrabhakar Kushwaha 
99631a48cf4SPrabhakar Kushwaha 	memset(&pools_params, 0, sizeof(pools_params));
997c517771aSPrabhakar Kushwaha 	pools_params.num_dpbp = 1;
998c517771aSPrabhakar Kushwaha 	pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
999c517771aSPrabhakar Kushwaha 	pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
1000c919ab9eSPrabhakar Kushwaha 	err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
1001c919ab9eSPrabhakar Kushwaha 			     dflt_dpni->dpni_handle, &pools_params);
1002c517771aSPrabhakar Kushwaha 	if (err) {
1003c517771aSPrabhakar Kushwaha 		printf("dpni_set_pools() failed\n");
1004c517771aSPrabhakar Kushwaha 		return err;
1005c517771aSPrabhakar Kushwaha 	}
1006c517771aSPrabhakar Kushwaha 
10072557c5a9SYogesh Gaur 	memset(&tx_queue, 0, sizeof(struct dpni_queue));
1008c517771aSPrabhakar Kushwaha 
10092557c5a9SYogesh Gaur 	err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
10102557c5a9SYogesh Gaur 			     dflt_dpni->dpni_handle,
10112557c5a9SYogesh Gaur 			     DPNI_QUEUE_TX, 0, 0, &tx_queue);
10122557c5a9SYogesh Gaur 
1013c517771aSPrabhakar Kushwaha 	if (err) {
10142557c5a9SYogesh Gaur 		printf("dpni_set_queue() failed\n");
1015c517771aSPrabhakar Kushwaha 		return err;
1016c517771aSPrabhakar Kushwaha 	}
1017c517771aSPrabhakar Kushwaha 
10182557c5a9SYogesh Gaur 	err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS,
10196073548aSPrabhakar Kushwaha 					    dflt_dpni->dpni_handle,
10202557c5a9SYogesh Gaur 					    DPNI_CONF_DISABLE);
10216073548aSPrabhakar Kushwaha 	if (err) {
10222557c5a9SYogesh Gaur 		printf("dpni_set_tx_confirmation_mode() failed\n");
10236073548aSPrabhakar Kushwaha 		return err;
10246073548aSPrabhakar Kushwaha 	}
10256073548aSPrabhakar Kushwaha 
1026c517771aSPrabhakar Kushwaha 	return 0;
1027c517771aSPrabhakar Kushwaha }
1028c517771aSPrabhakar Kushwaha 
ldpaa_eth_netdev_init(struct eth_device * net_dev,phy_interface_t enet_if)1029c919ab9eSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
1030c919ab9eSPrabhakar Kushwaha 				 phy_interface_t enet_if)
1031c517771aSPrabhakar Kushwaha {
1032c517771aSPrabhakar Kushwaha 	int err;
1033c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
1034c517771aSPrabhakar Kushwaha 
1035c022ec03SPankaj Bansal 	snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id,
1036c919ab9eSPrabhakar Kushwaha 		 phy_interface_strings[enet_if]);
1037c517771aSPrabhakar Kushwaha 
1038c517771aSPrabhakar Kushwaha 	net_dev->iobase = 0;
1039c517771aSPrabhakar Kushwaha 	net_dev->init = ldpaa_eth_open;
1040c517771aSPrabhakar Kushwaha 	net_dev->halt = ldpaa_eth_stop;
1041c517771aSPrabhakar Kushwaha 	net_dev->send = ldpaa_eth_tx;
1042c517771aSPrabhakar Kushwaha 	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
1043c517771aSPrabhakar Kushwaha 
10446c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
10456c2b520aSPrabhakar Kushwaha 	err = init_phy(net_dev);
10466c2b520aSPrabhakar Kushwaha 	if (err < 0)
10476c2b520aSPrabhakar Kushwaha 		return err;
10486c2b520aSPrabhakar Kushwaha #endif
1049c517771aSPrabhakar Kushwaha 
1050c517771aSPrabhakar Kushwaha 	err = eth_register(net_dev);
1051c517771aSPrabhakar Kushwaha 	if (err < 0) {
1052c517771aSPrabhakar Kushwaha 		printf("eth_register() = %d\n", err);
1053c517771aSPrabhakar Kushwaha 		return err;
1054c517771aSPrabhakar Kushwaha 	}
1055c517771aSPrabhakar Kushwaha 
1056c517771aSPrabhakar Kushwaha 	return 0;
1057c517771aSPrabhakar Kushwaha }
1058c517771aSPrabhakar Kushwaha 
ldpaa_eth_init(int dpmac_id,phy_interface_t enet_if)1059c919ab9eSPrabhakar Kushwaha int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
1060c517771aSPrabhakar Kushwaha {
1061c517771aSPrabhakar Kushwaha 	struct eth_device		*net_dev = NULL;
1062c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv		*priv = NULL;
1063c517771aSPrabhakar Kushwaha 	int				err = 0;
1064c517771aSPrabhakar Kushwaha 
1065c517771aSPrabhakar Kushwaha 	/* Net device */
1066c517771aSPrabhakar Kushwaha 	net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
1067c517771aSPrabhakar Kushwaha 	if (!net_dev) {
1068c517771aSPrabhakar Kushwaha 		printf("eth_device malloc() failed\n");
1069c517771aSPrabhakar Kushwaha 		return -ENOMEM;
1070c517771aSPrabhakar Kushwaha 	}
1071c517771aSPrabhakar Kushwaha 	memset(net_dev, 0, sizeof(struct eth_device));
1072c517771aSPrabhakar Kushwaha 
1073c517771aSPrabhakar Kushwaha 	/* alloc the ldpaa ethernet private struct */
1074c517771aSPrabhakar Kushwaha 	priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1075c517771aSPrabhakar Kushwaha 	if (!priv) {
1076c517771aSPrabhakar Kushwaha 		printf("ldpaa_eth_priv malloc() failed\n");
1077c517771aSPrabhakar Kushwaha 		return -ENOMEM;
1078c517771aSPrabhakar Kushwaha 	}
1079c517771aSPrabhakar Kushwaha 	memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1080c517771aSPrabhakar Kushwaha 
1081c517771aSPrabhakar Kushwaha 	net_dev->priv = (void *)priv;
1082c517771aSPrabhakar Kushwaha 	priv->net_dev = (struct eth_device *)net_dev;
1083c919ab9eSPrabhakar Kushwaha 	priv->dpmac_id = dpmac_id;
1084c919ab9eSPrabhakar Kushwaha 	debug("%s dpmac_id=%d\n", __func__, dpmac_id);
1085c517771aSPrabhakar Kushwaha 
1086c919ab9eSPrabhakar Kushwaha 	err = ldpaa_eth_netdev_init(net_dev, enet_if);
1087c517771aSPrabhakar Kushwaha 	if (err)
1088c517771aSPrabhakar Kushwaha 		goto err_netdev_init;
1089c517771aSPrabhakar Kushwaha 
1090c517771aSPrabhakar Kushwaha 	debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1091c517771aSPrabhakar Kushwaha 	return 0;
1092c517771aSPrabhakar Kushwaha 
1093c517771aSPrabhakar Kushwaha err_netdev_init:
1094c517771aSPrabhakar Kushwaha 	free(priv);
1095c517771aSPrabhakar Kushwaha 	net_dev->priv = NULL;
1096c517771aSPrabhakar Kushwaha 	free(net_dev);
1097c517771aSPrabhakar Kushwaha 
1098c517771aSPrabhakar Kushwaha 	return err;
1099c517771aSPrabhakar Kushwaha }
1100