xref: /openbmc/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c (revision d75e81d9e05575e3f8471e618846565b15b30060)
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
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;
26c517771aSPrabhakar Kushwaha 
276c2b520aSPrabhakar Kushwaha 	bus = wriop_get_mdio(priv->dpmac_id);
286c2b520aSPrabhakar Kushwaha 	if (bus == NULL)
29c517771aSPrabhakar Kushwaha 		return 0;
306c2b520aSPrabhakar Kushwaha 
316c2b520aSPrabhakar Kushwaha 	phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id),
326c2b520aSPrabhakar Kushwaha 			     dev, wriop_get_enet_if(priv->dpmac_id));
336c2b520aSPrabhakar Kushwaha 	if (!phydev) {
346c2b520aSPrabhakar Kushwaha 		printf("Failed to connect\n");
356c2b520aSPrabhakar Kushwaha 		return -1;
36c517771aSPrabhakar Kushwaha 	}
37c517771aSPrabhakar Kushwaha 
38*d75e81d9SPankaj Bansal 	wriop_set_phy_dev(priv->dpmac_id, phydev);
396c2b520aSPrabhakar Kushwaha 
406c2b520aSPrabhakar Kushwaha 	return phy_config(phydev);
416c2b520aSPrabhakar Kushwaha }
426c2b520aSPrabhakar Kushwaha #endif
436c2b520aSPrabhakar Kushwaha 
445038d3e5SPrabhakar Kushwaha #ifdef DEBUG
452557c5a9SYogesh Gaur 
462557c5a9SYogesh Gaur #define DPNI_STATS_PER_PAGE 6
472557c5a9SYogesh Gaur 
482557c5a9SYogesh Gaur static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = {
492557c5a9SYogesh Gaur 	{
502557c5a9SYogesh Gaur 	"DPNI_CNT_ING_ALL_FRAMES",
512557c5a9SYogesh Gaur 	"DPNI_CNT_ING_ALL_BYTES",
522557c5a9SYogesh Gaur 	"DPNI_CNT_ING_MCAST_FRAMES",
532557c5a9SYogesh Gaur 	"DPNI_CNT_ING_MCAST_BYTES",
542557c5a9SYogesh Gaur 	"DPNI_CNT_ING_BCAST_FRAMES",
552557c5a9SYogesh Gaur 	"DPNI_CNT_ING_BCAST_BYTES",
562557c5a9SYogesh Gaur 	}, {
572557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_ALL_FRAMES",
582557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_ALL_BYTES",
592557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_MCAST_FRAMES",
602557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_MCAST_BYTES",
612557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_BCAST_FRAMES",
622557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_BCAST_BYTES",
632557c5a9SYogesh Gaur 	}, {
642557c5a9SYogesh Gaur 	"DPNI_CNT_ING_FILTERED_FRAMES",
652557c5a9SYogesh Gaur 	"DPNI_CNT_ING_DISCARDED_FRAMES",
662557c5a9SYogesh Gaur 	"DPNI_CNT_ING_NOBUFFER_DISCARDS",
672557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_DISCARDED_FRAMES",
682557c5a9SYogesh Gaur 	"DPNI_CNT_EGR_CNF_FRAMES",
692557c5a9SYogesh Gaur 	""
702557c5a9SYogesh Gaur 	},
712557c5a9SYogesh Gaur };
722557c5a9SYogesh Gaur 
732557c5a9SYogesh Gaur static void print_dpni_stats(const char *strings[],
742557c5a9SYogesh Gaur 			     struct dpni_statistics dpni_stats)
752557c5a9SYogesh Gaur {
762557c5a9SYogesh Gaur 	uint64_t *stat;
772557c5a9SYogesh Gaur 	int i;
782557c5a9SYogesh Gaur 
792557c5a9SYogesh Gaur 	stat = (uint64_t *)&dpni_stats;
802557c5a9SYogesh Gaur 	for (i = 0; i < DPNI_STATS_PER_PAGE; i++) {
812557c5a9SYogesh Gaur 		if (strcmp(strings[i], "\0") == 0)
822557c5a9SYogesh Gaur 			break;
832557c5a9SYogesh Gaur 		printf("%s= %llu\n", strings[i], *stat);
842557c5a9SYogesh Gaur 		stat++;
852557c5a9SYogesh Gaur 	}
862557c5a9SYogesh Gaur }
872557c5a9SYogesh Gaur 
885038d3e5SPrabhakar Kushwaha static void ldpaa_eth_get_dpni_counter(void)
895038d3e5SPrabhakar Kushwaha {
905038d3e5SPrabhakar Kushwaha 	int err = 0;
912557c5a9SYogesh Gaur 	unsigned int page = 0;
922557c5a9SYogesh Gaur 	struct dpni_statistics dpni_stats;
935038d3e5SPrabhakar Kushwaha 
942557c5a9SYogesh Gaur 	printf("DPNI counters ..\n");
952557c5a9SYogesh Gaur 	for (page = 0; page < 3; page++) {
962557c5a9SYogesh Gaur 		err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS,
972557c5a9SYogesh Gaur 					  dflt_dpni->dpni_handle, page,
982557c5a9SYogesh Gaur 					  &dpni_stats);
995038d3e5SPrabhakar Kushwaha 		if (err < 0) {
1002557c5a9SYogesh Gaur 			printf("dpni_get_statistics: failed:");
1012557c5a9SYogesh Gaur 			printf("%d for page[%d]\n", err, page);
1025038d3e5SPrabhakar Kushwaha 			return;
1035038d3e5SPrabhakar Kushwaha 		}
1042557c5a9SYogesh Gaur 		print_dpni_stats(dpni_statistics[page], dpni_stats);
1055038d3e5SPrabhakar Kushwaha 	}
1065038d3e5SPrabhakar Kushwaha }
10744b2036eSPrabhakar Kushwaha 
10844b2036eSPrabhakar Kushwaha static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev)
10944b2036eSPrabhakar Kushwaha {
11044b2036eSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
11144b2036eSPrabhakar Kushwaha 	int err = 0;
11244b2036eSPrabhakar Kushwaha 	u64 value;
11344b2036eSPrabhakar Kushwaha 
11444b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
11544b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
11644b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_BYTE,
11744b2036eSPrabhakar Kushwaha 		     &value);
11844b2036eSPrabhakar Kushwaha 	if (err < 0) {
11944b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
12044b2036eSPrabhakar Kushwaha 		return;
12144b2036eSPrabhakar Kushwaha 	}
1222557c5a9SYogesh Gaur 	printf("\nDPMAC counters ..\n");
12344b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
12444b2036eSPrabhakar Kushwaha 
12544b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
12644b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
12744b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_FRAME_DISCARD,
12844b2036eSPrabhakar Kushwaha 		     &value);
12944b2036eSPrabhakar Kushwaha 	if (err < 0) {
13044b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
13144b2036eSPrabhakar Kushwaha 		return;
13244b2036eSPrabhakar Kushwaha 	}
13344b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value);
13444b2036eSPrabhakar Kushwaha 
13544b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
13644b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
13744b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_ALIGN_ERR,
13844b2036eSPrabhakar Kushwaha 		     &value);
13944b2036eSPrabhakar Kushwaha 	if (err < 0) {
14044b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
14144b2036eSPrabhakar Kushwaha 		return;
14244b2036eSPrabhakar Kushwaha 	}
14344b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value);
14444b2036eSPrabhakar Kushwaha 
14544b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
14644b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
14744b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_BYTE,
14844b2036eSPrabhakar Kushwaha 		     &value);
14944b2036eSPrabhakar Kushwaha 	if (err < 0) {
15044b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
15144b2036eSPrabhakar Kushwaha 		return;
15244b2036eSPrabhakar Kushwaha 	}
15344b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
15444b2036eSPrabhakar Kushwaha 
15544b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
15644b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
15744b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_ERR_FRAME,
15844b2036eSPrabhakar Kushwaha 		     &value);
15944b2036eSPrabhakar Kushwaha 	if (err < 0) {
16044b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
16144b2036eSPrabhakar Kushwaha 		return;
16244b2036eSPrabhakar Kushwaha 	}
16344b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value);
16444b2036eSPrabhakar Kushwaha 
16544b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
16644b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
16744b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_EGR_BYTE ,
16844b2036eSPrabhakar Kushwaha 		     &value);
16944b2036eSPrabhakar Kushwaha 	if (err < 0) {
17044b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
17144b2036eSPrabhakar Kushwaha 		return;
17244b2036eSPrabhakar Kushwaha 	}
17344b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_EGR_BYTE =%lld\n", value);
17444b2036eSPrabhakar Kushwaha 
17544b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
17644b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
17744b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_EGR_ERR_FRAME ,
17844b2036eSPrabhakar Kushwaha 		     &value);
17944b2036eSPrabhakar Kushwaha 	if (err < 0) {
18044b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
18144b2036eSPrabhakar Kushwaha 		return;
18244b2036eSPrabhakar Kushwaha 	}
18344b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
18444b2036eSPrabhakar Kushwaha }
1855038d3e5SPrabhakar Kushwaha #endif
1865038d3e5SPrabhakar Kushwaha 
187c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
188c517771aSPrabhakar Kushwaha 			 const struct dpaa_fd *fd)
189c517771aSPrabhakar Kushwaha {
190c517771aSPrabhakar Kushwaha 	u64 fd_addr;
191c517771aSPrabhakar Kushwaha 	uint16_t fd_offset;
192c517771aSPrabhakar Kushwaha 	uint32_t fd_length;
193c517771aSPrabhakar Kushwaha 	struct ldpaa_fas *fas;
194c517771aSPrabhakar Kushwaha 	uint32_t status, err;
19556c57cf7SPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
19656c57cf7SPrabhakar Kushwaha 	u32 time_start;
197c517771aSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
198c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
199c517771aSPrabhakar Kushwaha 
200c517771aSPrabhakar Kushwaha 	fd_addr = ldpaa_fd_get_addr(fd);
201c517771aSPrabhakar Kushwaha 	fd_offset = ldpaa_fd_get_offset(fd);
202c517771aSPrabhakar Kushwaha 	fd_length = ldpaa_fd_get_len(fd);
203c517771aSPrabhakar Kushwaha 
204c517771aSPrabhakar Kushwaha 	debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
205c517771aSPrabhakar Kushwaha 
206c517771aSPrabhakar Kushwaha 	if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
207c517771aSPrabhakar Kushwaha 		/* Read the frame annotation status word and check for errors */
208c517771aSPrabhakar Kushwaha 		fas = (struct ldpaa_fas *)
209c517771aSPrabhakar Kushwaha 				((uint8_t *)(fd_addr) +
210c919ab9eSPrabhakar Kushwaha 				dflt_dpni->buf_layout.private_data_size);
211c517771aSPrabhakar Kushwaha 		status = le32_to_cpu(fas->status);
212c517771aSPrabhakar Kushwaha 		if (status & LDPAA_ETH_RX_ERR_MASK) {
213c517771aSPrabhakar Kushwaha 			printf("Rx frame error(s): 0x%08x\n",
214c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_ERR_MASK);
215c517771aSPrabhakar Kushwaha 			goto error;
216c517771aSPrabhakar Kushwaha 		} else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
217c517771aSPrabhakar Kushwaha 			printf("Unsupported feature in bitmask: 0x%08x\n",
218c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_UNSUPP_MASK);
219c517771aSPrabhakar Kushwaha 			goto error;
220c517771aSPrabhakar Kushwaha 		}
221c517771aSPrabhakar Kushwaha 	}
222c517771aSPrabhakar Kushwaha 
223c517771aSPrabhakar Kushwaha 	debug("Rx frame: To Upper layer\n");
224c517771aSPrabhakar Kushwaha 	net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
225c517771aSPrabhakar Kushwaha 				    fd_length);
226c517771aSPrabhakar Kushwaha 
227c517771aSPrabhakar Kushwaha error:
2285753b0f1SPrabhakar Kushwaha 	flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
229c517771aSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
230c517771aSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
23156c57cf7SPrabhakar Kushwaha 	time_start = get_timer(0);
232c517771aSPrabhakar Kushwaha 	do {
233c517771aSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
234c517771aSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
23556c57cf7SPrabhakar Kushwaha 	} while (get_timer(time_start) < timeo && err == -EBUSY);
23656c57cf7SPrabhakar Kushwaha 
23756c57cf7SPrabhakar Kushwaha 	if (err == -EBUSY)
23856c57cf7SPrabhakar Kushwaha 		printf("Rx frame: QBMAN buffer release fails\n");
23956c57cf7SPrabhakar Kushwaha 
240c517771aSPrabhakar Kushwaha 	return;
241c517771aSPrabhakar Kushwaha }
242c517771aSPrabhakar Kushwaha 
243c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
244c517771aSPrabhakar Kushwaha {
245c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
246c517771aSPrabhakar Kushwaha 	const struct ldpaa_dq *dq;
247c517771aSPrabhakar Kushwaha 	const struct dpaa_fd *fd;
248b4c3a35dSPrabhakar Kushwaha 	int i = 5, err = 0, status;
249b4c3a35dSPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
250b4c3a35dSPrabhakar Kushwaha 	u32 time_start;
251c517771aSPrabhakar Kushwaha 	static struct qbman_pull_desc pulldesc;
252c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
253c517771aSPrabhakar Kushwaha 
2545753b0f1SPrabhakar Kushwaha 	while (--i) {
255c517771aSPrabhakar Kushwaha 		qbman_pull_desc_clear(&pulldesc);
256c517771aSPrabhakar Kushwaha 		qbman_pull_desc_set_numframes(&pulldesc, 1);
257c517771aSPrabhakar Kushwaha 		qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
258c517771aSPrabhakar Kushwaha 
259c517771aSPrabhakar Kushwaha 		err = qbman_swp_pull(swp, &pulldesc);
260c517771aSPrabhakar Kushwaha 		if (err < 0) {
261c517771aSPrabhakar Kushwaha 			printf("Dequeue frames error:0x%08x\n", err);
262c517771aSPrabhakar Kushwaha 			continue;
263c517771aSPrabhakar Kushwaha 		}
264c517771aSPrabhakar Kushwaha 
265b4c3a35dSPrabhakar Kushwaha 		time_start = get_timer(0);
2665753b0f1SPrabhakar Kushwaha 
267b4c3a35dSPrabhakar Kushwaha 		 do {
268b4c3a35dSPrabhakar Kushwaha 			dq = qbman_swp_dqrr_next(swp);
269b4c3a35dSPrabhakar Kushwaha 		} while (get_timer(time_start) < timeo && !dq);
2705753b0f1SPrabhakar Kushwaha 
271c517771aSPrabhakar Kushwaha 		if (dq) {
272c517771aSPrabhakar Kushwaha 			/* Check for valid frame. If not sent a consume
273c517771aSPrabhakar Kushwaha 			 * confirmation to QBMAN otherwise give it to NADK
274c517771aSPrabhakar Kushwaha 			 * application and then send consume confirmation to
275c517771aSPrabhakar Kushwaha 			 * QBMAN.
276c517771aSPrabhakar Kushwaha 			 */
277c517771aSPrabhakar Kushwaha 			status = (uint8_t)ldpaa_dq_flags(dq);
278c517771aSPrabhakar Kushwaha 			if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
279c517771aSPrabhakar Kushwaha 				debug("Dequeue RX frames:");
280c517771aSPrabhakar Kushwaha 				debug("No frame delivered\n");
281c517771aSPrabhakar Kushwaha 
282c517771aSPrabhakar Kushwaha 				qbman_swp_dqrr_consume(swp, dq);
2830c7c87a4SPrabhakar Kushwaha 				continue;
284c517771aSPrabhakar Kushwaha 			}
285c517771aSPrabhakar Kushwaha 
286c517771aSPrabhakar Kushwaha 			fd = ldpaa_dq_fd(dq);
287c517771aSPrabhakar Kushwaha 
288c517771aSPrabhakar Kushwaha 			/* Obtain FD and process it */
289c517771aSPrabhakar Kushwaha 			ldpaa_eth_rx(priv, fd);
290c517771aSPrabhakar Kushwaha 			qbman_swp_dqrr_consume(swp, dq);
291c517771aSPrabhakar Kushwaha 			break;
292b4c3a35dSPrabhakar Kushwaha 		} else {
293b4c3a35dSPrabhakar Kushwaha 			err = -ENODATA;
294b4c3a35dSPrabhakar Kushwaha 			debug("No DQRR entries\n");
295b4c3a35dSPrabhakar Kushwaha 			break;
296c517771aSPrabhakar Kushwaha 		}
297c517771aSPrabhakar Kushwaha 	}
298c517771aSPrabhakar Kushwaha 
299c517771aSPrabhakar Kushwaha 	return err;
300c517771aSPrabhakar Kushwaha }
301c517771aSPrabhakar Kushwaha 
302c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
303c517771aSPrabhakar Kushwaha {
304c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
305c517771aSPrabhakar Kushwaha 	struct dpaa_fd fd;
306c517771aSPrabhakar Kushwaha 	u64 buffer_start;
307c517771aSPrabhakar Kushwaha 	int data_offset, err;
308e48df52bSPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
309e48df52bSPrabhakar Kushwaha 	u32 time_start;
310c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
311c517771aSPrabhakar Kushwaha 	struct qbman_eq_desc ed;
312e48df52bSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
313c517771aSPrabhakar Kushwaha 
314c517771aSPrabhakar Kushwaha 	/* Setup the FD fields */
315c517771aSPrabhakar Kushwaha 	memset(&fd, 0, sizeof(fd));
316c517771aSPrabhakar Kushwaha 
317c517771aSPrabhakar Kushwaha 	data_offset = priv->tx_data_offset;
318c517771aSPrabhakar Kushwaha 
319c517771aSPrabhakar Kushwaha 	do {
320c517771aSPrabhakar Kushwaha 		err = qbman_swp_acquire(dflt_dpio->sw_portal,
321c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
322c517771aSPrabhakar Kushwaha 					&buffer_start, 1);
323c517771aSPrabhakar Kushwaha 	} while (err == -EBUSY);
324c517771aSPrabhakar Kushwaha 
3255e9445daSAshish Kumar 	if (err <= 0) {
326c517771aSPrabhakar Kushwaha 		printf("qbman_swp_acquire() failed\n");
327c517771aSPrabhakar Kushwaha 		return -ENOMEM;
328c517771aSPrabhakar Kushwaha 	}
329c517771aSPrabhakar Kushwaha 
330c517771aSPrabhakar Kushwaha 	debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
331c517771aSPrabhakar Kushwaha 
332c517771aSPrabhakar Kushwaha 	memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
333c517771aSPrabhakar Kushwaha 
3345753b0f1SPrabhakar Kushwaha 	flush_dcache_range(buffer_start, buffer_start +
3355753b0f1SPrabhakar Kushwaha 					LDPAA_ETH_RX_BUFFER_SIZE);
336c517771aSPrabhakar Kushwaha 
337c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_addr(&fd, (u64)buffer_start);
338c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
339c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
340c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_len(&fd, len);
341c517771aSPrabhakar Kushwaha 
342c517771aSPrabhakar Kushwaha 	fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
343c517771aSPrabhakar Kushwaha 				LDPAA_FD_CTRL_PTV1;
344c517771aSPrabhakar Kushwaha 
345c517771aSPrabhakar Kushwaha 	qbman_eq_desc_clear(&ed);
346c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_no_orp(&ed, 0);
347c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
348e48df52bSPrabhakar Kushwaha 
349e48df52bSPrabhakar Kushwaha 	time_start = get_timer(0);
350e48df52bSPrabhakar Kushwaha 
351e48df52bSPrabhakar Kushwaha 	while (get_timer(time_start) < timeo) {
352e48df52bSPrabhakar Kushwaha 		err = qbman_swp_enqueue(swp, &ed,
353e48df52bSPrabhakar Kushwaha 				(const struct qbman_fd *)(&fd));
354e48df52bSPrabhakar Kushwaha 		if (err != -EBUSY)
355e48df52bSPrabhakar Kushwaha 			break;
356e48df52bSPrabhakar Kushwaha 	}
357e48df52bSPrabhakar Kushwaha 
358e48df52bSPrabhakar Kushwaha 	if (err < 0) {
359c517771aSPrabhakar Kushwaha 		printf("error enqueueing Tx frame\n");
360e48df52bSPrabhakar Kushwaha 		goto error;
361e48df52bSPrabhakar Kushwaha 	}
362c517771aSPrabhakar Kushwaha 
363c517771aSPrabhakar Kushwaha 	return err;
364e48df52bSPrabhakar Kushwaha 
365e48df52bSPrabhakar Kushwaha error:
366e48df52bSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
367e48df52bSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
368e48df52bSPrabhakar Kushwaha 	time_start = get_timer(0);
369e48df52bSPrabhakar Kushwaha 	do {
370e48df52bSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
371e48df52bSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
372e48df52bSPrabhakar Kushwaha 	} while (get_timer(time_start) < timeo && err == -EBUSY);
373e48df52bSPrabhakar Kushwaha 
374e48df52bSPrabhakar Kushwaha 	if (err == -EBUSY)
375e48df52bSPrabhakar Kushwaha 		printf("TX data: QBMAN buffer release fails\n");
376e48df52bSPrabhakar Kushwaha 
377e48df52bSPrabhakar Kushwaha 	return err;
378c517771aSPrabhakar Kushwaha }
379c517771aSPrabhakar Kushwaha 
380c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
381c517771aSPrabhakar Kushwaha {
382c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
383c919ab9eSPrabhakar Kushwaha 	struct dpmac_link_state	dpmac_link_state = { 0 };
3845038d3e5SPrabhakar Kushwaha #ifdef DEBUG
3855038d3e5SPrabhakar Kushwaha 	struct dpni_link_state link_state;
3865038d3e5SPrabhakar Kushwaha #endif
3876c2b520aSPrabhakar Kushwaha 	int err = 0;
3886c2b520aSPrabhakar Kushwaha 	struct mii_dev *bus;
3896c2b520aSPrabhakar Kushwaha 	phy_interface_t enet_if;
3902557c5a9SYogesh Gaur 	struct dpni_queue d_queue;
391*d75e81d9SPankaj Bansal 	struct phy_device *phydev = NULL;
392c517771aSPrabhakar Kushwaha 
393c517771aSPrabhakar Kushwaha 	if (net_dev->state == ETH_STATE_ACTIVE)
394c517771aSPrabhakar Kushwaha 		return 0;
395c517771aSPrabhakar Kushwaha 
396c919ab9eSPrabhakar Kushwaha 	if (get_mc_boot_status() != 0) {
397c919ab9eSPrabhakar Kushwaha 		printf("ERROR (MC is not booted)\n");
398c919ab9eSPrabhakar Kushwaha 		return -ENODEV;
399c919ab9eSPrabhakar Kushwaha 	}
400c919ab9eSPrabhakar Kushwaha 
401c919ab9eSPrabhakar Kushwaha 	if (get_dpl_apply_status() == 0) {
402c919ab9eSPrabhakar Kushwaha 		printf("ERROR (DPL is deployed. No device available)\n");
403c919ab9eSPrabhakar Kushwaha 		return -ENODEV;
404c919ab9eSPrabhakar Kushwaha 	}
4056c2b520aSPrabhakar Kushwaha 
406c919ab9eSPrabhakar Kushwaha 	/* DPMAC initialization */
407c919ab9eSPrabhakar Kushwaha 	err = ldpaa_dpmac_setup(priv);
408c919ab9eSPrabhakar Kushwaha 	if (err < 0)
409c919ab9eSPrabhakar Kushwaha 		goto err_dpmac_setup;
410c919ab9eSPrabhakar Kushwaha 
4116c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
412*d75e81d9SPankaj Bansal 	phydev = wriop_get_phy_dev(priv->dpmac_id);
413*d75e81d9SPankaj Bansal 	if (phydev) {
414*d75e81d9SPankaj Bansal 		err = phy_startup(phydev);
4156c2b520aSPrabhakar Kushwaha 		if (err) {
4166c2b520aSPrabhakar Kushwaha 			printf("%s: Could not initialize\n",
417*d75e81d9SPankaj Bansal 			       phydev->dev->name);
418afd6c6b4SPankaj Bansal 			goto err_dpmac_bind;
4196c2b520aSPrabhakar Kushwaha 		}
420b7401d09SPriyanka Jain 	}
4216c2b520aSPrabhakar Kushwaha #else
422*d75e81d9SPankaj Bansal 	phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
423*d75e81d9SPankaj Bansal 	memset(phydev, 0, sizeof(struct phy_device));
424*d75e81d9SPankaj Bansal 	wriop_set_phy_dev(priv->dpmac_id, phydev);
4256c2b520aSPrabhakar Kushwaha 
426*d75e81d9SPankaj Bansal 	phydev->speed = SPEED_1000;
427*d75e81d9SPankaj Bansal 	phydev->link = 1;
428*d75e81d9SPankaj Bansal 	phydev->duplex = DUPLEX_FULL;
4296c2b520aSPrabhakar Kushwaha #endif
4306c2b520aSPrabhakar Kushwaha 
4316c2b520aSPrabhakar Kushwaha 	bus = wriop_get_mdio(priv->dpmac_id);
4326c2b520aSPrabhakar Kushwaha 	enet_if = wriop_get_enet_if(priv->dpmac_id);
4336c2b520aSPrabhakar Kushwaha 	if ((bus == NULL) &&
4346c2b520aSPrabhakar Kushwaha 	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
435*d75e81d9SPankaj Bansal 		phydev = (struct phy_device *)
4366c2b520aSPrabhakar Kushwaha 				malloc(sizeof(struct phy_device));
437*d75e81d9SPankaj Bansal 		memset(phydev, 0, sizeof(struct phy_device));
438*d75e81d9SPankaj Bansal 		wriop_set_phy_dev(priv->dpmac_id, phydev);
4396c2b520aSPrabhakar Kushwaha 
440*d75e81d9SPankaj Bansal 		phydev->speed = SPEED_10000;
441*d75e81d9SPankaj Bansal 		phydev->link = 1;
442*d75e81d9SPankaj Bansal 		phydev->duplex = DUPLEX_FULL;
4436c2b520aSPrabhakar Kushwaha 	}
4446c2b520aSPrabhakar Kushwaha 
445*d75e81d9SPankaj Bansal 	if (!phydev->link) {
446*d75e81d9SPankaj Bansal 		printf("%s: No link.\n", phydev->dev->name);
4476c2b520aSPrabhakar Kushwaha 		err = -1;
448afd6c6b4SPankaj Bansal 		goto err_dpmac_bind;
4496c2b520aSPrabhakar Kushwaha 	}
4506c2b520aSPrabhakar Kushwaha 
451c919ab9eSPrabhakar Kushwaha 	/* DPMAC binding DPNI */
452c919ab9eSPrabhakar Kushwaha 	err = ldpaa_dpmac_bind(priv);
453c919ab9eSPrabhakar Kushwaha 	if (err)
454afd6c6b4SPankaj Bansal 		goto err_dpmac_bind;
455c919ab9eSPrabhakar Kushwaha 
456c517771aSPrabhakar Kushwaha 	/* DPNI initialization */
457c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_setup(priv);
458c517771aSPrabhakar Kushwaha 	if (err < 0)
459c517771aSPrabhakar Kushwaha 		goto err_dpni_setup;
460c517771aSPrabhakar Kushwaha 
461c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_setup();
462c517771aSPrabhakar Kushwaha 	if (err < 0)
463c517771aSPrabhakar Kushwaha 		goto err_dpbp_setup;
464c517771aSPrabhakar Kushwaha 
465c517771aSPrabhakar Kushwaha 	/* DPNI binding DPBP */
466c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_bind(priv);
467c517771aSPrabhakar Kushwaha 	if (err)
468c919ab9eSPrabhakar Kushwaha 		goto err_dpni_bind;
469c517771aSPrabhakar Kushwaha 
4707b2edb8bSPrabhakar Kushwaha 	err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
471c919ab9eSPrabhakar Kushwaha 				dflt_dpni->dpni_handle, net_dev->enetaddr);
472c517771aSPrabhakar Kushwaha 	if (err) {
4737b2edb8bSPrabhakar Kushwaha 		printf("dpni_add_mac_addr() failed\n");
474c517771aSPrabhakar Kushwaha 		return err;
475c517771aSPrabhakar Kushwaha 	}
476c517771aSPrabhakar Kushwaha 
477c919ab9eSPrabhakar Kushwaha 	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
478c517771aSPrabhakar Kushwaha 	if (err < 0) {
479c517771aSPrabhakar Kushwaha 		printf("dpni_enable() failed\n");
480c517771aSPrabhakar Kushwaha 		return err;
481c517771aSPrabhakar Kushwaha 	}
482c517771aSPrabhakar Kushwaha 
483*d75e81d9SPankaj Bansal 	dpmac_link_state.rate = phydev->speed;
4846c2b520aSPrabhakar Kushwaha 
485*d75e81d9SPankaj Bansal 	if (phydev->autoneg == AUTONEG_DISABLE)
4866c2b520aSPrabhakar Kushwaha 		dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
4876c2b520aSPrabhakar Kushwaha 	else
4886c2b520aSPrabhakar Kushwaha 		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
4896c2b520aSPrabhakar Kushwaha 
490*d75e81d9SPankaj Bansal 	if (phydev->duplex == DUPLEX_HALF)
4916c2b520aSPrabhakar Kushwaha 		dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
4926c2b520aSPrabhakar Kushwaha 
493*d75e81d9SPankaj Bansal 	dpmac_link_state.up = phydev->link;
4946c2b520aSPrabhakar Kushwaha 
495c919ab9eSPrabhakar Kushwaha 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
496c919ab9eSPrabhakar Kushwaha 				  priv->dpmac_handle, &dpmac_link_state);
497c919ab9eSPrabhakar Kushwaha 	if (err < 0) {
498c919ab9eSPrabhakar Kushwaha 		printf("dpmac_set_link_state() failed\n");
499c919ab9eSPrabhakar Kushwaha 		return err;
500c919ab9eSPrabhakar Kushwaha 	}
5015038d3e5SPrabhakar Kushwaha 
5025038d3e5SPrabhakar Kushwaha #ifdef DEBUG
5032557c5a9SYogesh Gaur 	printf("DPMAC link status: %d - ", dpmac_link_state.up);
5042557c5a9SYogesh Gaur 	dpmac_link_state.up == 0 ? printf("down\n") :
5052557c5a9SYogesh Gaur 	dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n");
5062557c5a9SYogesh Gaur 
5075038d3e5SPrabhakar Kushwaha 	err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
5085038d3e5SPrabhakar Kushwaha 				  dflt_dpni->dpni_handle, &link_state);
5095038d3e5SPrabhakar Kushwaha 	if (err < 0) {
5105038d3e5SPrabhakar Kushwaha 		printf("dpni_get_link_state() failed\n");
5115038d3e5SPrabhakar Kushwaha 		return err;
5125038d3e5SPrabhakar Kushwaha 	}
5135038d3e5SPrabhakar Kushwaha 
5142557c5a9SYogesh Gaur 	printf("DPNI link status: %d - ", link_state.up);
5155038d3e5SPrabhakar Kushwaha 	link_state.up == 0 ? printf("down\n") :
5165038d3e5SPrabhakar Kushwaha 	link_state.up == 1 ? printf("up\n") : printf("error state\n");
5175038d3e5SPrabhakar Kushwaha #endif
5185038d3e5SPrabhakar Kushwaha 
5192557c5a9SYogesh Gaur 	memset(&d_queue, 0, sizeof(struct dpni_queue));
5202557c5a9SYogesh Gaur 	err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
5212557c5a9SYogesh Gaur 			     dflt_dpni->dpni_handle, DPNI_QUEUE_RX,
5222557c5a9SYogesh Gaur 			     0, 0, &d_queue);
523c517771aSPrabhakar Kushwaha 	if (err) {
5242557c5a9SYogesh Gaur 		printf("dpni_get_queue failed\n");
5252557c5a9SYogesh Gaur 		goto err_get_queue;
526c517771aSPrabhakar Kushwaha 	}
527c517771aSPrabhakar Kushwaha 
5282557c5a9SYogesh Gaur 	priv->rx_dflt_fqid = d_queue.fqid;
529c517771aSPrabhakar Kushwaha 
530c919ab9eSPrabhakar Kushwaha 	err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
53187457d11SPrabhakar Kushwaha 			    &priv->tx_qdid);
532c517771aSPrabhakar Kushwaha 	if (err) {
533c517771aSPrabhakar Kushwaha 		printf("dpni_get_qdid() failed\n");
534c517771aSPrabhakar Kushwaha 		goto err_qdid;
535c517771aSPrabhakar Kushwaha 	}
536c517771aSPrabhakar Kushwaha 
537*d75e81d9SPankaj Bansal 	return phydev->link;
538c517771aSPrabhakar Kushwaha 
539c517771aSPrabhakar Kushwaha err_qdid:
5402557c5a9SYogesh Gaur err_get_queue:
541c919ab9eSPrabhakar Kushwaha 	dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
542c919ab9eSPrabhakar Kushwaha err_dpni_bind:
543c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
544c517771aSPrabhakar Kushwaha err_dpbp_setup:
545c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
546c517771aSPrabhakar Kushwaha err_dpni_setup:
547afd6c6b4SPankaj Bansal err_dpmac_bind:
5482557c5a9SYogesh Gaur 	dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
5492557c5a9SYogesh Gaur 	dpmac_destroy(dflt_mc_io,
5502557c5a9SYogesh Gaur 		      dflt_dprc_handle,
5512557c5a9SYogesh Gaur 		      MC_CMD_NO_FLAGS, priv->dpmac_id);
552c919ab9eSPrabhakar Kushwaha err_dpmac_setup:
553c517771aSPrabhakar Kushwaha 	return err;
554c517771aSPrabhakar Kushwaha }
555c517771aSPrabhakar Kushwaha 
556c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev)
557c517771aSPrabhakar Kushwaha {
558c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
559c517771aSPrabhakar Kushwaha 	int err = 0;
5606c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
5616c2b520aSPrabhakar Kushwaha 	struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
5626c2b520aSPrabhakar Kushwaha #endif
563*d75e81d9SPankaj Bansal 	struct phy_device *phydev = NULL;
564c517771aSPrabhakar Kushwaha 
5655753b0f1SPrabhakar Kushwaha 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
5665753b0f1SPrabhakar Kushwaha 	    (net_dev->state == ETH_STATE_INIT))
567c517771aSPrabhakar Kushwaha 		return;
568c919ab9eSPrabhakar Kushwaha 
5695038d3e5SPrabhakar Kushwaha #ifdef DEBUG
5705038d3e5SPrabhakar Kushwaha 	ldpaa_eth_get_dpni_counter();
57144b2036eSPrabhakar Kushwaha 	ldpaa_eth_get_dpmac_counter(net_dev);
5725038d3e5SPrabhakar Kushwaha #endif
5735038d3e5SPrabhakar Kushwaha 
574c919ab9eSPrabhakar Kushwaha 	err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
575c919ab9eSPrabhakar Kushwaha 			      dflt_dprc_handle, &dpmac_endpoint);
576c919ab9eSPrabhakar Kushwaha 	if (err < 0)
577c919ab9eSPrabhakar Kushwaha 		printf("dprc_disconnect() failed dpmac_endpoint\n");
578c919ab9eSPrabhakar Kushwaha 
5792557c5a9SYogesh Gaur 	err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
5802557c5a9SYogesh Gaur 	if (err < 0)
5812557c5a9SYogesh Gaur 		printf("dpmac_close() failed\n");
5822557c5a9SYogesh Gaur 
5832557c5a9SYogesh Gaur 	err = dpmac_destroy(dflt_mc_io,
5842557c5a9SYogesh Gaur 			    dflt_dprc_handle,
5852557c5a9SYogesh Gaur 			    MC_CMD_NO_FLAGS,
5862557c5a9SYogesh Gaur 			    priv->dpmac_id);
587c919ab9eSPrabhakar Kushwaha 	if (err < 0)
588c919ab9eSPrabhakar Kushwaha 		printf("dpmac_destroy() failed\n");
589c919ab9eSPrabhakar Kushwaha 
590c517771aSPrabhakar Kushwaha 	/* Stop Tx and Rx traffic */
591c919ab9eSPrabhakar Kushwaha 	err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
592c517771aSPrabhakar Kushwaha 	if (err < 0)
593c517771aSPrabhakar Kushwaha 		printf("dpni_disable() failed\n");
594c517771aSPrabhakar Kushwaha 
595c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
596*d75e81d9SPankaj Bansal 	phydev = wriop_get_phy_dev(priv->dpmac_id);
597*d75e81d9SPankaj Bansal 	if (phydev && bus) {
598*d75e81d9SPankaj Bansal 		phy_shutdown(phydev);
599*d75e81d9SPankaj Bansal 	} else {
600*d75e81d9SPankaj Bansal 		free(phydev);
601*d75e81d9SPankaj Bansal 		wriop_set_phy_dev(priv->dpmac_id, NULL);
602a5fe87e8SPrabhakar Kushwaha 	}
603c517771aSPrabhakar Kushwaha #endif
604c517771aSPrabhakar Kushwaha 
6052557c5a9SYogesh Gaur 	/* Free DPBP handle and reset. */
606c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
6072557c5a9SYogesh Gaur 
608c919ab9eSPrabhakar Kushwaha 	dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
6092557c5a9SYogesh Gaur 	if (err < 0)
6102557c5a9SYogesh Gaur 		printf("dpni_reset() failed\n");
6112557c5a9SYogesh Gaur 
612c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
6132557c5a9SYogesh Gaur 	if (err < 0)
6142557c5a9SYogesh Gaur 		printf("dpni_close() failed\n");
615c517771aSPrabhakar Kushwaha }
616c517771aSPrabhakar Kushwaha 
617c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count)
618c517771aSPrabhakar Kushwaha {
619c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
620c517771aSPrabhakar Kushwaha 	void *addr;
621c517771aSPrabhakar Kushwaha 	int ret, i;
622c517771aSPrabhakar Kushwaha 
623c517771aSPrabhakar Kushwaha 	BUG_ON(count > 7);
624c517771aSPrabhakar Kushwaha 
625c517771aSPrabhakar Kushwaha 	do {
626c517771aSPrabhakar Kushwaha 		ret = qbman_swp_acquire(dflt_dpio->sw_portal,
627c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
628c517771aSPrabhakar Kushwaha 					buf_array, count);
629c517771aSPrabhakar Kushwaha 		if (ret < 0) {
630c517771aSPrabhakar Kushwaha 			printf("qbman_swp_acquire() failed\n");
631c517771aSPrabhakar Kushwaha 			return;
632c517771aSPrabhakar Kushwaha 		}
633c517771aSPrabhakar Kushwaha 		for (i = 0; i < ret; i++) {
634c517771aSPrabhakar Kushwaha 			addr = (void *)buf_array[i];
635c517771aSPrabhakar Kushwaha 			debug("Free: buffer addr =0x%p\n", addr);
636c517771aSPrabhakar Kushwaha 			free(addr);
637c517771aSPrabhakar Kushwaha 		}
638c517771aSPrabhakar Kushwaha 	} while (ret);
639c517771aSPrabhakar Kushwaha }
640c517771aSPrabhakar Kushwaha 
641c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void)
642c517771aSPrabhakar Kushwaha {
643c517771aSPrabhakar Kushwaha 	int i;
644c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
645c517771aSPrabhakar Kushwaha 		ldpaa_dpbp_drain_cnt(7);
646c517771aSPrabhakar Kushwaha }
647c517771aSPrabhakar Kushwaha 
648c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid)
649c517771aSPrabhakar Kushwaha {
650c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
651c517771aSPrabhakar Kushwaha 	u8 *addr;
652c517771aSPrabhakar Kushwaha 	int i;
653c517771aSPrabhakar Kushwaha 	struct qbman_release_desc rd;
654c517771aSPrabhakar Kushwaha 
655c517771aSPrabhakar Kushwaha 	for (i = 0; i < 7; i++) {
65614480454SPrabhakar Kushwaha 		addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
657c517771aSPrabhakar Kushwaha 		if (!addr) {
658c517771aSPrabhakar Kushwaha 			printf("addr allocation failed\n");
659c517771aSPrabhakar Kushwaha 			goto err_alloc;
660c517771aSPrabhakar Kushwaha 		}
661c517771aSPrabhakar Kushwaha 		memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
6625753b0f1SPrabhakar Kushwaha 		flush_dcache_range((u64)addr,
6635753b0f1SPrabhakar Kushwaha 				   (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
664c517771aSPrabhakar Kushwaha 
665c517771aSPrabhakar Kushwaha 		buf_array[i] = (uint64_t)addr;
666c517771aSPrabhakar Kushwaha 		debug("Release: buffer addr =0x%p\n", addr);
667c517771aSPrabhakar Kushwaha 	}
668c517771aSPrabhakar Kushwaha 
669c517771aSPrabhakar Kushwaha release_bufs:
670c517771aSPrabhakar Kushwaha 	/* In case the portal is busy, retry until successful.
671c517771aSPrabhakar Kushwaha 	 * This function is guaranteed to succeed in a reasonable amount
672c517771aSPrabhakar Kushwaha 	 * of time.
673c517771aSPrabhakar Kushwaha 	 */
674c517771aSPrabhakar Kushwaha 
675c517771aSPrabhakar Kushwaha 	do {
676c517771aSPrabhakar Kushwaha 		mdelay(1);
677c517771aSPrabhakar Kushwaha 		qbman_release_desc_clear(&rd);
678c517771aSPrabhakar Kushwaha 		qbman_release_desc_set_bpid(&rd, bpid);
679c517771aSPrabhakar Kushwaha 	} while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
680c517771aSPrabhakar Kushwaha 
681c517771aSPrabhakar Kushwaha 	return i;
682c517771aSPrabhakar Kushwaha 
683c517771aSPrabhakar Kushwaha err_alloc:
684c517771aSPrabhakar Kushwaha 	if (i)
685c517771aSPrabhakar Kushwaha 		goto release_bufs;
686c517771aSPrabhakar Kushwaha 
687c517771aSPrabhakar Kushwaha 	return 0;
688c517771aSPrabhakar Kushwaha }
689c517771aSPrabhakar Kushwaha 
690c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid)
691c517771aSPrabhakar Kushwaha {
692c517771aSPrabhakar Kushwaha 	int i;
693c517771aSPrabhakar Kushwaha 	int count;
694c517771aSPrabhakar Kushwaha 
695c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
696c517771aSPrabhakar Kushwaha 		count = ldpaa_bp_add_7(bpid);
697c517771aSPrabhakar Kushwaha 		if (count < 7)
698c517771aSPrabhakar Kushwaha 			printf("Buffer Seed= %d\n", count);
699c517771aSPrabhakar Kushwaha 	}
700c517771aSPrabhakar Kushwaha 
701c517771aSPrabhakar Kushwaha 	return 0;
702c517771aSPrabhakar Kushwaha }
703c517771aSPrabhakar Kushwaha 
704c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void)
705c517771aSPrabhakar Kushwaha {
706c517771aSPrabhakar Kushwaha 	int err;
707c517771aSPrabhakar Kushwaha 
70887457d11SPrabhakar Kushwaha 	err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
709c517771aSPrabhakar Kushwaha 			&dflt_dpbp->dpbp_handle);
710c517771aSPrabhakar Kushwaha 	if (err) {
711c517771aSPrabhakar Kushwaha 		printf("dpbp_open() failed\n");
712c517771aSPrabhakar Kushwaha 		goto err_open;
713c517771aSPrabhakar Kushwaha 	}
714c517771aSPrabhakar Kushwaha 
71587457d11SPrabhakar Kushwaha 	err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
716c517771aSPrabhakar Kushwaha 	if (err) {
717c517771aSPrabhakar Kushwaha 		printf("dpbp_enable() failed\n");
718c517771aSPrabhakar Kushwaha 		goto err_enable;
719c517771aSPrabhakar Kushwaha 	}
720c517771aSPrabhakar Kushwaha 
72187457d11SPrabhakar Kushwaha 	err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
72287457d11SPrabhakar Kushwaha 				  dflt_dpbp->dpbp_handle,
723c517771aSPrabhakar Kushwaha 				  &dflt_dpbp->dpbp_attr);
724c517771aSPrabhakar Kushwaha 	if (err) {
725c517771aSPrabhakar Kushwaha 		printf("dpbp_get_attributes() failed\n");
726c517771aSPrabhakar Kushwaha 		goto err_get_attr;
727c517771aSPrabhakar Kushwaha 	}
728c517771aSPrabhakar Kushwaha 
729c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
7302557c5a9SYogesh Gaur 
731c517771aSPrabhakar Kushwaha 	if (err) {
732c517771aSPrabhakar Kushwaha 		printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
733c517771aSPrabhakar Kushwaha 		       dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
734c517771aSPrabhakar Kushwaha 		goto err_seed;
735c517771aSPrabhakar Kushwaha 	}
736c517771aSPrabhakar Kushwaha 
737c517771aSPrabhakar Kushwaha 	return 0;
738c517771aSPrabhakar Kushwaha 
739c517771aSPrabhakar Kushwaha err_seed:
740c517771aSPrabhakar Kushwaha err_get_attr:
74187457d11SPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
742c517771aSPrabhakar Kushwaha err_enable:
74387457d11SPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
744c517771aSPrabhakar Kushwaha err_open:
745c517771aSPrabhakar Kushwaha 	return err;
746c517771aSPrabhakar Kushwaha }
747c517771aSPrabhakar Kushwaha 
748c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void)
749c517771aSPrabhakar Kushwaha {
750c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_drain();
75187457d11SPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
75287457d11SPrabhakar Kushwaha 	dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
75387457d11SPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
754c517771aSPrabhakar Kushwaha }
755c517771aSPrabhakar Kushwaha 
7569a696f56SPrabhakar Kushwaha static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
7579a696f56SPrabhakar Kushwaha 				     struct ldpaa_eth_priv *priv)
7589a696f56SPrabhakar Kushwaha {
7599a696f56SPrabhakar Kushwaha 	int error;
7602557c5a9SYogesh Gaur 	uint16_t major_ver, minor_ver;
7619a696f56SPrabhakar Kushwaha 
7622557c5a9SYogesh Gaur 	error = dpmac_get_api_version(dflt_mc_io, 0,
7632557c5a9SYogesh Gaur 					&major_ver,
7642557c5a9SYogesh Gaur 					&minor_ver);
7652557c5a9SYogesh Gaur 	if ((major_ver < DPMAC_VER_MAJOR) ||
7662557c5a9SYogesh Gaur 	    (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) {
7679a696f56SPrabhakar Kushwaha 		printf("DPMAC version mismatch found %u.%u,",
7682557c5a9SYogesh Gaur 		       major_ver, minor_ver);
7699a696f56SPrabhakar Kushwaha 		printf("supported version is %u.%u\n",
7709a696f56SPrabhakar Kushwaha 		       DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
7712557c5a9SYogesh Gaur 		return error;
7729a696f56SPrabhakar Kushwaha 	}
7739a696f56SPrabhakar Kushwaha 
7749a696f56SPrabhakar Kushwaha 	return error;
7759a696f56SPrabhakar Kushwaha }
7769a696f56SPrabhakar Kushwaha 
777c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
778c919ab9eSPrabhakar Kushwaha {
779c919ab9eSPrabhakar Kushwaha 	int err = 0;
780c919ab9eSPrabhakar Kushwaha 	struct dpmac_cfg dpmac_cfg;
781c919ab9eSPrabhakar Kushwaha 
782c919ab9eSPrabhakar Kushwaha 	dpmac_cfg.mac_id = priv->dpmac_id;
7832557c5a9SYogesh Gaur 
7842557c5a9SYogesh Gaur 	err = dpmac_create(dflt_mc_io,
7852557c5a9SYogesh Gaur 			   dflt_dprc_handle,
7862557c5a9SYogesh Gaur 			   MC_CMD_NO_FLAGS, &dpmac_cfg,
7872557c5a9SYogesh Gaur 			   &priv->dpmac_id);
788c919ab9eSPrabhakar Kushwaha 	if (err)
789c919ab9eSPrabhakar Kushwaha 		printf("dpmac_create() failed\n");
7909a696f56SPrabhakar Kushwaha 
7919a696f56SPrabhakar Kushwaha 	err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
7922557c5a9SYogesh Gaur 	if (err < 0) {
7939a696f56SPrabhakar Kushwaha 		printf("ldpaa_dpmac_version_check() failed: %d\n", err);
7942557c5a9SYogesh Gaur 		goto err_version_check;
7952557c5a9SYogesh Gaur 	}
7962557c5a9SYogesh Gaur 
7972557c5a9SYogesh Gaur 	err = dpmac_open(dflt_mc_io,
7982557c5a9SYogesh Gaur 			 MC_CMD_NO_FLAGS,
7992557c5a9SYogesh Gaur 			 priv->dpmac_id,
8002557c5a9SYogesh Gaur 			 &priv->dpmac_handle);
8012557c5a9SYogesh Gaur 	if (err < 0) {
8022557c5a9SYogesh Gaur 		printf("dpmac_open() failed: %d\n", err);
8032557c5a9SYogesh Gaur 		goto err_open;
8042557c5a9SYogesh Gaur 	}
8052557c5a9SYogesh Gaur 
8062557c5a9SYogesh Gaur 	return err;
8072557c5a9SYogesh Gaur 
8082557c5a9SYogesh Gaur err_open:
8092557c5a9SYogesh Gaur err_version_check:
8102557c5a9SYogesh Gaur 	dpmac_destroy(dflt_mc_io,
8112557c5a9SYogesh Gaur 		      dflt_dprc_handle,
8122557c5a9SYogesh Gaur 		      MC_CMD_NO_FLAGS, priv->dpmac_id);
8139a696f56SPrabhakar Kushwaha 
814c919ab9eSPrabhakar Kushwaha 	return err;
815c919ab9eSPrabhakar Kushwaha }
816c919ab9eSPrabhakar Kushwaha 
817c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
818c919ab9eSPrabhakar Kushwaha {
819c919ab9eSPrabhakar Kushwaha 	int err = 0;
820c919ab9eSPrabhakar Kushwaha 	struct dprc_connection_cfg dprc_connection_cfg = {
821c919ab9eSPrabhakar Kushwaha 		/* If both rates are zero the connection */
822c919ab9eSPrabhakar Kushwaha 		/* will be configured in "best effort" mode. */
823c919ab9eSPrabhakar Kushwaha 		.committed_rate = 0,
824c919ab9eSPrabhakar Kushwaha 		.max_rate = 0
825c919ab9eSPrabhakar Kushwaha 	};
826c919ab9eSPrabhakar Kushwaha 
8275038d3e5SPrabhakar Kushwaha #ifdef DEBUG
8285038d3e5SPrabhakar Kushwaha 	struct dprc_endpoint dbg_endpoint;
8295038d3e5SPrabhakar Kushwaha 	int state = 0;
8305038d3e5SPrabhakar Kushwaha #endif
8315038d3e5SPrabhakar Kushwaha 
832c919ab9eSPrabhakar Kushwaha 	memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
833192bc694SBen Whitten 	strcpy(dpmac_endpoint.type, "dpmac");
834c919ab9eSPrabhakar Kushwaha 	dpmac_endpoint.id = priv->dpmac_id;
835c919ab9eSPrabhakar Kushwaha 
836c919ab9eSPrabhakar Kushwaha 	memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
837192bc694SBen Whitten 	strcpy(dpni_endpoint.type, "dpni");
838c919ab9eSPrabhakar Kushwaha 	dpni_endpoint.id = dflt_dpni->dpni_id;
839c919ab9eSPrabhakar Kushwaha 
840c919ab9eSPrabhakar Kushwaha 	err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
841c919ab9eSPrabhakar Kushwaha 			     dflt_dprc_handle,
842c919ab9eSPrabhakar Kushwaha 			     &dpmac_endpoint,
843c919ab9eSPrabhakar Kushwaha 			     &dpni_endpoint,
844c919ab9eSPrabhakar Kushwaha 			     &dprc_connection_cfg);
8455038d3e5SPrabhakar Kushwaha 	if (err)
8465038d3e5SPrabhakar Kushwaha 		printf("dprc_connect() failed\n");
8475038d3e5SPrabhakar Kushwaha 
8485038d3e5SPrabhakar Kushwaha #ifdef DEBUG
8495038d3e5SPrabhakar Kushwaha 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
8505038d3e5SPrabhakar Kushwaha 				    dflt_dprc_handle, &dpni_endpoint,
8515038d3e5SPrabhakar Kushwaha 				    &dbg_endpoint, &state);
8525038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
8535038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
8545038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC State= %d\n", __func__, state);
8555038d3e5SPrabhakar Kushwaha 
8565038d3e5SPrabhakar Kushwaha 	memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
8575038d3e5SPrabhakar Kushwaha 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
8585038d3e5SPrabhakar Kushwaha 				    dflt_dprc_handle, &dpmac_endpoint,
8595038d3e5SPrabhakar Kushwaha 				    &dbg_endpoint, &state);
8605038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
8615038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
8625038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI State= %d\n", __func__, state);
8635038d3e5SPrabhakar Kushwaha #endif
864c919ab9eSPrabhakar Kushwaha 	return err;
865c919ab9eSPrabhakar Kushwaha }
866c919ab9eSPrabhakar Kushwaha 
867c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
868c517771aSPrabhakar Kushwaha {
869c517771aSPrabhakar Kushwaha 	int err;
870c517771aSPrabhakar Kushwaha 
871c517771aSPrabhakar Kushwaha 	/* and get a handle for the DPNI this interface is associate with */
872c919ab9eSPrabhakar Kushwaha 	err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
873c919ab9eSPrabhakar Kushwaha 			&dflt_dpni->dpni_handle);
874c517771aSPrabhakar Kushwaha 	if (err) {
875c517771aSPrabhakar Kushwaha 		printf("dpni_open() failed\n");
876c517771aSPrabhakar Kushwaha 		goto err_open;
877c517771aSPrabhakar Kushwaha 	}
87887457d11SPrabhakar Kushwaha 	err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
879c919ab9eSPrabhakar Kushwaha 				  dflt_dpni->dpni_handle,
880c919ab9eSPrabhakar Kushwaha 				  &dflt_dpni->dpni_attrs);
881c517771aSPrabhakar Kushwaha 	if (err) {
882c517771aSPrabhakar Kushwaha 		printf("dpni_get_attributes() failed (err=%d)\n", err);
883c517771aSPrabhakar Kushwaha 		goto err_get_attr;
884c517771aSPrabhakar Kushwaha 	}
885c517771aSPrabhakar Kushwaha 
886c517771aSPrabhakar Kushwaha 	/* Configure our buffers' layout */
887c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
888c517771aSPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
88914480454SPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
89014480454SPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
891c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.pass_parser_result = true;
892c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.pass_frame_status = true;
893c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
89414480454SPrabhakar Kushwaha 	/* HW erratum mandates data alignment in multiples of 256 */
89514480454SPrabhakar Kushwaha 	dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
8962557c5a9SYogesh Gaur 
897c517771aSPrabhakar Kushwaha 	/* ...rx, ... */
8982557c5a9SYogesh Gaur 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
899c919ab9eSPrabhakar Kushwaha 				     dflt_dpni->dpni_handle,
9002557c5a9SYogesh Gaur 				     &dflt_dpni->buf_layout, DPNI_QUEUE_RX);
901c517771aSPrabhakar Kushwaha 	if (err) {
9022557c5a9SYogesh Gaur 		printf("dpni_set_buffer_layout() failed");
903c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
904c517771aSPrabhakar Kushwaha 	}
905c517771aSPrabhakar Kushwaha 
906c517771aSPrabhakar Kushwaha 	/* ... tx, ... */
90714480454SPrabhakar Kushwaha 	/* remove Rx-only options */
90814480454SPrabhakar Kushwaha 	dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
90914480454SPrabhakar Kushwaha 				      DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
9102557c5a9SYogesh Gaur 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
911c919ab9eSPrabhakar Kushwaha 				     dflt_dpni->dpni_handle,
9122557c5a9SYogesh Gaur 				     &dflt_dpni->buf_layout, DPNI_QUEUE_TX);
913c517771aSPrabhakar Kushwaha 	if (err) {
9142557c5a9SYogesh Gaur 		printf("dpni_set_buffer_layout() failed");
915c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
916c517771aSPrabhakar Kushwaha 	}
917c517771aSPrabhakar Kushwaha 
918c517771aSPrabhakar Kushwaha 	/* ... tx-confirm. */
919c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
9202557c5a9SYogesh Gaur 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
921c919ab9eSPrabhakar Kushwaha 				     dflt_dpni->dpni_handle,
9222557c5a9SYogesh Gaur 				     &dflt_dpni->buf_layout,
9232557c5a9SYogesh Gaur 				     DPNI_QUEUE_TX_CONFIRM);
924c517771aSPrabhakar Kushwaha 	if (err) {
9252557c5a9SYogesh Gaur 		printf("dpni_set_buffer_layout() failed");
926c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
927c517771aSPrabhakar Kushwaha 	}
928c517771aSPrabhakar Kushwaha 
929c517771aSPrabhakar Kushwaha 	/* Now that we've set our tx buffer layout, retrieve the minimum
930c517771aSPrabhakar Kushwaha 	 * required tx data offset.
931c517771aSPrabhakar Kushwaha 	 */
93287457d11SPrabhakar Kushwaha 	err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
933c919ab9eSPrabhakar Kushwaha 				      dflt_dpni->dpni_handle,
934c919ab9eSPrabhakar Kushwaha 				      &priv->tx_data_offset);
935c517771aSPrabhakar Kushwaha 	if (err) {
936c517771aSPrabhakar Kushwaha 		printf("dpni_get_tx_data_offset() failed\n");
937c517771aSPrabhakar Kushwaha 		goto err_data_offset;
938c517771aSPrabhakar Kushwaha 	}
939c517771aSPrabhakar Kushwaha 
940c517771aSPrabhakar Kushwaha 	/* Warn in case TX data offset is not multiple of 64 bytes. */
941c517771aSPrabhakar Kushwaha 	WARN_ON(priv->tx_data_offset % 64);
942c517771aSPrabhakar Kushwaha 
943c517771aSPrabhakar Kushwaha 	/* Accomodate SWA space. */
944c517771aSPrabhakar Kushwaha 	priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
945c517771aSPrabhakar Kushwaha 	debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
946c517771aSPrabhakar Kushwaha 
947c517771aSPrabhakar Kushwaha 	return 0;
948c517771aSPrabhakar Kushwaha 
949c517771aSPrabhakar Kushwaha err_data_offset:
950c517771aSPrabhakar Kushwaha err_buf_layout:
951c517771aSPrabhakar Kushwaha err_get_attr:
952c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
953c517771aSPrabhakar Kushwaha err_open:
954c517771aSPrabhakar Kushwaha 	return err;
955c517771aSPrabhakar Kushwaha }
956c517771aSPrabhakar Kushwaha 
957c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
958c517771aSPrabhakar Kushwaha {
959c517771aSPrabhakar Kushwaha 	struct dpni_pools_cfg pools_params;
9602557c5a9SYogesh Gaur 	struct dpni_queue tx_queue;
961c517771aSPrabhakar Kushwaha 	int err = 0;
962c517771aSPrabhakar Kushwaha 
96331a48cf4SPrabhakar Kushwaha 	memset(&pools_params, 0, sizeof(pools_params));
964c517771aSPrabhakar Kushwaha 	pools_params.num_dpbp = 1;
965c517771aSPrabhakar Kushwaha 	pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
966c517771aSPrabhakar Kushwaha 	pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
967c919ab9eSPrabhakar Kushwaha 	err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
968c919ab9eSPrabhakar Kushwaha 			     dflt_dpni->dpni_handle, &pools_params);
969c517771aSPrabhakar Kushwaha 	if (err) {
970c517771aSPrabhakar Kushwaha 		printf("dpni_set_pools() failed\n");
971c517771aSPrabhakar Kushwaha 		return err;
972c517771aSPrabhakar Kushwaha 	}
973c517771aSPrabhakar Kushwaha 
9742557c5a9SYogesh Gaur 	memset(&tx_queue, 0, sizeof(struct dpni_queue));
975c517771aSPrabhakar Kushwaha 
9762557c5a9SYogesh Gaur 	err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
9772557c5a9SYogesh Gaur 			     dflt_dpni->dpni_handle,
9782557c5a9SYogesh Gaur 			     DPNI_QUEUE_TX, 0, 0, &tx_queue);
9792557c5a9SYogesh Gaur 
980c517771aSPrabhakar Kushwaha 	if (err) {
9812557c5a9SYogesh Gaur 		printf("dpni_set_queue() failed\n");
982c517771aSPrabhakar Kushwaha 		return err;
983c517771aSPrabhakar Kushwaha 	}
984c517771aSPrabhakar Kushwaha 
9852557c5a9SYogesh Gaur 	err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS,
9866073548aSPrabhakar Kushwaha 					    dflt_dpni->dpni_handle,
9872557c5a9SYogesh Gaur 					    DPNI_CONF_DISABLE);
9886073548aSPrabhakar Kushwaha 	if (err) {
9892557c5a9SYogesh Gaur 		printf("dpni_set_tx_confirmation_mode() failed\n");
9906073548aSPrabhakar Kushwaha 		return err;
9916073548aSPrabhakar Kushwaha 	}
9926073548aSPrabhakar Kushwaha 
993c517771aSPrabhakar Kushwaha 	return 0;
994c517771aSPrabhakar Kushwaha }
995c517771aSPrabhakar Kushwaha 
996c919ab9eSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
997c919ab9eSPrabhakar Kushwaha 				 phy_interface_t enet_if)
998c517771aSPrabhakar Kushwaha {
999c517771aSPrabhakar Kushwaha 	int err;
1000c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
1001c517771aSPrabhakar Kushwaha 
1002c022ec03SPankaj Bansal 	snprintf(net_dev->name, ETH_NAME_LEN, "DPMAC%d@%s", priv->dpmac_id,
1003c919ab9eSPrabhakar Kushwaha 		 phy_interface_strings[enet_if]);
1004c517771aSPrabhakar Kushwaha 
1005c517771aSPrabhakar Kushwaha 	net_dev->iobase = 0;
1006c517771aSPrabhakar Kushwaha 	net_dev->init = ldpaa_eth_open;
1007c517771aSPrabhakar Kushwaha 	net_dev->halt = ldpaa_eth_stop;
1008c517771aSPrabhakar Kushwaha 	net_dev->send = ldpaa_eth_tx;
1009c517771aSPrabhakar Kushwaha 	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
1010c517771aSPrabhakar Kushwaha 
10116c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
10126c2b520aSPrabhakar Kushwaha 	err = init_phy(net_dev);
10136c2b520aSPrabhakar Kushwaha 	if (err < 0)
10146c2b520aSPrabhakar Kushwaha 		return err;
10156c2b520aSPrabhakar Kushwaha #endif
1016c517771aSPrabhakar Kushwaha 
1017c517771aSPrabhakar Kushwaha 	err = eth_register(net_dev);
1018c517771aSPrabhakar Kushwaha 	if (err < 0) {
1019c517771aSPrabhakar Kushwaha 		printf("eth_register() = %d\n", err);
1020c517771aSPrabhakar Kushwaha 		return err;
1021c517771aSPrabhakar Kushwaha 	}
1022c517771aSPrabhakar Kushwaha 
1023c517771aSPrabhakar Kushwaha 	return 0;
1024c517771aSPrabhakar Kushwaha }
1025c517771aSPrabhakar Kushwaha 
1026c919ab9eSPrabhakar Kushwaha int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
1027c517771aSPrabhakar Kushwaha {
1028c517771aSPrabhakar Kushwaha 	struct eth_device		*net_dev = NULL;
1029c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv		*priv = NULL;
1030c517771aSPrabhakar Kushwaha 	int				err = 0;
1031c517771aSPrabhakar Kushwaha 
1032c517771aSPrabhakar Kushwaha 	/* Net device */
1033c517771aSPrabhakar Kushwaha 	net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
1034c517771aSPrabhakar Kushwaha 	if (!net_dev) {
1035c517771aSPrabhakar Kushwaha 		printf("eth_device malloc() failed\n");
1036c517771aSPrabhakar Kushwaha 		return -ENOMEM;
1037c517771aSPrabhakar Kushwaha 	}
1038c517771aSPrabhakar Kushwaha 	memset(net_dev, 0, sizeof(struct eth_device));
1039c517771aSPrabhakar Kushwaha 
1040c517771aSPrabhakar Kushwaha 	/* alloc the ldpaa ethernet private struct */
1041c517771aSPrabhakar Kushwaha 	priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1042c517771aSPrabhakar Kushwaha 	if (!priv) {
1043c517771aSPrabhakar Kushwaha 		printf("ldpaa_eth_priv malloc() failed\n");
1044c517771aSPrabhakar Kushwaha 		return -ENOMEM;
1045c517771aSPrabhakar Kushwaha 	}
1046c517771aSPrabhakar Kushwaha 	memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1047c517771aSPrabhakar Kushwaha 
1048c517771aSPrabhakar Kushwaha 	net_dev->priv = (void *)priv;
1049c517771aSPrabhakar Kushwaha 	priv->net_dev = (struct eth_device *)net_dev;
1050c919ab9eSPrabhakar Kushwaha 	priv->dpmac_id = dpmac_id;
1051c919ab9eSPrabhakar Kushwaha 	debug("%s dpmac_id=%d\n", __func__, dpmac_id);
1052c517771aSPrabhakar Kushwaha 
1053c919ab9eSPrabhakar Kushwaha 	err = ldpaa_eth_netdev_init(net_dev, enet_if);
1054c517771aSPrabhakar Kushwaha 	if (err)
1055c517771aSPrabhakar Kushwaha 		goto err_netdev_init;
1056c517771aSPrabhakar Kushwaha 
1057c517771aSPrabhakar Kushwaha 	debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1058c517771aSPrabhakar Kushwaha 	return 0;
1059c517771aSPrabhakar Kushwaha 
1060c517771aSPrabhakar Kushwaha err_netdev_init:
1061c517771aSPrabhakar Kushwaha 	free(priv);
1062c517771aSPrabhakar Kushwaha 	net_dev->priv = NULL;
1063c517771aSPrabhakar Kushwaha 	free(net_dev);
1064c517771aSPrabhakar Kushwaha 
1065c517771aSPrabhakar Kushwaha 	return err;
1066c517771aSPrabhakar Kushwaha }
1067