xref: /openbmc/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c (revision 5e9445da288c5121546235e8201768abd087b281)
1c517771aSPrabhakar Kushwaha /*
2c517771aSPrabhakar Kushwaha  * Copyright (C) 2014 Freescale Semiconductor
3c517771aSPrabhakar Kushwaha  *
4c517771aSPrabhakar Kushwaha  * SPDX-License-Identifier:	GPL-2.0+
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 
386c2b520aSPrabhakar Kushwaha 	priv->phydev = phydev;
396c2b520aSPrabhakar Kushwaha 
406c2b520aSPrabhakar Kushwaha 	return phy_config(phydev);
416c2b520aSPrabhakar Kushwaha }
426c2b520aSPrabhakar Kushwaha #endif
436c2b520aSPrabhakar Kushwaha 
445038d3e5SPrabhakar Kushwaha #ifdef DEBUG
455038d3e5SPrabhakar Kushwaha static void ldpaa_eth_get_dpni_counter(void)
465038d3e5SPrabhakar Kushwaha {
475038d3e5SPrabhakar Kushwaha 	int err = 0;
485038d3e5SPrabhakar Kushwaha 	u64 value;
495038d3e5SPrabhakar Kushwaha 
505038d3e5SPrabhakar Kushwaha 	err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
515038d3e5SPrabhakar Kushwaha 		     dflt_dpni->dpni_handle,
525038d3e5SPrabhakar Kushwaha 		     DPNI_CNT_ING_FRAME,
535038d3e5SPrabhakar Kushwaha 		     &value);
545038d3e5SPrabhakar Kushwaha 	if (err < 0) {
555038d3e5SPrabhakar Kushwaha 		printf("dpni_get_counter: DPNI_CNT_ING_FRAME failed\n");
565038d3e5SPrabhakar Kushwaha 		return;
575038d3e5SPrabhakar Kushwaha 	}
585038d3e5SPrabhakar Kushwaha 	printf("DPNI_CNT_ING_FRAME=%lld\n", value);
595038d3e5SPrabhakar Kushwaha 
605038d3e5SPrabhakar Kushwaha 	err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
615038d3e5SPrabhakar Kushwaha 		     dflt_dpni->dpni_handle,
625038d3e5SPrabhakar Kushwaha 		     DPNI_CNT_ING_BYTE,
635038d3e5SPrabhakar Kushwaha 		     &value);
645038d3e5SPrabhakar Kushwaha 	if (err < 0) {
655038d3e5SPrabhakar Kushwaha 		printf("dpni_get_counter: DPNI_CNT_ING_BYTE failed\n");
665038d3e5SPrabhakar Kushwaha 		return;
675038d3e5SPrabhakar Kushwaha 	}
685038d3e5SPrabhakar Kushwaha 	printf("DPNI_CNT_ING_BYTE=%lld\n", value);
695038d3e5SPrabhakar Kushwaha 
705038d3e5SPrabhakar Kushwaha 	err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
715038d3e5SPrabhakar Kushwaha 		     dflt_dpni->dpni_handle,
725038d3e5SPrabhakar Kushwaha 		     DPNI_CNT_ING_FRAME_DROP ,
735038d3e5SPrabhakar Kushwaha 		     &value);
745038d3e5SPrabhakar Kushwaha 	if (err < 0) {
755038d3e5SPrabhakar Kushwaha 		printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DROP failed\n");
765038d3e5SPrabhakar Kushwaha 		return;
775038d3e5SPrabhakar Kushwaha 	}
785038d3e5SPrabhakar Kushwaha 	printf("DPNI_CNT_ING_FRAME_DROP =%lld\n", value);
795038d3e5SPrabhakar Kushwaha 
805038d3e5SPrabhakar Kushwaha 	err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
815038d3e5SPrabhakar Kushwaha 		     dflt_dpni->dpni_handle,
825038d3e5SPrabhakar Kushwaha 		     DPNI_CNT_ING_FRAME_DISCARD,
835038d3e5SPrabhakar Kushwaha 		     &value);
845038d3e5SPrabhakar Kushwaha 	if (err < 0) {
855038d3e5SPrabhakar Kushwaha 		printf("dpni_get_counter: DPNI_CNT_ING_FRAME_DISCARD failed\n");
865038d3e5SPrabhakar Kushwaha 		return;
875038d3e5SPrabhakar Kushwaha 	}
885038d3e5SPrabhakar Kushwaha 	printf("DPNI_CNT_ING_FRAME_DISCARD=%lld\n", value);
895038d3e5SPrabhakar Kushwaha 
905038d3e5SPrabhakar Kushwaha 	err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
915038d3e5SPrabhakar Kushwaha 		     dflt_dpni->dpni_handle,
925038d3e5SPrabhakar Kushwaha 		     DPNI_CNT_EGR_FRAME,
935038d3e5SPrabhakar Kushwaha 		     &value);
945038d3e5SPrabhakar Kushwaha 	if (err < 0) {
955038d3e5SPrabhakar Kushwaha 		printf("dpni_get_counter: DPNI_CNT_EGR_FRAME failed\n");
965038d3e5SPrabhakar Kushwaha 		return;
975038d3e5SPrabhakar Kushwaha 	}
985038d3e5SPrabhakar Kushwaha 	printf("DPNI_CNT_EGR_FRAME=%lld\n", value);
995038d3e5SPrabhakar Kushwaha 
1005038d3e5SPrabhakar Kushwaha 	err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
1015038d3e5SPrabhakar Kushwaha 		     dflt_dpni->dpni_handle,
1025038d3e5SPrabhakar Kushwaha 		     DPNI_CNT_EGR_BYTE ,
1035038d3e5SPrabhakar Kushwaha 		     &value);
1045038d3e5SPrabhakar Kushwaha 	if (err < 0) {
1055038d3e5SPrabhakar Kushwaha 		printf("dpni_get_counter: DPNI_CNT_EGR_BYTE failed\n");
1065038d3e5SPrabhakar Kushwaha 		return;
1075038d3e5SPrabhakar Kushwaha 	}
1085038d3e5SPrabhakar Kushwaha 	printf("DPNI_CNT_EGR_BYTE =%lld\n", value);
1095038d3e5SPrabhakar Kushwaha 
1105038d3e5SPrabhakar Kushwaha 	err = dpni_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
1115038d3e5SPrabhakar Kushwaha 		     dflt_dpni->dpni_handle,
1125038d3e5SPrabhakar Kushwaha 		     DPNI_CNT_EGR_FRAME_DISCARD ,
1135038d3e5SPrabhakar Kushwaha 		     &value);
1145038d3e5SPrabhakar Kushwaha 	if (err < 0) {
1155038d3e5SPrabhakar Kushwaha 		printf("dpni_get_counter: DPNI_CNT_EGR_FRAME_DISCARD failed\n");
1165038d3e5SPrabhakar Kushwaha 		return;
1175038d3e5SPrabhakar Kushwaha 	}
1185038d3e5SPrabhakar Kushwaha 	printf("DPNI_CNT_EGR_FRAME_DISCARD =%lld\n", value);
1195038d3e5SPrabhakar Kushwaha }
12044b2036eSPrabhakar Kushwaha 
12144b2036eSPrabhakar Kushwaha static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev)
12244b2036eSPrabhakar Kushwaha {
12344b2036eSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
12444b2036eSPrabhakar Kushwaha 	int err = 0;
12544b2036eSPrabhakar Kushwaha 	u64 value;
12644b2036eSPrabhakar Kushwaha 
12744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
12844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
12944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_BYTE,
13044b2036eSPrabhakar Kushwaha 		     &value);
13144b2036eSPrabhakar Kushwaha 	if (err < 0) {
13244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
13344b2036eSPrabhakar Kushwaha 		return;
13444b2036eSPrabhakar Kushwaha 	}
13544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
13644b2036eSPrabhakar Kushwaha 
13744b2036eSPrabhakar Kushwaha 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
13844b2036eSPrabhakar Kushwaha 		     priv->dpmac_handle,
13944b2036eSPrabhakar Kushwaha 		     DPMAC_CNT_ING_FRAME_DISCARD,
14044b2036eSPrabhakar Kushwaha 		     &value);
14144b2036eSPrabhakar Kushwaha 	if (err < 0) {
14244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
14344b2036eSPrabhakar Kushwaha 		return;
14444b2036eSPrabhakar Kushwaha 	}
14544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_FRAME_DISCARD=%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_ALIGN_ERR,
15044b2036eSPrabhakar Kushwaha 		     &value);
15144b2036eSPrabhakar Kushwaha 	if (err < 0) {
15244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
15344b2036eSPrabhakar Kushwaha 		return;
15444b2036eSPrabhakar Kushwaha 	}
15544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_ALIGN_ERR =%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_BYTE,
16044b2036eSPrabhakar Kushwaha 		     &value);
16144b2036eSPrabhakar Kushwaha 	if (err < 0) {
16244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
16344b2036eSPrabhakar Kushwaha 		return;
16444b2036eSPrabhakar Kushwaha 	}
16544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_BYTE=%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_ERR_FRAME,
17044b2036eSPrabhakar Kushwaha 		     &value);
17144b2036eSPrabhakar Kushwaha 	if (err < 0) {
17244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
17344b2036eSPrabhakar Kushwaha 		return;
17444b2036eSPrabhakar Kushwaha 	}
17544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_ING_ERR_FRAME=%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_EGR_BYTE ,
18044b2036eSPrabhakar Kushwaha 		     &value);
18144b2036eSPrabhakar Kushwaha 	if (err < 0) {
18244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
18344b2036eSPrabhakar Kushwaha 		return;
18444b2036eSPrabhakar Kushwaha 	}
18544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_EGR_BYTE =%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_ERR_FRAME ,
19044b2036eSPrabhakar Kushwaha 		     &value);
19144b2036eSPrabhakar Kushwaha 	if (err < 0) {
19244b2036eSPrabhakar Kushwaha 		printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
19344b2036eSPrabhakar Kushwaha 		return;
19444b2036eSPrabhakar Kushwaha 	}
19544b2036eSPrabhakar Kushwaha 	printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
19644b2036eSPrabhakar Kushwaha }
1975038d3e5SPrabhakar Kushwaha #endif
1985038d3e5SPrabhakar Kushwaha 
199c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
200c517771aSPrabhakar Kushwaha 			 const struct dpaa_fd *fd)
201c517771aSPrabhakar Kushwaha {
202c517771aSPrabhakar Kushwaha 	u64 fd_addr;
203c517771aSPrabhakar Kushwaha 	uint16_t fd_offset;
204c517771aSPrabhakar Kushwaha 	uint32_t fd_length;
205c517771aSPrabhakar Kushwaha 	struct ldpaa_fas *fas;
206c517771aSPrabhakar Kushwaha 	uint32_t status, err;
20756c57cf7SPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
20856c57cf7SPrabhakar Kushwaha 	u32 time_start;
209c517771aSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
210c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
211c517771aSPrabhakar Kushwaha 
212c517771aSPrabhakar Kushwaha 	fd_addr = ldpaa_fd_get_addr(fd);
213c517771aSPrabhakar Kushwaha 	fd_offset = ldpaa_fd_get_offset(fd);
214c517771aSPrabhakar Kushwaha 	fd_length = ldpaa_fd_get_len(fd);
215c517771aSPrabhakar Kushwaha 
216c517771aSPrabhakar Kushwaha 	debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
217c517771aSPrabhakar Kushwaha 
218c517771aSPrabhakar Kushwaha 	if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
219c517771aSPrabhakar Kushwaha 		/* Read the frame annotation status word and check for errors */
220c517771aSPrabhakar Kushwaha 		fas = (struct ldpaa_fas *)
221c517771aSPrabhakar Kushwaha 				((uint8_t *)(fd_addr) +
222c919ab9eSPrabhakar Kushwaha 				dflt_dpni->buf_layout.private_data_size);
223c517771aSPrabhakar Kushwaha 		status = le32_to_cpu(fas->status);
224c517771aSPrabhakar Kushwaha 		if (status & LDPAA_ETH_RX_ERR_MASK) {
225c517771aSPrabhakar Kushwaha 			printf("Rx frame error(s): 0x%08x\n",
226c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_ERR_MASK);
227c517771aSPrabhakar Kushwaha 			goto error;
228c517771aSPrabhakar Kushwaha 		} else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
229c517771aSPrabhakar Kushwaha 			printf("Unsupported feature in bitmask: 0x%08x\n",
230c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_UNSUPP_MASK);
231c517771aSPrabhakar Kushwaha 			goto error;
232c517771aSPrabhakar Kushwaha 		}
233c517771aSPrabhakar Kushwaha 	}
234c517771aSPrabhakar Kushwaha 
235c517771aSPrabhakar Kushwaha 	debug("Rx frame: To Upper layer\n");
236c517771aSPrabhakar Kushwaha 	net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
237c517771aSPrabhakar Kushwaha 				    fd_length);
238c517771aSPrabhakar Kushwaha 
239c517771aSPrabhakar Kushwaha error:
2405753b0f1SPrabhakar Kushwaha 	flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
241c517771aSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
242c517771aSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
24356c57cf7SPrabhakar Kushwaha 	time_start = get_timer(0);
244c517771aSPrabhakar Kushwaha 	do {
245c517771aSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
246c517771aSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
24756c57cf7SPrabhakar Kushwaha 	} while (get_timer(time_start) < timeo && err == -EBUSY);
24856c57cf7SPrabhakar Kushwaha 
24956c57cf7SPrabhakar Kushwaha 	if (err == -EBUSY)
25056c57cf7SPrabhakar Kushwaha 		printf("Rx frame: QBMAN buffer release fails\n");
25156c57cf7SPrabhakar Kushwaha 
252c517771aSPrabhakar Kushwaha 	return;
253c517771aSPrabhakar Kushwaha }
254c517771aSPrabhakar Kushwaha 
255c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
256c517771aSPrabhakar Kushwaha {
257c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
258c517771aSPrabhakar Kushwaha 	const struct ldpaa_dq *dq;
259c517771aSPrabhakar Kushwaha 	const struct dpaa_fd *fd;
260b4c3a35dSPrabhakar Kushwaha 	int i = 5, err = 0, status;
261b4c3a35dSPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
262b4c3a35dSPrabhakar Kushwaha 	u32 time_start;
263c517771aSPrabhakar Kushwaha 	static struct qbman_pull_desc pulldesc;
264c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
265c517771aSPrabhakar Kushwaha 
2665753b0f1SPrabhakar Kushwaha 	while (--i) {
267c517771aSPrabhakar Kushwaha 		qbman_pull_desc_clear(&pulldesc);
268c517771aSPrabhakar Kushwaha 		qbman_pull_desc_set_numframes(&pulldesc, 1);
269c517771aSPrabhakar Kushwaha 		qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
270c517771aSPrabhakar Kushwaha 
271c517771aSPrabhakar Kushwaha 		err = qbman_swp_pull(swp, &pulldesc);
272c517771aSPrabhakar Kushwaha 		if (err < 0) {
273c517771aSPrabhakar Kushwaha 			printf("Dequeue frames error:0x%08x\n", err);
274c517771aSPrabhakar Kushwaha 			continue;
275c517771aSPrabhakar Kushwaha 		}
276c517771aSPrabhakar Kushwaha 
277b4c3a35dSPrabhakar Kushwaha 		time_start = get_timer(0);
2785753b0f1SPrabhakar Kushwaha 
279b4c3a35dSPrabhakar Kushwaha 		 do {
280b4c3a35dSPrabhakar Kushwaha 			dq = qbman_swp_dqrr_next(swp);
281b4c3a35dSPrabhakar Kushwaha 		} while (get_timer(time_start) < timeo && !dq);
2825753b0f1SPrabhakar Kushwaha 
283c517771aSPrabhakar Kushwaha 		if (dq) {
284c517771aSPrabhakar Kushwaha 			/* Check for valid frame. If not sent a consume
285c517771aSPrabhakar Kushwaha 			 * confirmation to QBMAN otherwise give it to NADK
286c517771aSPrabhakar Kushwaha 			 * application and then send consume confirmation to
287c517771aSPrabhakar Kushwaha 			 * QBMAN.
288c517771aSPrabhakar Kushwaha 			 */
289c517771aSPrabhakar Kushwaha 			status = (uint8_t)ldpaa_dq_flags(dq);
290c517771aSPrabhakar Kushwaha 			if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
291c517771aSPrabhakar Kushwaha 				debug("Dequeue RX frames:");
292c517771aSPrabhakar Kushwaha 				debug("No frame delivered\n");
293c517771aSPrabhakar Kushwaha 
294c517771aSPrabhakar Kushwaha 				qbman_swp_dqrr_consume(swp, dq);
2950c7c87a4SPrabhakar Kushwaha 				continue;
296c517771aSPrabhakar Kushwaha 			}
297c517771aSPrabhakar Kushwaha 
298c517771aSPrabhakar Kushwaha 			fd = ldpaa_dq_fd(dq);
299c517771aSPrabhakar Kushwaha 
300c517771aSPrabhakar Kushwaha 			/* Obtain FD and process it */
301c517771aSPrabhakar Kushwaha 			ldpaa_eth_rx(priv, fd);
302c517771aSPrabhakar Kushwaha 			qbman_swp_dqrr_consume(swp, dq);
303c517771aSPrabhakar Kushwaha 			break;
304b4c3a35dSPrabhakar Kushwaha 		} else {
305b4c3a35dSPrabhakar Kushwaha 			err = -ENODATA;
306b4c3a35dSPrabhakar Kushwaha 			debug("No DQRR entries\n");
307b4c3a35dSPrabhakar Kushwaha 			break;
308c517771aSPrabhakar Kushwaha 		}
309c517771aSPrabhakar Kushwaha 	}
310c517771aSPrabhakar Kushwaha 
311c517771aSPrabhakar Kushwaha 	return err;
312c517771aSPrabhakar Kushwaha }
313c517771aSPrabhakar Kushwaha 
314c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
315c517771aSPrabhakar Kushwaha {
316c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
317c517771aSPrabhakar Kushwaha 	struct dpaa_fd fd;
318c517771aSPrabhakar Kushwaha 	u64 buffer_start;
319c517771aSPrabhakar Kushwaha 	int data_offset, err;
320e48df52bSPrabhakar Kushwaha 	u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
321e48df52bSPrabhakar Kushwaha 	u32 time_start;
322c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
323c517771aSPrabhakar Kushwaha 	struct qbman_eq_desc ed;
324e48df52bSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
325c517771aSPrabhakar Kushwaha 
326c517771aSPrabhakar Kushwaha 	/* Setup the FD fields */
327c517771aSPrabhakar Kushwaha 	memset(&fd, 0, sizeof(fd));
328c517771aSPrabhakar Kushwaha 
329c517771aSPrabhakar Kushwaha 	data_offset = priv->tx_data_offset;
330c517771aSPrabhakar Kushwaha 
331c517771aSPrabhakar Kushwaha 	do {
332c517771aSPrabhakar Kushwaha 		err = qbman_swp_acquire(dflt_dpio->sw_portal,
333c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
334c517771aSPrabhakar Kushwaha 					&buffer_start, 1);
335c517771aSPrabhakar Kushwaha 	} while (err == -EBUSY);
336c517771aSPrabhakar Kushwaha 
337*5e9445daSAshish Kumar 	if (err <= 0) {
338c517771aSPrabhakar Kushwaha 		printf("qbman_swp_acquire() failed\n");
339c517771aSPrabhakar Kushwaha 		return -ENOMEM;
340c517771aSPrabhakar Kushwaha 	}
341c517771aSPrabhakar Kushwaha 
342c517771aSPrabhakar Kushwaha 	debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
343c517771aSPrabhakar Kushwaha 
344c517771aSPrabhakar Kushwaha 	memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
345c517771aSPrabhakar Kushwaha 
3465753b0f1SPrabhakar Kushwaha 	flush_dcache_range(buffer_start, buffer_start +
3475753b0f1SPrabhakar Kushwaha 					LDPAA_ETH_RX_BUFFER_SIZE);
348c517771aSPrabhakar Kushwaha 
349c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_addr(&fd, (u64)buffer_start);
350c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
351c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
352c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_len(&fd, len);
353c517771aSPrabhakar Kushwaha 
354c517771aSPrabhakar Kushwaha 	fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
355c517771aSPrabhakar Kushwaha 				LDPAA_FD_CTRL_PTV1;
356c517771aSPrabhakar Kushwaha 
357c517771aSPrabhakar Kushwaha 	qbman_eq_desc_clear(&ed);
358c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_no_orp(&ed, 0);
359c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
360e48df52bSPrabhakar Kushwaha 
361e48df52bSPrabhakar Kushwaha 	time_start = get_timer(0);
362e48df52bSPrabhakar Kushwaha 
363e48df52bSPrabhakar Kushwaha 	while (get_timer(time_start) < timeo) {
364e48df52bSPrabhakar Kushwaha 		err = qbman_swp_enqueue(swp, &ed,
365e48df52bSPrabhakar Kushwaha 				(const struct qbman_fd *)(&fd));
366e48df52bSPrabhakar Kushwaha 		if (err != -EBUSY)
367e48df52bSPrabhakar Kushwaha 			break;
368e48df52bSPrabhakar Kushwaha 	}
369e48df52bSPrabhakar Kushwaha 
370e48df52bSPrabhakar Kushwaha 	if (err < 0) {
371c517771aSPrabhakar Kushwaha 		printf("error enqueueing Tx frame\n");
372e48df52bSPrabhakar Kushwaha 		goto error;
373e48df52bSPrabhakar Kushwaha 	}
374c517771aSPrabhakar Kushwaha 
375c517771aSPrabhakar Kushwaha 	return err;
376e48df52bSPrabhakar Kushwaha 
377e48df52bSPrabhakar Kushwaha error:
378e48df52bSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
379e48df52bSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
380e48df52bSPrabhakar Kushwaha 	time_start = get_timer(0);
381e48df52bSPrabhakar Kushwaha 	do {
382e48df52bSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
383e48df52bSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
384e48df52bSPrabhakar Kushwaha 	} while (get_timer(time_start) < timeo && err == -EBUSY);
385e48df52bSPrabhakar Kushwaha 
386e48df52bSPrabhakar Kushwaha 	if (err == -EBUSY)
387e48df52bSPrabhakar Kushwaha 		printf("TX data: QBMAN buffer release fails\n");
388e48df52bSPrabhakar Kushwaha 
389e48df52bSPrabhakar Kushwaha 	return err;
390c517771aSPrabhakar Kushwaha }
391c517771aSPrabhakar Kushwaha 
392c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
393c517771aSPrabhakar Kushwaha {
394c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
395c517771aSPrabhakar Kushwaha 	struct dpni_queue_attr rx_queue_attr;
396c919ab9eSPrabhakar Kushwaha 	struct dpmac_link_state	dpmac_link_state = { 0 };
3975038d3e5SPrabhakar Kushwaha #ifdef DEBUG
3985038d3e5SPrabhakar Kushwaha 	struct dpni_link_state link_state;
3995038d3e5SPrabhakar Kushwaha #endif
4006c2b520aSPrabhakar Kushwaha 	int err = 0;
4016c2b520aSPrabhakar Kushwaha 	struct mii_dev *bus;
4026c2b520aSPrabhakar Kushwaha 	phy_interface_t enet_if;
403c517771aSPrabhakar Kushwaha 
404c517771aSPrabhakar Kushwaha 	if (net_dev->state == ETH_STATE_ACTIVE)
405c517771aSPrabhakar Kushwaha 		return 0;
406c517771aSPrabhakar Kushwaha 
407c919ab9eSPrabhakar Kushwaha 	if (get_mc_boot_status() != 0) {
408c919ab9eSPrabhakar Kushwaha 		printf("ERROR (MC is not booted)\n");
409c919ab9eSPrabhakar Kushwaha 		return -ENODEV;
410c919ab9eSPrabhakar Kushwaha 	}
411c919ab9eSPrabhakar Kushwaha 
412c919ab9eSPrabhakar Kushwaha 	if (get_dpl_apply_status() == 0) {
413c919ab9eSPrabhakar Kushwaha 		printf("ERROR (DPL is deployed. No device available)\n");
414c919ab9eSPrabhakar Kushwaha 		return -ENODEV;
415c919ab9eSPrabhakar Kushwaha 	}
4166c2b520aSPrabhakar Kushwaha 
417c919ab9eSPrabhakar Kushwaha 	/* DPMAC initialization */
418c919ab9eSPrabhakar Kushwaha 	err = ldpaa_dpmac_setup(priv);
419c919ab9eSPrabhakar Kushwaha 	if (err < 0)
420c919ab9eSPrabhakar Kushwaha 		goto err_dpmac_setup;
421c919ab9eSPrabhakar Kushwaha 
4226c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
423b7401d09SPriyanka Jain 	if (priv->phydev) {
4246c2b520aSPrabhakar Kushwaha 		err = phy_startup(priv->phydev);
4256c2b520aSPrabhakar Kushwaha 		if (err) {
4266c2b520aSPrabhakar Kushwaha 			printf("%s: Could not initialize\n",
4276c2b520aSPrabhakar Kushwaha 			       priv->phydev->dev->name);
4286c2b520aSPrabhakar Kushwaha 			goto err_dpamc_bind;
4296c2b520aSPrabhakar Kushwaha 		}
430b7401d09SPriyanka Jain 	}
4316c2b520aSPrabhakar Kushwaha #else
4326c2b520aSPrabhakar Kushwaha 	priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
4336c2b520aSPrabhakar Kushwaha 	memset(priv->phydev, 0, sizeof(struct phy_device));
4346c2b520aSPrabhakar Kushwaha 
4356c2b520aSPrabhakar Kushwaha 	priv->phydev->speed = SPEED_1000;
4366c2b520aSPrabhakar Kushwaha 	priv->phydev->link = 1;
4376c2b520aSPrabhakar Kushwaha 	priv->phydev->duplex = DUPLEX_FULL;
4386c2b520aSPrabhakar Kushwaha #endif
4396c2b520aSPrabhakar Kushwaha 
4406c2b520aSPrabhakar Kushwaha 	bus = wriop_get_mdio(priv->dpmac_id);
4416c2b520aSPrabhakar Kushwaha 	enet_if = wriop_get_enet_if(priv->dpmac_id);
4426c2b520aSPrabhakar Kushwaha 	if ((bus == NULL) &&
4436c2b520aSPrabhakar Kushwaha 	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
4446c2b520aSPrabhakar Kushwaha 		priv->phydev = (struct phy_device *)
4456c2b520aSPrabhakar Kushwaha 				malloc(sizeof(struct phy_device));
4466c2b520aSPrabhakar Kushwaha 		memset(priv->phydev, 0, sizeof(struct phy_device));
4476c2b520aSPrabhakar Kushwaha 
4486c2b520aSPrabhakar Kushwaha 		priv->phydev->speed = SPEED_10000;
4496c2b520aSPrabhakar Kushwaha 		priv->phydev->link = 1;
4506c2b520aSPrabhakar Kushwaha 		priv->phydev->duplex = DUPLEX_FULL;
4516c2b520aSPrabhakar Kushwaha 	}
4526c2b520aSPrabhakar Kushwaha 
4536c2b520aSPrabhakar Kushwaha 	if (!priv->phydev->link) {
4546c2b520aSPrabhakar Kushwaha 		printf("%s: No link.\n", priv->phydev->dev->name);
4556c2b520aSPrabhakar Kushwaha 		err = -1;
4566c2b520aSPrabhakar Kushwaha 		goto err_dpamc_bind;
4576c2b520aSPrabhakar Kushwaha 	}
4586c2b520aSPrabhakar Kushwaha 
459c919ab9eSPrabhakar Kushwaha 	/* DPMAC binding DPNI */
460c919ab9eSPrabhakar Kushwaha 	err = ldpaa_dpmac_bind(priv);
461c919ab9eSPrabhakar Kushwaha 	if (err)
462c919ab9eSPrabhakar Kushwaha 		goto err_dpamc_bind;
463c919ab9eSPrabhakar Kushwaha 
464c517771aSPrabhakar Kushwaha 	/* DPNI initialization */
465c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_setup(priv);
466c517771aSPrabhakar Kushwaha 	if (err < 0)
467c517771aSPrabhakar Kushwaha 		goto err_dpni_setup;
468c517771aSPrabhakar Kushwaha 
469c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_setup();
470c517771aSPrabhakar Kushwaha 	if (err < 0)
471c517771aSPrabhakar Kushwaha 		goto err_dpbp_setup;
472c517771aSPrabhakar Kushwaha 
473c517771aSPrabhakar Kushwaha 	/* DPNI binding DPBP */
474c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_bind(priv);
475c517771aSPrabhakar Kushwaha 	if (err)
476c919ab9eSPrabhakar Kushwaha 		goto err_dpni_bind;
477c517771aSPrabhakar Kushwaha 
4787b2edb8bSPrabhakar Kushwaha 	err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
479c919ab9eSPrabhakar Kushwaha 				dflt_dpni->dpni_handle, net_dev->enetaddr);
480c517771aSPrabhakar Kushwaha 	if (err) {
4817b2edb8bSPrabhakar Kushwaha 		printf("dpni_add_mac_addr() failed\n");
482c517771aSPrabhakar Kushwaha 		return err;
483c517771aSPrabhakar Kushwaha 	}
484c517771aSPrabhakar Kushwaha 
485c919ab9eSPrabhakar Kushwaha 	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
486c517771aSPrabhakar Kushwaha 	if (err < 0) {
487c517771aSPrabhakar Kushwaha 		printf("dpni_enable() failed\n");
488c517771aSPrabhakar Kushwaha 		return err;
489c517771aSPrabhakar Kushwaha 	}
490c517771aSPrabhakar Kushwaha 
4916c2b520aSPrabhakar Kushwaha 	dpmac_link_state.rate = priv->phydev->speed;
4926c2b520aSPrabhakar Kushwaha 
4936c2b520aSPrabhakar Kushwaha 	if (priv->phydev->autoneg == AUTONEG_DISABLE)
4946c2b520aSPrabhakar Kushwaha 		dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
4956c2b520aSPrabhakar Kushwaha 	else
4966c2b520aSPrabhakar Kushwaha 		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
4976c2b520aSPrabhakar Kushwaha 
4986c2b520aSPrabhakar Kushwaha 	if (priv->phydev->duplex == DUPLEX_HALF)
4996c2b520aSPrabhakar Kushwaha 		dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
5006c2b520aSPrabhakar Kushwaha 
5016c2b520aSPrabhakar Kushwaha 	dpmac_link_state.up = priv->phydev->link;
5026c2b520aSPrabhakar Kushwaha 
503c919ab9eSPrabhakar Kushwaha 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
504c919ab9eSPrabhakar Kushwaha 				  priv->dpmac_handle, &dpmac_link_state);
505c919ab9eSPrabhakar Kushwaha 	if (err < 0) {
506c919ab9eSPrabhakar Kushwaha 		printf("dpmac_set_link_state() failed\n");
507c919ab9eSPrabhakar Kushwaha 		return err;
508c919ab9eSPrabhakar Kushwaha 	}
5095038d3e5SPrabhakar Kushwaha 
5105038d3e5SPrabhakar Kushwaha #ifdef DEBUG
5115038d3e5SPrabhakar Kushwaha 	err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
5125038d3e5SPrabhakar Kushwaha 				  dflt_dpni->dpni_handle, &link_state);
5135038d3e5SPrabhakar Kushwaha 	if (err < 0) {
5145038d3e5SPrabhakar Kushwaha 		printf("dpni_get_link_state() failed\n");
5155038d3e5SPrabhakar Kushwaha 		return err;
5165038d3e5SPrabhakar Kushwaha 	}
5175038d3e5SPrabhakar Kushwaha 
5185038d3e5SPrabhakar Kushwaha 	printf("link status: %d - ", link_state.up);
5195038d3e5SPrabhakar Kushwaha 	link_state.up == 0 ? printf("down\n") :
5205038d3e5SPrabhakar Kushwaha 	link_state.up == 1 ? printf("up\n") : printf("error state\n");
5215038d3e5SPrabhakar Kushwaha #endif
5225038d3e5SPrabhakar Kushwaha 
523c517771aSPrabhakar Kushwaha 	/* TODO: support multiple Rx flows */
524c919ab9eSPrabhakar Kushwaha 	err = dpni_get_rx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
525c919ab9eSPrabhakar Kushwaha 			       dflt_dpni->dpni_handle, 0, 0, &rx_queue_attr);
526c517771aSPrabhakar Kushwaha 	if (err) {
527c517771aSPrabhakar Kushwaha 		printf("dpni_get_rx_flow() failed\n");
528c517771aSPrabhakar Kushwaha 		goto err_rx_flow;
529c517771aSPrabhakar Kushwaha 	}
530c517771aSPrabhakar Kushwaha 
531c517771aSPrabhakar Kushwaha 	priv->rx_dflt_fqid = rx_queue_attr.fqid;
532c517771aSPrabhakar Kushwaha 
533c919ab9eSPrabhakar Kushwaha 	err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
53487457d11SPrabhakar Kushwaha 			    &priv->tx_qdid);
535c517771aSPrabhakar Kushwaha 	if (err) {
536c517771aSPrabhakar Kushwaha 		printf("dpni_get_qdid() failed\n");
537c517771aSPrabhakar Kushwaha 		goto err_qdid;
538c517771aSPrabhakar Kushwaha 	}
539c517771aSPrabhakar Kushwaha 
5406c2b520aSPrabhakar Kushwaha 	return priv->phydev->link;
541c517771aSPrabhakar Kushwaha 
542c517771aSPrabhakar Kushwaha err_qdid:
543c517771aSPrabhakar Kushwaha err_rx_flow:
544c919ab9eSPrabhakar Kushwaha 	dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
545c919ab9eSPrabhakar Kushwaha err_dpni_bind:
546c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
547c517771aSPrabhakar Kushwaha err_dpbp_setup:
548c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
549c517771aSPrabhakar Kushwaha err_dpni_setup:
5506c2b520aSPrabhakar Kushwaha err_dpamc_bind:
5516c2b520aSPrabhakar Kushwaha 	dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
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
563c517771aSPrabhakar Kushwaha 
5645753b0f1SPrabhakar Kushwaha 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
5655753b0f1SPrabhakar Kushwaha 	    (net_dev->state == ETH_STATE_INIT))
566c517771aSPrabhakar Kushwaha 		return;
567c919ab9eSPrabhakar Kushwaha 
5685038d3e5SPrabhakar Kushwaha #ifdef DEBUG
5695038d3e5SPrabhakar Kushwaha 	ldpaa_eth_get_dpni_counter();
57044b2036eSPrabhakar Kushwaha 	ldpaa_eth_get_dpmac_counter(net_dev);
5715038d3e5SPrabhakar Kushwaha #endif
5725038d3e5SPrabhakar Kushwaha 
573c919ab9eSPrabhakar Kushwaha 	err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
574c919ab9eSPrabhakar Kushwaha 			      dflt_dprc_handle, &dpmac_endpoint);
575c919ab9eSPrabhakar Kushwaha 	if (err < 0)
576c919ab9eSPrabhakar Kushwaha 		printf("dprc_disconnect() failed dpmac_endpoint\n");
577c919ab9eSPrabhakar Kushwaha 
578c919ab9eSPrabhakar Kushwaha 	err = dpmac_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
579c919ab9eSPrabhakar Kushwaha 	if (err < 0)
580c919ab9eSPrabhakar Kushwaha 		printf("dpmac_destroy() failed\n");
581c919ab9eSPrabhakar Kushwaha 
582c517771aSPrabhakar Kushwaha 	/* Stop Tx and Rx traffic */
583c919ab9eSPrabhakar Kushwaha 	err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
584c517771aSPrabhakar Kushwaha 	if (err < 0)
585c517771aSPrabhakar Kushwaha 		printf("dpni_disable() failed\n");
586c517771aSPrabhakar Kushwaha 
587c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
5886c2b520aSPrabhakar Kushwaha 	if (priv->phydev && bus != NULL)
589c517771aSPrabhakar Kushwaha 		phy_shutdown(priv->phydev);
590a5fe87e8SPrabhakar Kushwaha 	else {
5916c2b520aSPrabhakar Kushwaha 		free(priv->phydev);
592a5fe87e8SPrabhakar Kushwaha 		priv->phydev = NULL;
593a5fe87e8SPrabhakar Kushwaha 	}
594c517771aSPrabhakar Kushwaha #endif
595c517771aSPrabhakar Kushwaha 
596c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
597c919ab9eSPrabhakar Kushwaha 	dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
598c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
599c517771aSPrabhakar Kushwaha }
600c517771aSPrabhakar Kushwaha 
601c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count)
602c517771aSPrabhakar Kushwaha {
603c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
604c517771aSPrabhakar Kushwaha 	void *addr;
605c517771aSPrabhakar Kushwaha 	int ret, i;
606c517771aSPrabhakar Kushwaha 
607c517771aSPrabhakar Kushwaha 	BUG_ON(count > 7);
608c517771aSPrabhakar Kushwaha 
609c517771aSPrabhakar Kushwaha 	do {
610c517771aSPrabhakar Kushwaha 		ret = qbman_swp_acquire(dflt_dpio->sw_portal,
611c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
612c517771aSPrabhakar Kushwaha 					buf_array, count);
613c517771aSPrabhakar Kushwaha 		if (ret < 0) {
614c517771aSPrabhakar Kushwaha 			printf("qbman_swp_acquire() failed\n");
615c517771aSPrabhakar Kushwaha 			return;
616c517771aSPrabhakar Kushwaha 		}
617c517771aSPrabhakar Kushwaha 		for (i = 0; i < ret; i++) {
618c517771aSPrabhakar Kushwaha 			addr = (void *)buf_array[i];
619c517771aSPrabhakar Kushwaha 			debug("Free: buffer addr =0x%p\n", addr);
620c517771aSPrabhakar Kushwaha 			free(addr);
621c517771aSPrabhakar Kushwaha 		}
622c517771aSPrabhakar Kushwaha 	} while (ret);
623c517771aSPrabhakar Kushwaha }
624c517771aSPrabhakar Kushwaha 
625c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void)
626c517771aSPrabhakar Kushwaha {
627c517771aSPrabhakar Kushwaha 	int i;
628c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
629c517771aSPrabhakar Kushwaha 		ldpaa_dpbp_drain_cnt(7);
630c517771aSPrabhakar Kushwaha }
631c517771aSPrabhakar Kushwaha 
632c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid)
633c517771aSPrabhakar Kushwaha {
634c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
635c517771aSPrabhakar Kushwaha 	u8 *addr;
636c517771aSPrabhakar Kushwaha 	int i;
637c517771aSPrabhakar Kushwaha 	struct qbman_release_desc rd;
638c517771aSPrabhakar Kushwaha 
639c517771aSPrabhakar Kushwaha 	for (i = 0; i < 7; i++) {
64014480454SPrabhakar Kushwaha 		addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
641c517771aSPrabhakar Kushwaha 		if (!addr) {
642c517771aSPrabhakar Kushwaha 			printf("addr allocation failed\n");
643c517771aSPrabhakar Kushwaha 			goto err_alloc;
644c517771aSPrabhakar Kushwaha 		}
645c517771aSPrabhakar Kushwaha 		memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
6465753b0f1SPrabhakar Kushwaha 		flush_dcache_range((u64)addr,
6475753b0f1SPrabhakar Kushwaha 				   (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
648c517771aSPrabhakar Kushwaha 
649c517771aSPrabhakar Kushwaha 		buf_array[i] = (uint64_t)addr;
650c517771aSPrabhakar Kushwaha 		debug("Release: buffer addr =0x%p\n", addr);
651c517771aSPrabhakar Kushwaha 	}
652c517771aSPrabhakar Kushwaha 
653c517771aSPrabhakar Kushwaha release_bufs:
654c517771aSPrabhakar Kushwaha 	/* In case the portal is busy, retry until successful.
655c517771aSPrabhakar Kushwaha 	 * This function is guaranteed to succeed in a reasonable amount
656c517771aSPrabhakar Kushwaha 	 * of time.
657c517771aSPrabhakar Kushwaha 	 */
658c517771aSPrabhakar Kushwaha 
659c517771aSPrabhakar Kushwaha 	do {
660c517771aSPrabhakar Kushwaha 		mdelay(1);
661c517771aSPrabhakar Kushwaha 		qbman_release_desc_clear(&rd);
662c517771aSPrabhakar Kushwaha 		qbman_release_desc_set_bpid(&rd, bpid);
663c517771aSPrabhakar Kushwaha 	} while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
664c517771aSPrabhakar Kushwaha 
665c517771aSPrabhakar Kushwaha 	return i;
666c517771aSPrabhakar Kushwaha 
667c517771aSPrabhakar Kushwaha err_alloc:
668c517771aSPrabhakar Kushwaha 	if (i)
669c517771aSPrabhakar Kushwaha 		goto release_bufs;
670c517771aSPrabhakar Kushwaha 
671c517771aSPrabhakar Kushwaha 	return 0;
672c517771aSPrabhakar Kushwaha }
673c517771aSPrabhakar Kushwaha 
674c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid)
675c517771aSPrabhakar Kushwaha {
676c517771aSPrabhakar Kushwaha 	int i;
677c517771aSPrabhakar Kushwaha 	int count;
678c517771aSPrabhakar Kushwaha 
679c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
680c517771aSPrabhakar Kushwaha 		count = ldpaa_bp_add_7(bpid);
681c517771aSPrabhakar Kushwaha 		if (count < 7)
682c517771aSPrabhakar Kushwaha 			printf("Buffer Seed= %d\n", count);
683c517771aSPrabhakar Kushwaha 	}
684c517771aSPrabhakar Kushwaha 
685c517771aSPrabhakar Kushwaha 	return 0;
686c517771aSPrabhakar Kushwaha }
687c517771aSPrabhakar Kushwaha 
688c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void)
689c517771aSPrabhakar Kushwaha {
690c517771aSPrabhakar Kushwaha 	int err;
691c517771aSPrabhakar Kushwaha 
69287457d11SPrabhakar Kushwaha 	err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
693c517771aSPrabhakar Kushwaha 			&dflt_dpbp->dpbp_handle);
694c517771aSPrabhakar Kushwaha 	if (err) {
695c517771aSPrabhakar Kushwaha 		printf("dpbp_open() failed\n");
696c517771aSPrabhakar Kushwaha 		goto err_open;
697c517771aSPrabhakar Kushwaha 	}
698c517771aSPrabhakar Kushwaha 
69987457d11SPrabhakar Kushwaha 	err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
700c517771aSPrabhakar Kushwaha 	if (err) {
701c517771aSPrabhakar Kushwaha 		printf("dpbp_enable() failed\n");
702c517771aSPrabhakar Kushwaha 		goto err_enable;
703c517771aSPrabhakar Kushwaha 	}
704c517771aSPrabhakar Kushwaha 
70587457d11SPrabhakar Kushwaha 	err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
70687457d11SPrabhakar Kushwaha 				  dflt_dpbp->dpbp_handle,
707c517771aSPrabhakar Kushwaha 				  &dflt_dpbp->dpbp_attr);
708c517771aSPrabhakar Kushwaha 	if (err) {
709c517771aSPrabhakar Kushwaha 		printf("dpbp_get_attributes() failed\n");
710c517771aSPrabhakar Kushwaha 		goto err_get_attr;
711c517771aSPrabhakar Kushwaha 	}
712c517771aSPrabhakar Kushwaha 
713c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
714c517771aSPrabhakar Kushwaha 	if (err) {
715c517771aSPrabhakar Kushwaha 		printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
716c517771aSPrabhakar Kushwaha 		       dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
717c517771aSPrabhakar Kushwaha 		goto err_seed;
718c517771aSPrabhakar Kushwaha 	}
719c517771aSPrabhakar Kushwaha 
720c517771aSPrabhakar Kushwaha 	return 0;
721c517771aSPrabhakar Kushwaha 
722c517771aSPrabhakar Kushwaha err_seed:
723c517771aSPrabhakar Kushwaha err_get_attr:
72487457d11SPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
725c517771aSPrabhakar Kushwaha err_enable:
72687457d11SPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
727c517771aSPrabhakar Kushwaha err_open:
728c517771aSPrabhakar Kushwaha 	return err;
729c517771aSPrabhakar Kushwaha }
730c517771aSPrabhakar Kushwaha 
731c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void)
732c517771aSPrabhakar Kushwaha {
733c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_drain();
73487457d11SPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
73587457d11SPrabhakar Kushwaha 	dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
73687457d11SPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
737c517771aSPrabhakar Kushwaha }
738c517771aSPrabhakar Kushwaha 
7399a696f56SPrabhakar Kushwaha static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
7409a696f56SPrabhakar Kushwaha 				     struct ldpaa_eth_priv *priv)
7419a696f56SPrabhakar Kushwaha {
7429a696f56SPrabhakar Kushwaha 	struct dpmac_attr attr;
7439a696f56SPrabhakar Kushwaha 	int error;
7449a696f56SPrabhakar Kushwaha 
7459a696f56SPrabhakar Kushwaha 	memset(&attr, 0, sizeof(struct dpmac_attr));
7469a696f56SPrabhakar Kushwaha 	error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS,
7479a696f56SPrabhakar Kushwaha 				     priv->dpmac_handle,
7489a696f56SPrabhakar Kushwaha 				     &attr);
7499a696f56SPrabhakar Kushwaha 	if (error == 0) {
7509a696f56SPrabhakar Kushwaha 		if ((attr.version.major != DPMAC_VER_MAJOR) ||
7519a696f56SPrabhakar Kushwaha 		    (attr.version.minor != DPMAC_VER_MINOR)) {
7529a696f56SPrabhakar Kushwaha 			printf("DPMAC version mismatch found %u.%u,",
7539a696f56SPrabhakar Kushwaha 			       attr.version.major, attr.version.minor);
7549a696f56SPrabhakar Kushwaha 			printf("supported version is %u.%u\n",
7559a696f56SPrabhakar Kushwaha 			       DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
7569a696f56SPrabhakar Kushwaha 		}
7579a696f56SPrabhakar Kushwaha 	}
7589a696f56SPrabhakar Kushwaha 
7599a696f56SPrabhakar Kushwaha 	return error;
7609a696f56SPrabhakar Kushwaha }
7619a696f56SPrabhakar Kushwaha 
762c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
763c919ab9eSPrabhakar Kushwaha {
764c919ab9eSPrabhakar Kushwaha 	int err = 0;
765c919ab9eSPrabhakar Kushwaha 	struct dpmac_cfg dpmac_cfg;
766c919ab9eSPrabhakar Kushwaha 
767c919ab9eSPrabhakar Kushwaha 	dpmac_cfg.mac_id = priv->dpmac_id;
768c919ab9eSPrabhakar Kushwaha 	err = dpmac_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpmac_cfg,
769c919ab9eSPrabhakar Kushwaha 			  &priv->dpmac_handle);
770c919ab9eSPrabhakar Kushwaha 	if (err)
771c919ab9eSPrabhakar Kushwaha 		printf("dpmac_create() failed\n");
7729a696f56SPrabhakar Kushwaha 
7739a696f56SPrabhakar Kushwaha 	err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
7749a696f56SPrabhakar Kushwaha 	if (err < 0)
7759a696f56SPrabhakar Kushwaha 		printf("ldpaa_dpmac_version_check() failed: %d\n", err);
7769a696f56SPrabhakar Kushwaha 
777c919ab9eSPrabhakar Kushwaha 	return err;
778c919ab9eSPrabhakar Kushwaha }
779c919ab9eSPrabhakar Kushwaha 
780c919ab9eSPrabhakar Kushwaha static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
781c919ab9eSPrabhakar Kushwaha {
782c919ab9eSPrabhakar Kushwaha 	int err = 0;
783c919ab9eSPrabhakar Kushwaha 	struct dprc_connection_cfg dprc_connection_cfg = {
784c919ab9eSPrabhakar Kushwaha 		/* If both rates are zero the connection */
785c919ab9eSPrabhakar Kushwaha 		/* will be configured in "best effort" mode. */
786c919ab9eSPrabhakar Kushwaha 		.committed_rate = 0,
787c919ab9eSPrabhakar Kushwaha 		.max_rate = 0
788c919ab9eSPrabhakar Kushwaha 	};
789c919ab9eSPrabhakar Kushwaha 
7905038d3e5SPrabhakar Kushwaha #ifdef DEBUG
7915038d3e5SPrabhakar Kushwaha 	struct dprc_endpoint dbg_endpoint;
7925038d3e5SPrabhakar Kushwaha 	int state = 0;
7935038d3e5SPrabhakar Kushwaha #endif
7945038d3e5SPrabhakar Kushwaha 
795c919ab9eSPrabhakar Kushwaha 	memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
796192bc694SBen Whitten 	strcpy(dpmac_endpoint.type, "dpmac");
797c919ab9eSPrabhakar Kushwaha 	dpmac_endpoint.id = priv->dpmac_id;
798c919ab9eSPrabhakar Kushwaha 
799c919ab9eSPrabhakar Kushwaha 	memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
800192bc694SBen Whitten 	strcpy(dpni_endpoint.type, "dpni");
801c919ab9eSPrabhakar Kushwaha 	dpni_endpoint.id = dflt_dpni->dpni_id;
802c919ab9eSPrabhakar Kushwaha 
803c919ab9eSPrabhakar Kushwaha 	err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
804c919ab9eSPrabhakar Kushwaha 			     dflt_dprc_handle,
805c919ab9eSPrabhakar Kushwaha 			     &dpmac_endpoint,
806c919ab9eSPrabhakar Kushwaha 			     &dpni_endpoint,
807c919ab9eSPrabhakar Kushwaha 			     &dprc_connection_cfg);
8085038d3e5SPrabhakar Kushwaha 	if (err)
8095038d3e5SPrabhakar Kushwaha 		printf("dprc_connect() failed\n");
8105038d3e5SPrabhakar Kushwaha 
8115038d3e5SPrabhakar Kushwaha #ifdef DEBUG
8125038d3e5SPrabhakar Kushwaha 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
8135038d3e5SPrabhakar Kushwaha 				    dflt_dprc_handle, &dpni_endpoint,
8145038d3e5SPrabhakar Kushwaha 				    &dbg_endpoint, &state);
8155038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
8165038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
8175038d3e5SPrabhakar Kushwaha 	printf("%s, DPMAC State= %d\n", __func__, state);
8185038d3e5SPrabhakar Kushwaha 
8195038d3e5SPrabhakar Kushwaha 	memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
8205038d3e5SPrabhakar Kushwaha 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
8215038d3e5SPrabhakar Kushwaha 				    dflt_dprc_handle, &dpmac_endpoint,
8225038d3e5SPrabhakar Kushwaha 				    &dbg_endpoint, &state);
8235038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
8245038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
8255038d3e5SPrabhakar Kushwaha 	printf("%s, DPNI State= %d\n", __func__, state);
8265038d3e5SPrabhakar Kushwaha #endif
827c919ab9eSPrabhakar Kushwaha 	return err;
828c919ab9eSPrabhakar Kushwaha }
829c919ab9eSPrabhakar Kushwaha 
830c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
831c517771aSPrabhakar Kushwaha {
832c517771aSPrabhakar Kushwaha 	int err;
833c517771aSPrabhakar Kushwaha 
834c517771aSPrabhakar Kushwaha 	/* and get a handle for the DPNI this interface is associate with */
835c919ab9eSPrabhakar Kushwaha 	err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
836c919ab9eSPrabhakar Kushwaha 			&dflt_dpni->dpni_handle);
837c517771aSPrabhakar Kushwaha 	if (err) {
838c517771aSPrabhakar Kushwaha 		printf("dpni_open() failed\n");
839c517771aSPrabhakar Kushwaha 		goto err_open;
840c517771aSPrabhakar Kushwaha 	}
841c517771aSPrabhakar Kushwaha 
84287457d11SPrabhakar Kushwaha 	err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
843c919ab9eSPrabhakar Kushwaha 				  dflt_dpni->dpni_handle,
844c919ab9eSPrabhakar Kushwaha 				  &dflt_dpni->dpni_attrs);
845c517771aSPrabhakar Kushwaha 	if (err) {
846c517771aSPrabhakar Kushwaha 		printf("dpni_get_attributes() failed (err=%d)\n", err);
847c517771aSPrabhakar Kushwaha 		goto err_get_attr;
848c517771aSPrabhakar Kushwaha 	}
849c517771aSPrabhakar Kushwaha 
850c517771aSPrabhakar Kushwaha 	/* Configure our buffers' layout */
851c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
852c517771aSPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
85314480454SPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
85414480454SPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
855c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.pass_parser_result = true;
856c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.pass_frame_status = true;
857c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
85814480454SPrabhakar Kushwaha 	/* HW erratum mandates data alignment in multiples of 256 */
85914480454SPrabhakar Kushwaha 	dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
860c517771aSPrabhakar Kushwaha 	/* ...rx, ... */
86187457d11SPrabhakar Kushwaha 	err = dpni_set_rx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
862c919ab9eSPrabhakar Kushwaha 					dflt_dpni->dpni_handle,
863c919ab9eSPrabhakar Kushwaha 					&dflt_dpni->buf_layout);
864c517771aSPrabhakar Kushwaha 	if (err) {
865c517771aSPrabhakar Kushwaha 		printf("dpni_set_rx_buffer_layout() failed");
866c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
867c517771aSPrabhakar Kushwaha 	}
868c517771aSPrabhakar Kushwaha 
869c517771aSPrabhakar Kushwaha 	/* ... tx, ... */
87014480454SPrabhakar Kushwaha 	/* remove Rx-only options */
87114480454SPrabhakar Kushwaha 	dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
87214480454SPrabhakar Kushwaha 				      DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
87387457d11SPrabhakar Kushwaha 	err = dpni_set_tx_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
874c919ab9eSPrabhakar Kushwaha 					dflt_dpni->dpni_handle,
875c919ab9eSPrabhakar Kushwaha 					&dflt_dpni->buf_layout);
876c517771aSPrabhakar Kushwaha 	if (err) {
877c517771aSPrabhakar Kushwaha 		printf("dpni_set_tx_buffer_layout() failed");
878c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
879c517771aSPrabhakar Kushwaha 	}
880c517771aSPrabhakar Kushwaha 
881c517771aSPrabhakar Kushwaha 	/* ... tx-confirm. */
882c919ab9eSPrabhakar Kushwaha 	dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
88387457d11SPrabhakar Kushwaha 	err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
884c919ab9eSPrabhakar Kushwaha 					     dflt_dpni->dpni_handle,
885c919ab9eSPrabhakar Kushwaha 					     &dflt_dpni->buf_layout);
886c517771aSPrabhakar Kushwaha 	if (err) {
887c517771aSPrabhakar Kushwaha 		printf("dpni_set_tx_conf_buffer_layout() failed");
888c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
889c517771aSPrabhakar Kushwaha 	}
890c517771aSPrabhakar Kushwaha 
891c517771aSPrabhakar Kushwaha 	/* Now that we've set our tx buffer layout, retrieve the minimum
892c517771aSPrabhakar Kushwaha 	 * required tx data offset.
893c517771aSPrabhakar Kushwaha 	 */
89487457d11SPrabhakar Kushwaha 	err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
895c919ab9eSPrabhakar Kushwaha 				      dflt_dpni->dpni_handle,
896c919ab9eSPrabhakar Kushwaha 				      &priv->tx_data_offset);
897c517771aSPrabhakar Kushwaha 	if (err) {
898c517771aSPrabhakar Kushwaha 		printf("dpni_get_tx_data_offset() failed\n");
899c517771aSPrabhakar Kushwaha 		goto err_data_offset;
900c517771aSPrabhakar Kushwaha 	}
901c517771aSPrabhakar Kushwaha 
902c517771aSPrabhakar Kushwaha 	/* Warn in case TX data offset is not multiple of 64 bytes. */
903c517771aSPrabhakar Kushwaha 	WARN_ON(priv->tx_data_offset % 64);
904c517771aSPrabhakar Kushwaha 
905c517771aSPrabhakar Kushwaha 	/* Accomodate SWA space. */
906c517771aSPrabhakar Kushwaha 	priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
907c517771aSPrabhakar Kushwaha 	debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
908c517771aSPrabhakar Kushwaha 
909c517771aSPrabhakar Kushwaha 	return 0;
910c517771aSPrabhakar Kushwaha 
911c517771aSPrabhakar Kushwaha err_data_offset:
912c517771aSPrabhakar Kushwaha err_buf_layout:
913c517771aSPrabhakar Kushwaha err_get_attr:
914c919ab9eSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
915c517771aSPrabhakar Kushwaha err_open:
916c517771aSPrabhakar Kushwaha 	return err;
917c517771aSPrabhakar Kushwaha }
918c517771aSPrabhakar Kushwaha 
919c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
920c517771aSPrabhakar Kushwaha {
921c517771aSPrabhakar Kushwaha 	struct dpni_pools_cfg pools_params;
922c517771aSPrabhakar Kushwaha 	struct dpni_tx_flow_cfg dflt_tx_flow;
9236073548aSPrabhakar Kushwaha 	struct dpni_tx_conf_cfg tx_conf_cfg;
924c517771aSPrabhakar Kushwaha 	int err = 0;
925c517771aSPrabhakar Kushwaha 
92631a48cf4SPrabhakar Kushwaha 	memset(&pools_params, 0, sizeof(pools_params));
927c517771aSPrabhakar Kushwaha 	pools_params.num_dpbp = 1;
928c517771aSPrabhakar Kushwaha 	pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
929c517771aSPrabhakar Kushwaha 	pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
930c919ab9eSPrabhakar Kushwaha 	err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
931c919ab9eSPrabhakar Kushwaha 			     dflt_dpni->dpni_handle, &pools_params);
932c517771aSPrabhakar Kushwaha 	if (err) {
933c517771aSPrabhakar Kushwaha 		printf("dpni_set_pools() failed\n");
934c517771aSPrabhakar Kushwaha 		return err;
935c517771aSPrabhakar Kushwaha 	}
936c517771aSPrabhakar Kushwaha 
937c517771aSPrabhakar Kushwaha 	priv->tx_flow_id = DPNI_NEW_FLOW_ID;
938c517771aSPrabhakar Kushwaha 	memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
939c517771aSPrabhakar Kushwaha 
94053e353fcSPrabhakar Kushwaha 	dflt_tx_flow.use_common_tx_conf_queue = 0;
941c919ab9eSPrabhakar Kushwaha 	err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
942c919ab9eSPrabhakar Kushwaha 			       dflt_dpni->dpni_handle, &priv->tx_flow_id,
943c919ab9eSPrabhakar Kushwaha 			       &dflt_tx_flow);
944c517771aSPrabhakar Kushwaha 	if (err) {
945c517771aSPrabhakar Kushwaha 		printf("dpni_set_tx_flow() failed\n");
946c517771aSPrabhakar Kushwaha 		return err;
947c517771aSPrabhakar Kushwaha 	}
948c517771aSPrabhakar Kushwaha 
9496073548aSPrabhakar Kushwaha 	memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg));
9506073548aSPrabhakar Kushwaha 	tx_conf_cfg.errors_only = true;
9516073548aSPrabhakar Kushwaha 	/*Set tx-conf and error configuration*/
9526073548aSPrabhakar Kushwaha 	err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS,
9536073548aSPrabhakar Kushwaha 			       dflt_dpni->dpni_handle,
9546073548aSPrabhakar Kushwaha 			       priv->tx_flow_id, &tx_conf_cfg);
9556073548aSPrabhakar Kushwaha 	if (err) {
9566073548aSPrabhakar Kushwaha 		printf("dpni_set_tx_conf() failed\n");
9576073548aSPrabhakar Kushwaha 		return err;
9586073548aSPrabhakar Kushwaha 	}
9596073548aSPrabhakar Kushwaha 
960c517771aSPrabhakar Kushwaha 	return 0;
961c517771aSPrabhakar Kushwaha }
962c517771aSPrabhakar Kushwaha 
963c919ab9eSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
964c919ab9eSPrabhakar Kushwaha 				 phy_interface_t enet_if)
965c517771aSPrabhakar Kushwaha {
966c517771aSPrabhakar Kushwaha 	int err;
967c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
968c517771aSPrabhakar Kushwaha 
969c919ab9eSPrabhakar Kushwaha 	sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id,
970c919ab9eSPrabhakar Kushwaha 		phy_interface_strings[enet_if]);
971c517771aSPrabhakar Kushwaha 
972c517771aSPrabhakar Kushwaha 	net_dev->iobase = 0;
973c517771aSPrabhakar Kushwaha 	net_dev->init = ldpaa_eth_open;
974c517771aSPrabhakar Kushwaha 	net_dev->halt = ldpaa_eth_stop;
975c517771aSPrabhakar Kushwaha 	net_dev->send = ldpaa_eth_tx;
976c517771aSPrabhakar Kushwaha 	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
977c517771aSPrabhakar Kushwaha 
9786c2b520aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
9796c2b520aSPrabhakar Kushwaha 	err = init_phy(net_dev);
9806c2b520aSPrabhakar Kushwaha 	if (err < 0)
9816c2b520aSPrabhakar Kushwaha 		return err;
9826c2b520aSPrabhakar Kushwaha #endif
983c517771aSPrabhakar Kushwaha 
984c517771aSPrabhakar Kushwaha 	err = eth_register(net_dev);
985c517771aSPrabhakar Kushwaha 	if (err < 0) {
986c517771aSPrabhakar Kushwaha 		printf("eth_register() = %d\n", err);
987c517771aSPrabhakar Kushwaha 		return err;
988c517771aSPrabhakar Kushwaha 	}
989c517771aSPrabhakar Kushwaha 
990c517771aSPrabhakar Kushwaha 	return 0;
991c517771aSPrabhakar Kushwaha }
992c517771aSPrabhakar Kushwaha 
993c919ab9eSPrabhakar Kushwaha int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
994c517771aSPrabhakar Kushwaha {
995c517771aSPrabhakar Kushwaha 	struct eth_device		*net_dev = NULL;
996c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv		*priv = NULL;
997c517771aSPrabhakar Kushwaha 	int				err = 0;
998c517771aSPrabhakar Kushwaha 
999c517771aSPrabhakar Kushwaha 
1000c517771aSPrabhakar Kushwaha 	/* Net device */
1001c517771aSPrabhakar Kushwaha 	net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
1002c517771aSPrabhakar Kushwaha 	if (!net_dev) {
1003c517771aSPrabhakar Kushwaha 		printf("eth_device malloc() failed\n");
1004c517771aSPrabhakar Kushwaha 		return -ENOMEM;
1005c517771aSPrabhakar Kushwaha 	}
1006c517771aSPrabhakar Kushwaha 	memset(net_dev, 0, sizeof(struct eth_device));
1007c517771aSPrabhakar Kushwaha 
1008c517771aSPrabhakar Kushwaha 	/* alloc the ldpaa ethernet private struct */
1009c517771aSPrabhakar Kushwaha 	priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1010c517771aSPrabhakar Kushwaha 	if (!priv) {
1011c517771aSPrabhakar Kushwaha 		printf("ldpaa_eth_priv malloc() failed\n");
1012c517771aSPrabhakar Kushwaha 		return -ENOMEM;
1013c517771aSPrabhakar Kushwaha 	}
1014c517771aSPrabhakar Kushwaha 	memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1015c517771aSPrabhakar Kushwaha 
1016c517771aSPrabhakar Kushwaha 	net_dev->priv = (void *)priv;
1017c517771aSPrabhakar Kushwaha 	priv->net_dev = (struct eth_device *)net_dev;
1018c919ab9eSPrabhakar Kushwaha 	priv->dpmac_id = dpmac_id;
1019c919ab9eSPrabhakar Kushwaha 	debug("%s dpmac_id=%d\n", __func__, dpmac_id);
1020c517771aSPrabhakar Kushwaha 
1021c919ab9eSPrabhakar Kushwaha 	err = ldpaa_eth_netdev_init(net_dev, enet_if);
1022c517771aSPrabhakar Kushwaha 	if (err)
1023c517771aSPrabhakar Kushwaha 		goto err_netdev_init;
1024c517771aSPrabhakar Kushwaha 
1025c517771aSPrabhakar Kushwaha 	debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1026c517771aSPrabhakar Kushwaha 	return 0;
1027c517771aSPrabhakar Kushwaha 
1028c517771aSPrabhakar Kushwaha err_netdev_init:
1029c517771aSPrabhakar Kushwaha 	free(priv);
1030c517771aSPrabhakar Kushwaha 	net_dev->priv = NULL;
1031c517771aSPrabhakar Kushwaha 	free(net_dev);
1032c517771aSPrabhakar Kushwaha 
1033c517771aSPrabhakar Kushwaha 	return err;
1034c517771aSPrabhakar Kushwaha }
1035