xref: /openbmc/u-boot/drivers/net/ldpaa_eth/ldpaa_eth.c (revision c517771ae745dbba59112b8d311e41d37c0fc032)
1*c517771aSPrabhakar Kushwaha /*
2*c517771aSPrabhakar Kushwaha  * Copyright (C) 2014 Freescale Semiconductor
3*c517771aSPrabhakar Kushwaha  *
4*c517771aSPrabhakar Kushwaha  * SPDX-License-Identifier:	GPL-2.0+
5*c517771aSPrabhakar Kushwaha  */
6*c517771aSPrabhakar Kushwaha 
7*c517771aSPrabhakar Kushwaha #include <common.h>
8*c517771aSPrabhakar Kushwaha #include <asm/io.h>
9*c517771aSPrabhakar Kushwaha #include <asm/types.h>
10*c517771aSPrabhakar Kushwaha #include <malloc.h>
11*c517771aSPrabhakar Kushwaha #include <net.h>
12*c517771aSPrabhakar Kushwaha #include <hwconfig.h>
13*c517771aSPrabhakar Kushwaha #include <phy.h>
14*c517771aSPrabhakar Kushwaha #include <linux/compat.h>
15*c517771aSPrabhakar Kushwaha 
16*c517771aSPrabhakar Kushwaha #include "ldpaa_eth.h"
17*c517771aSPrabhakar Kushwaha 
18*c517771aSPrabhakar Kushwaha static int init_phy(struct eth_device *dev)
19*c517771aSPrabhakar Kushwaha {
20*c517771aSPrabhakar Kushwaha 	/*TODO for external PHY */
21*c517771aSPrabhakar Kushwaha 
22*c517771aSPrabhakar Kushwaha 	return 0;
23*c517771aSPrabhakar Kushwaha }
24*c517771aSPrabhakar Kushwaha 
25*c517771aSPrabhakar Kushwaha static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
26*c517771aSPrabhakar Kushwaha 			 const struct dpaa_fd *fd)
27*c517771aSPrabhakar Kushwaha {
28*c517771aSPrabhakar Kushwaha 	u64 fd_addr;
29*c517771aSPrabhakar Kushwaha 	uint16_t fd_offset;
30*c517771aSPrabhakar Kushwaha 	uint32_t fd_length;
31*c517771aSPrabhakar Kushwaha 	struct ldpaa_fas *fas;
32*c517771aSPrabhakar Kushwaha 	uint32_t status, err;
33*c517771aSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
34*c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
35*c517771aSPrabhakar Kushwaha 
36*c517771aSPrabhakar Kushwaha 	invalidate_dcache_all();
37*c517771aSPrabhakar Kushwaha 
38*c517771aSPrabhakar Kushwaha 	fd_addr = ldpaa_fd_get_addr(fd);
39*c517771aSPrabhakar Kushwaha 	fd_offset = ldpaa_fd_get_offset(fd);
40*c517771aSPrabhakar Kushwaha 	fd_length = ldpaa_fd_get_len(fd);
41*c517771aSPrabhakar Kushwaha 
42*c517771aSPrabhakar Kushwaha 	debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
43*c517771aSPrabhakar Kushwaha 
44*c517771aSPrabhakar Kushwaha 	if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
45*c517771aSPrabhakar Kushwaha 		/* Read the frame annotation status word and check for errors */
46*c517771aSPrabhakar Kushwaha 		fas = (struct ldpaa_fas *)
47*c517771aSPrabhakar Kushwaha 				((uint8_t *)(fd_addr) +
48*c517771aSPrabhakar Kushwaha 				priv->buf_layout.private_data_size);
49*c517771aSPrabhakar Kushwaha 		status = le32_to_cpu(fas->status);
50*c517771aSPrabhakar Kushwaha 		if (status & LDPAA_ETH_RX_ERR_MASK) {
51*c517771aSPrabhakar Kushwaha 			printf("Rx frame error(s): 0x%08x\n",
52*c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_ERR_MASK);
53*c517771aSPrabhakar Kushwaha 			goto error;
54*c517771aSPrabhakar Kushwaha 		} else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
55*c517771aSPrabhakar Kushwaha 			printf("Unsupported feature in bitmask: 0x%08x\n",
56*c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_RX_UNSUPP_MASK);
57*c517771aSPrabhakar Kushwaha 			goto error;
58*c517771aSPrabhakar Kushwaha 		}
59*c517771aSPrabhakar Kushwaha 	}
60*c517771aSPrabhakar Kushwaha 
61*c517771aSPrabhakar Kushwaha 	debug("Rx frame: To Upper layer\n");
62*c517771aSPrabhakar Kushwaha 	net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
63*c517771aSPrabhakar Kushwaha 				    fd_length);
64*c517771aSPrabhakar Kushwaha 
65*c517771aSPrabhakar Kushwaha error:
66*c517771aSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
67*c517771aSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
68*c517771aSPrabhakar Kushwaha 	do {
69*c517771aSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
70*c517771aSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
71*c517771aSPrabhakar Kushwaha 	} while (err == -EBUSY);
72*c517771aSPrabhakar Kushwaha 	return;
73*c517771aSPrabhakar Kushwaha }
74*c517771aSPrabhakar Kushwaha 
75*c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
76*c517771aSPrabhakar Kushwaha {
77*c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
78*c517771aSPrabhakar Kushwaha 	const struct ldpaa_dq *dq;
79*c517771aSPrabhakar Kushwaha 	const struct dpaa_fd *fd;
80*c517771aSPrabhakar Kushwaha 	int i = 5, err = 0, status;
81*c517771aSPrabhakar Kushwaha 	static struct qbman_pull_desc pulldesc;
82*c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
83*c517771aSPrabhakar Kushwaha 
84*c517771aSPrabhakar Kushwaha 	qbman_pull_desc_clear(&pulldesc);
85*c517771aSPrabhakar Kushwaha 	qbman_pull_desc_set_numframes(&pulldesc, 1);
86*c517771aSPrabhakar Kushwaha 	qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
87*c517771aSPrabhakar Kushwaha 
88*c517771aSPrabhakar Kushwaha 	while (--i) {
89*c517771aSPrabhakar Kushwaha 		err = qbman_swp_pull(swp, &pulldesc);
90*c517771aSPrabhakar Kushwaha 		if (err < 0) {
91*c517771aSPrabhakar Kushwaha 			printf("Dequeue frames error:0x%08x\n", err);
92*c517771aSPrabhakar Kushwaha 			continue;
93*c517771aSPrabhakar Kushwaha 		}
94*c517771aSPrabhakar Kushwaha 
95*c517771aSPrabhakar Kushwaha 		dq = qbman_swp_dqrr_next(swp);
96*c517771aSPrabhakar Kushwaha 		if (dq) {
97*c517771aSPrabhakar Kushwaha 			/* Check for valid frame. If not sent a consume
98*c517771aSPrabhakar Kushwaha 			 * confirmation to QBMAN otherwise give it to NADK
99*c517771aSPrabhakar Kushwaha 			 * application and then send consume confirmation to
100*c517771aSPrabhakar Kushwaha 			 * QBMAN.
101*c517771aSPrabhakar Kushwaha 			 */
102*c517771aSPrabhakar Kushwaha 			status = (uint8_t)ldpaa_dq_flags(dq);
103*c517771aSPrabhakar Kushwaha 			if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
104*c517771aSPrabhakar Kushwaha 				debug("Dequeue RX frames:");
105*c517771aSPrabhakar Kushwaha 				debug("No frame delivered\n");
106*c517771aSPrabhakar Kushwaha 
107*c517771aSPrabhakar Kushwaha 				qbman_swp_dqrr_consume(swp, dq);
108*c517771aSPrabhakar Kushwaha 				break;
109*c517771aSPrabhakar Kushwaha 			}
110*c517771aSPrabhakar Kushwaha 
111*c517771aSPrabhakar Kushwaha 			fd = ldpaa_dq_fd(dq);
112*c517771aSPrabhakar Kushwaha 
113*c517771aSPrabhakar Kushwaha 			/* Obtain FD and process it */
114*c517771aSPrabhakar Kushwaha 			ldpaa_eth_rx(priv, fd);
115*c517771aSPrabhakar Kushwaha 			qbman_swp_dqrr_consume(swp, dq);
116*c517771aSPrabhakar Kushwaha 			break;
117*c517771aSPrabhakar Kushwaha 		}
118*c517771aSPrabhakar Kushwaha 	}
119*c517771aSPrabhakar Kushwaha 
120*c517771aSPrabhakar Kushwaha 	return err;
121*c517771aSPrabhakar Kushwaha }
122*c517771aSPrabhakar Kushwaha 
123*c517771aSPrabhakar Kushwaha static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv,
124*c517771aSPrabhakar Kushwaha 			      const struct dpaa_fd *fd)
125*c517771aSPrabhakar Kushwaha {
126*c517771aSPrabhakar Kushwaha 	uint64_t fd_addr;
127*c517771aSPrabhakar Kushwaha 	struct ldpaa_fas *fas;
128*c517771aSPrabhakar Kushwaha 	uint32_t status, err;
129*c517771aSPrabhakar Kushwaha 	struct qbman_release_desc releasedesc;
130*c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
131*c517771aSPrabhakar Kushwaha 
132*c517771aSPrabhakar Kushwaha 	invalidate_dcache_all();
133*c517771aSPrabhakar Kushwaha 	fd_addr = ldpaa_fd_get_addr(fd);
134*c517771aSPrabhakar Kushwaha 
135*c517771aSPrabhakar Kushwaha 
136*c517771aSPrabhakar Kushwaha 	debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr);
137*c517771aSPrabhakar Kushwaha 
138*c517771aSPrabhakar Kushwaha 	/* Check the status from the Frame Annotation */
139*c517771aSPrabhakar Kushwaha 	if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
140*c517771aSPrabhakar Kushwaha 		fas = (struct ldpaa_fas *)
141*c517771aSPrabhakar Kushwaha 				((uint8_t *)(fd_addr) +
142*c517771aSPrabhakar Kushwaha 				priv->buf_layout.private_data_size);
143*c517771aSPrabhakar Kushwaha 		status = le32_to_cpu(fas->status);
144*c517771aSPrabhakar Kushwaha 		if (status & LDPAA_ETH_TXCONF_ERR_MASK) {
145*c517771aSPrabhakar Kushwaha 			printf("TxConf frame error(s): 0x%08x\n",
146*c517771aSPrabhakar Kushwaha 			       status & LDPAA_ETH_TXCONF_ERR_MASK);
147*c517771aSPrabhakar Kushwaha 		}
148*c517771aSPrabhakar Kushwaha 	}
149*c517771aSPrabhakar Kushwaha 
150*c517771aSPrabhakar Kushwaha 	qbman_release_desc_clear(&releasedesc);
151*c517771aSPrabhakar Kushwaha 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
152*c517771aSPrabhakar Kushwaha 	do {
153*c517771aSPrabhakar Kushwaha 		/* Release buffer into the QBMAN */
154*c517771aSPrabhakar Kushwaha 		err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
155*c517771aSPrabhakar Kushwaha 	} while (err == -EBUSY);
156*c517771aSPrabhakar Kushwaha }
157*c517771aSPrabhakar Kushwaha 
158*c517771aSPrabhakar Kushwaha static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)
159*c517771aSPrabhakar Kushwaha {
160*c517771aSPrabhakar Kushwaha 	const struct ldpaa_dq *dq;
161*c517771aSPrabhakar Kushwaha 	const struct dpaa_fd *fd;
162*c517771aSPrabhakar Kushwaha 	int err = 0;
163*c517771aSPrabhakar Kushwaha 	int i = 5, status;
164*c517771aSPrabhakar Kushwaha 	static struct qbman_pull_desc pulldesc;
165*c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
166*c517771aSPrabhakar Kushwaha 
167*c517771aSPrabhakar Kushwaha 	qbman_pull_desc_clear(&pulldesc);
168*c517771aSPrabhakar Kushwaha 	qbman_pull_desc_set_numframes(&pulldesc, 1);
169*c517771aSPrabhakar Kushwaha 	qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid);
170*c517771aSPrabhakar Kushwaha 
171*c517771aSPrabhakar Kushwaha 	while (--i) {
172*c517771aSPrabhakar Kushwaha 		err =  qbman_swp_pull(swp, &pulldesc);
173*c517771aSPrabhakar Kushwaha 		if (err < 0) {
174*c517771aSPrabhakar Kushwaha 			printf("Dequeue TX conf frames error:0x%08x\n", err);
175*c517771aSPrabhakar Kushwaha 			continue;
176*c517771aSPrabhakar Kushwaha 		}
177*c517771aSPrabhakar Kushwaha 
178*c517771aSPrabhakar Kushwaha 		dq = qbman_swp_dqrr_next(swp);
179*c517771aSPrabhakar Kushwaha 		if (dq) {
180*c517771aSPrabhakar Kushwaha 			/* Check for valid frame. If not sent a consume
181*c517771aSPrabhakar Kushwaha 			 * confirmation to QBMAN otherwise give it to NADK
182*c517771aSPrabhakar Kushwaha 			 * application and then send consume confirmation to
183*c517771aSPrabhakar Kushwaha 			 * QBMAN.
184*c517771aSPrabhakar Kushwaha 			 */
185*c517771aSPrabhakar Kushwaha 			status = (uint8_t)ldpaa_dq_flags(dq);
186*c517771aSPrabhakar Kushwaha 			if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
187*c517771aSPrabhakar Kushwaha 				debug("Dequeue TX conf frames:");
188*c517771aSPrabhakar Kushwaha 				debug("No frame is delivered\n");
189*c517771aSPrabhakar Kushwaha 
190*c517771aSPrabhakar Kushwaha 				qbman_swp_dqrr_consume(swp, dq);
191*c517771aSPrabhakar Kushwaha 				break;
192*c517771aSPrabhakar Kushwaha 			}
193*c517771aSPrabhakar Kushwaha 			fd = ldpaa_dq_fd(dq);
194*c517771aSPrabhakar Kushwaha 
195*c517771aSPrabhakar Kushwaha 			ldpaa_eth_tx_conf(priv, fd);
196*c517771aSPrabhakar Kushwaha 			qbman_swp_dqrr_consume(swp, dq);
197*c517771aSPrabhakar Kushwaha 			break;
198*c517771aSPrabhakar Kushwaha 		}
199*c517771aSPrabhakar Kushwaha 	}
200*c517771aSPrabhakar Kushwaha 
201*c517771aSPrabhakar Kushwaha 	return err;
202*c517771aSPrabhakar Kushwaha }
203*c517771aSPrabhakar Kushwaha 
204*c517771aSPrabhakar Kushwaha static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
205*c517771aSPrabhakar Kushwaha {
206*c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
207*c517771aSPrabhakar Kushwaha 	struct dpaa_fd fd;
208*c517771aSPrabhakar Kushwaha 	u64 buffer_start;
209*c517771aSPrabhakar Kushwaha 	int data_offset, err;
210*c517771aSPrabhakar Kushwaha 	struct qbman_swp *swp = dflt_dpio->sw_portal;
211*c517771aSPrabhakar Kushwaha 	struct qbman_eq_desc ed;
212*c517771aSPrabhakar Kushwaha 
213*c517771aSPrabhakar Kushwaha 	/* Setup the FD fields */
214*c517771aSPrabhakar Kushwaha 	memset(&fd, 0, sizeof(fd));
215*c517771aSPrabhakar Kushwaha 
216*c517771aSPrabhakar Kushwaha 	data_offset = priv->tx_data_offset;
217*c517771aSPrabhakar Kushwaha 
218*c517771aSPrabhakar Kushwaha 	do {
219*c517771aSPrabhakar Kushwaha 		err = qbman_swp_acquire(dflt_dpio->sw_portal,
220*c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
221*c517771aSPrabhakar Kushwaha 					&buffer_start, 1);
222*c517771aSPrabhakar Kushwaha 	} while (err == -EBUSY);
223*c517771aSPrabhakar Kushwaha 
224*c517771aSPrabhakar Kushwaha 	if (err < 0) {
225*c517771aSPrabhakar Kushwaha 		printf("qbman_swp_acquire() failed\n");
226*c517771aSPrabhakar Kushwaha 		return -ENOMEM;
227*c517771aSPrabhakar Kushwaha 	}
228*c517771aSPrabhakar Kushwaha 
229*c517771aSPrabhakar Kushwaha 	debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
230*c517771aSPrabhakar Kushwaha 
231*c517771aSPrabhakar Kushwaha 	memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
232*c517771aSPrabhakar Kushwaha 
233*c517771aSPrabhakar Kushwaha 	flush_dcache_range(buffer_start, LDPAA_ETH_RX_BUFFER_SIZE);
234*c517771aSPrabhakar Kushwaha 
235*c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_addr(&fd, (u64)buffer_start);
236*c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
237*c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
238*c517771aSPrabhakar Kushwaha 	ldpaa_fd_set_len(&fd, len);
239*c517771aSPrabhakar Kushwaha 
240*c517771aSPrabhakar Kushwaha 	fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
241*c517771aSPrabhakar Kushwaha 				LDPAA_FD_CTRL_PTV1;
242*c517771aSPrabhakar Kushwaha 
243*c517771aSPrabhakar Kushwaha 	qbman_eq_desc_clear(&ed);
244*c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_no_orp(&ed, 0);
245*c517771aSPrabhakar Kushwaha 	qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
246*c517771aSPrabhakar Kushwaha 	err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd));
247*c517771aSPrabhakar Kushwaha 	if (err < 0)
248*c517771aSPrabhakar Kushwaha 		printf("error enqueueing Tx frame\n");
249*c517771aSPrabhakar Kushwaha 
250*c517771aSPrabhakar Kushwaha 	mdelay(1);
251*c517771aSPrabhakar Kushwaha 
252*c517771aSPrabhakar Kushwaha 	err = ldpaa_eth_pull_dequeue_tx_conf(priv);
253*c517771aSPrabhakar Kushwaha 	if (err < 0)
254*c517771aSPrabhakar Kushwaha 		printf("error Tx Conf frame\n");
255*c517771aSPrabhakar Kushwaha 
256*c517771aSPrabhakar Kushwaha 	return err;
257*c517771aSPrabhakar Kushwaha }
258*c517771aSPrabhakar Kushwaha 
259*c517771aSPrabhakar Kushwaha static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
260*c517771aSPrabhakar Kushwaha {
261*c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
262*c517771aSPrabhakar Kushwaha 	struct dpni_queue_attr rx_queue_attr;
263*c517771aSPrabhakar Kushwaha 	struct dpni_tx_flow_attr tx_flow_attr;
264*c517771aSPrabhakar Kushwaha 	uint8_t mac_addr[6];
265*c517771aSPrabhakar Kushwaha 	int err;
266*c517771aSPrabhakar Kushwaha 
267*c517771aSPrabhakar Kushwaha 	if (net_dev->state == ETH_STATE_ACTIVE)
268*c517771aSPrabhakar Kushwaha 		return 0;
269*c517771aSPrabhakar Kushwaha 
270*c517771aSPrabhakar Kushwaha 	/* DPNI initialization */
271*c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_setup(priv);
272*c517771aSPrabhakar Kushwaha 	if (err < 0)
273*c517771aSPrabhakar Kushwaha 		goto err_dpni_setup;
274*c517771aSPrabhakar Kushwaha 
275*c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_setup();
276*c517771aSPrabhakar Kushwaha 	if (err < 0)
277*c517771aSPrabhakar Kushwaha 		goto err_dpbp_setup;
278*c517771aSPrabhakar Kushwaha 
279*c517771aSPrabhakar Kushwaha 	/* DPNI binding DPBP */
280*c517771aSPrabhakar Kushwaha 	err = ldpaa_dpni_bind(priv);
281*c517771aSPrabhakar Kushwaha 	if (err)
282*c517771aSPrabhakar Kushwaha 		goto err_bind;
283*c517771aSPrabhakar Kushwaha 
284*c517771aSPrabhakar Kushwaha 	err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle,
285*c517771aSPrabhakar Kushwaha 					mac_addr);
286*c517771aSPrabhakar Kushwaha 	if (err) {
287*c517771aSPrabhakar Kushwaha 		printf("dpni_get_primary_mac_addr() failed\n");
288*c517771aSPrabhakar Kushwaha 		return err;
289*c517771aSPrabhakar Kushwaha 	}
290*c517771aSPrabhakar Kushwaha 
291*c517771aSPrabhakar Kushwaha 	memcpy(net_dev->enetaddr, mac_addr, 0x6);
292*c517771aSPrabhakar Kushwaha 
293*c517771aSPrabhakar Kushwaha 	/* setup the MAC address */
294*c517771aSPrabhakar Kushwaha 	if (net_dev->enetaddr[0] & 0x01) {
295*c517771aSPrabhakar Kushwaha 		printf("%s: MacAddress is multcast address\n",	__func__);
296*c517771aSPrabhakar Kushwaha 		return 1;
297*c517771aSPrabhakar Kushwaha 	}
298*c517771aSPrabhakar Kushwaha 
299*c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
300*c517771aSPrabhakar Kushwaha 	/* TODO Check this path */
301*c517771aSPrabhakar Kushwaha 	ret = phy_startup(priv->phydev);
302*c517771aSPrabhakar Kushwaha 	if (ret) {
303*c517771aSPrabhakar Kushwaha 		printf("%s: Could not initialize\n", priv->phydev->dev->name);
304*c517771aSPrabhakar Kushwaha 		return ret;
305*c517771aSPrabhakar Kushwaha 	}
306*c517771aSPrabhakar Kushwaha #else
307*c517771aSPrabhakar Kushwaha 	priv->phydev->speed = SPEED_1000;
308*c517771aSPrabhakar Kushwaha 	priv->phydev->link = 1;
309*c517771aSPrabhakar Kushwaha 	priv->phydev->duplex = DUPLEX_FULL;
310*c517771aSPrabhakar Kushwaha #endif
311*c517771aSPrabhakar Kushwaha 
312*c517771aSPrabhakar Kushwaha 	err = dpni_enable(dflt_mc_io, priv->dpni_handle);
313*c517771aSPrabhakar Kushwaha 	if (err < 0) {
314*c517771aSPrabhakar Kushwaha 		printf("dpni_enable() failed\n");
315*c517771aSPrabhakar Kushwaha 		return err;
316*c517771aSPrabhakar Kushwaha 	}
317*c517771aSPrabhakar Kushwaha 
318*c517771aSPrabhakar Kushwaha 	/* TODO: support multiple Rx flows */
319*c517771aSPrabhakar Kushwaha 	err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0,
320*c517771aSPrabhakar Kushwaha 			       &rx_queue_attr);
321*c517771aSPrabhakar Kushwaha 	if (err) {
322*c517771aSPrabhakar Kushwaha 		printf("dpni_get_rx_flow() failed\n");
323*c517771aSPrabhakar Kushwaha 		goto err_rx_flow;
324*c517771aSPrabhakar Kushwaha 	}
325*c517771aSPrabhakar Kushwaha 
326*c517771aSPrabhakar Kushwaha 	priv->rx_dflt_fqid = rx_queue_attr.fqid;
327*c517771aSPrabhakar Kushwaha 
328*c517771aSPrabhakar Kushwaha 	err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid);
329*c517771aSPrabhakar Kushwaha 	if (err) {
330*c517771aSPrabhakar Kushwaha 		printf("dpni_get_qdid() failed\n");
331*c517771aSPrabhakar Kushwaha 		goto err_qdid;
332*c517771aSPrabhakar Kushwaha 	}
333*c517771aSPrabhakar Kushwaha 
334*c517771aSPrabhakar Kushwaha 	err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id,
335*c517771aSPrabhakar Kushwaha 			       &tx_flow_attr);
336*c517771aSPrabhakar Kushwaha 	if (err) {
337*c517771aSPrabhakar Kushwaha 		printf("dpni_get_tx_flow() failed\n");
338*c517771aSPrabhakar Kushwaha 		goto err_tx_flow;
339*c517771aSPrabhakar Kushwaha 	}
340*c517771aSPrabhakar Kushwaha 
341*c517771aSPrabhakar Kushwaha 	priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid;
342*c517771aSPrabhakar Kushwaha 
343*c517771aSPrabhakar Kushwaha 	if (!priv->phydev->link)
344*c517771aSPrabhakar Kushwaha 		printf("%s: No link.\n", priv->phydev->dev->name);
345*c517771aSPrabhakar Kushwaha 
346*c517771aSPrabhakar Kushwaha 	return priv->phydev->link ? 0 : -1;
347*c517771aSPrabhakar Kushwaha 
348*c517771aSPrabhakar Kushwaha err_tx_flow:
349*c517771aSPrabhakar Kushwaha err_qdid:
350*c517771aSPrabhakar Kushwaha err_rx_flow:
351*c517771aSPrabhakar Kushwaha 	dpni_disable(dflt_mc_io, priv->dpni_handle);
352*c517771aSPrabhakar Kushwaha err_bind:
353*c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
354*c517771aSPrabhakar Kushwaha err_dpbp_setup:
355*c517771aSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, priv->dpni_handle);
356*c517771aSPrabhakar Kushwaha err_dpni_setup:
357*c517771aSPrabhakar Kushwaha 	return err;
358*c517771aSPrabhakar Kushwaha }
359*c517771aSPrabhakar Kushwaha 
360*c517771aSPrabhakar Kushwaha static void ldpaa_eth_stop(struct eth_device *net_dev)
361*c517771aSPrabhakar Kushwaha {
362*c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
363*c517771aSPrabhakar Kushwaha 	int err = 0;
364*c517771aSPrabhakar Kushwaha 
365*c517771aSPrabhakar Kushwaha 	if (net_dev->state == ETH_STATE_PASSIVE)
366*c517771aSPrabhakar Kushwaha 		return;
367*c517771aSPrabhakar Kushwaha 	/* Stop Tx and Rx traffic */
368*c517771aSPrabhakar Kushwaha 	err = dpni_disable(dflt_mc_io, priv->dpni_handle);
369*c517771aSPrabhakar Kushwaha 	if (err < 0)
370*c517771aSPrabhakar Kushwaha 		printf("dpni_disable() failed\n");
371*c517771aSPrabhakar Kushwaha 
372*c517771aSPrabhakar Kushwaha #ifdef CONFIG_PHYLIB
373*c517771aSPrabhakar Kushwaha 	phy_shutdown(priv->phydev);
374*c517771aSPrabhakar Kushwaha #endif
375*c517771aSPrabhakar Kushwaha 
376*c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_free();
377*c517771aSPrabhakar Kushwaha 	dpni_reset(dflt_mc_io, priv->dpni_handle);
378*c517771aSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, priv->dpni_handle);
379*c517771aSPrabhakar Kushwaha }
380*c517771aSPrabhakar Kushwaha 
381*c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain_cnt(int count)
382*c517771aSPrabhakar Kushwaha {
383*c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
384*c517771aSPrabhakar Kushwaha 	void *addr;
385*c517771aSPrabhakar Kushwaha 	int ret, i;
386*c517771aSPrabhakar Kushwaha 
387*c517771aSPrabhakar Kushwaha 	BUG_ON(count > 7);
388*c517771aSPrabhakar Kushwaha 
389*c517771aSPrabhakar Kushwaha 	do {
390*c517771aSPrabhakar Kushwaha 		ret = qbman_swp_acquire(dflt_dpio->sw_portal,
391*c517771aSPrabhakar Kushwaha 					dflt_dpbp->dpbp_attr.bpid,
392*c517771aSPrabhakar Kushwaha 					buf_array, count);
393*c517771aSPrabhakar Kushwaha 		if (ret < 0) {
394*c517771aSPrabhakar Kushwaha 			printf("qbman_swp_acquire() failed\n");
395*c517771aSPrabhakar Kushwaha 			return;
396*c517771aSPrabhakar Kushwaha 		}
397*c517771aSPrabhakar Kushwaha 		for (i = 0; i < ret; i++) {
398*c517771aSPrabhakar Kushwaha 			addr = (void *)buf_array[i];
399*c517771aSPrabhakar Kushwaha 			debug("Free: buffer addr =0x%p\n", addr);
400*c517771aSPrabhakar Kushwaha 			free(addr);
401*c517771aSPrabhakar Kushwaha 		}
402*c517771aSPrabhakar Kushwaha 	} while (ret);
403*c517771aSPrabhakar Kushwaha }
404*c517771aSPrabhakar Kushwaha 
405*c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_drain(void)
406*c517771aSPrabhakar Kushwaha {
407*c517771aSPrabhakar Kushwaha 	int i;
408*c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
409*c517771aSPrabhakar Kushwaha 		ldpaa_dpbp_drain_cnt(7);
410*c517771aSPrabhakar Kushwaha }
411*c517771aSPrabhakar Kushwaha 
412*c517771aSPrabhakar Kushwaha static int ldpaa_bp_add_7(uint16_t bpid)
413*c517771aSPrabhakar Kushwaha {
414*c517771aSPrabhakar Kushwaha 	uint64_t buf_array[7];
415*c517771aSPrabhakar Kushwaha 	u8 *addr;
416*c517771aSPrabhakar Kushwaha 	int i;
417*c517771aSPrabhakar Kushwaha 	struct qbman_release_desc rd;
418*c517771aSPrabhakar Kushwaha 
419*c517771aSPrabhakar Kushwaha 	for (i = 0; i < 7; i++) {
420*c517771aSPrabhakar Kushwaha 		addr = memalign(L1_CACHE_BYTES, LDPAA_ETH_RX_BUFFER_SIZE);
421*c517771aSPrabhakar Kushwaha 		if (!addr) {
422*c517771aSPrabhakar Kushwaha 			printf("addr allocation failed\n");
423*c517771aSPrabhakar Kushwaha 			goto err_alloc;
424*c517771aSPrabhakar Kushwaha 		}
425*c517771aSPrabhakar Kushwaha 		memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
426*c517771aSPrabhakar Kushwaha 
427*c517771aSPrabhakar Kushwaha 		buf_array[i] = (uint64_t)addr;
428*c517771aSPrabhakar Kushwaha 		debug("Release: buffer addr =0x%p\n", addr);
429*c517771aSPrabhakar Kushwaha 	}
430*c517771aSPrabhakar Kushwaha 
431*c517771aSPrabhakar Kushwaha release_bufs:
432*c517771aSPrabhakar Kushwaha 	/* In case the portal is busy, retry until successful.
433*c517771aSPrabhakar Kushwaha 	 * This function is guaranteed to succeed in a reasonable amount
434*c517771aSPrabhakar Kushwaha 	 * of time.
435*c517771aSPrabhakar Kushwaha 	 */
436*c517771aSPrabhakar Kushwaha 
437*c517771aSPrabhakar Kushwaha 	do {
438*c517771aSPrabhakar Kushwaha 		mdelay(1);
439*c517771aSPrabhakar Kushwaha 		qbman_release_desc_clear(&rd);
440*c517771aSPrabhakar Kushwaha 		qbman_release_desc_set_bpid(&rd, bpid);
441*c517771aSPrabhakar Kushwaha 	} while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
442*c517771aSPrabhakar Kushwaha 
443*c517771aSPrabhakar Kushwaha 	return i;
444*c517771aSPrabhakar Kushwaha 
445*c517771aSPrabhakar Kushwaha err_alloc:
446*c517771aSPrabhakar Kushwaha 	if (i)
447*c517771aSPrabhakar Kushwaha 		goto release_bufs;
448*c517771aSPrabhakar Kushwaha 
449*c517771aSPrabhakar Kushwaha 	return 0;
450*c517771aSPrabhakar Kushwaha }
451*c517771aSPrabhakar Kushwaha 
452*c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_seed(uint16_t bpid)
453*c517771aSPrabhakar Kushwaha {
454*c517771aSPrabhakar Kushwaha 	int i;
455*c517771aSPrabhakar Kushwaha 	int count;
456*c517771aSPrabhakar Kushwaha 
457*c517771aSPrabhakar Kushwaha 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
458*c517771aSPrabhakar Kushwaha 		count = ldpaa_bp_add_7(bpid);
459*c517771aSPrabhakar Kushwaha 		if (count < 7)
460*c517771aSPrabhakar Kushwaha 			printf("Buffer Seed= %d\n", count);
461*c517771aSPrabhakar Kushwaha 	}
462*c517771aSPrabhakar Kushwaha 
463*c517771aSPrabhakar Kushwaha 	return 0;
464*c517771aSPrabhakar Kushwaha }
465*c517771aSPrabhakar Kushwaha 
466*c517771aSPrabhakar Kushwaha static int ldpaa_dpbp_setup(void)
467*c517771aSPrabhakar Kushwaha {
468*c517771aSPrabhakar Kushwaha 	int err;
469*c517771aSPrabhakar Kushwaha 
470*c517771aSPrabhakar Kushwaha 	err = dpbp_open(dflt_mc_io, dflt_dpbp->dpbp_attr.id,
471*c517771aSPrabhakar Kushwaha 			&dflt_dpbp->dpbp_handle);
472*c517771aSPrabhakar Kushwaha 	if (err) {
473*c517771aSPrabhakar Kushwaha 		printf("dpbp_open() failed\n");
474*c517771aSPrabhakar Kushwaha 		goto err_open;
475*c517771aSPrabhakar Kushwaha 	}
476*c517771aSPrabhakar Kushwaha 
477*c517771aSPrabhakar Kushwaha 	err = dpbp_enable(dflt_mc_io, dflt_dpbp->dpbp_handle);
478*c517771aSPrabhakar Kushwaha 	if (err) {
479*c517771aSPrabhakar Kushwaha 		printf("dpbp_enable() failed\n");
480*c517771aSPrabhakar Kushwaha 		goto err_enable;
481*c517771aSPrabhakar Kushwaha 	}
482*c517771aSPrabhakar Kushwaha 
483*c517771aSPrabhakar Kushwaha 	err = dpbp_get_attributes(dflt_mc_io, dflt_dpbp->dpbp_handle,
484*c517771aSPrabhakar Kushwaha 				  &dflt_dpbp->dpbp_attr);
485*c517771aSPrabhakar Kushwaha 	if (err) {
486*c517771aSPrabhakar Kushwaha 		printf("dpbp_get_attributes() failed\n");
487*c517771aSPrabhakar Kushwaha 		goto err_get_attr;
488*c517771aSPrabhakar Kushwaha 	}
489*c517771aSPrabhakar Kushwaha 
490*c517771aSPrabhakar Kushwaha 	err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
491*c517771aSPrabhakar Kushwaha 	if (err) {
492*c517771aSPrabhakar Kushwaha 		printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
493*c517771aSPrabhakar Kushwaha 		       dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
494*c517771aSPrabhakar Kushwaha 		goto err_seed;
495*c517771aSPrabhakar Kushwaha 	}
496*c517771aSPrabhakar Kushwaha 
497*c517771aSPrabhakar Kushwaha 	return 0;
498*c517771aSPrabhakar Kushwaha 
499*c517771aSPrabhakar Kushwaha err_seed:
500*c517771aSPrabhakar Kushwaha err_get_attr:
501*c517771aSPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
502*c517771aSPrabhakar Kushwaha err_enable:
503*c517771aSPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
504*c517771aSPrabhakar Kushwaha err_open:
505*c517771aSPrabhakar Kushwaha 	return err;
506*c517771aSPrabhakar Kushwaha }
507*c517771aSPrabhakar Kushwaha 
508*c517771aSPrabhakar Kushwaha static void ldpaa_dpbp_free(void)
509*c517771aSPrabhakar Kushwaha {
510*c517771aSPrabhakar Kushwaha 	ldpaa_dpbp_drain();
511*c517771aSPrabhakar Kushwaha 	dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
512*c517771aSPrabhakar Kushwaha 	dpbp_reset(dflt_mc_io, dflt_dpbp->dpbp_handle);
513*c517771aSPrabhakar Kushwaha 	dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
514*c517771aSPrabhakar Kushwaha }
515*c517771aSPrabhakar Kushwaha 
516*c517771aSPrabhakar Kushwaha static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
517*c517771aSPrabhakar Kushwaha {
518*c517771aSPrabhakar Kushwaha 	int err;
519*c517771aSPrabhakar Kushwaha 
520*c517771aSPrabhakar Kushwaha 	/* and get a handle for the DPNI this interface is associate with */
521*c517771aSPrabhakar Kushwaha 	err = dpni_open(dflt_mc_io, priv->dpni_id, &priv->dpni_handle);
522*c517771aSPrabhakar Kushwaha 	if (err) {
523*c517771aSPrabhakar Kushwaha 		printf("dpni_open() failed\n");
524*c517771aSPrabhakar Kushwaha 		goto err_open;
525*c517771aSPrabhakar Kushwaha 	}
526*c517771aSPrabhakar Kushwaha 
527*c517771aSPrabhakar Kushwaha 	err = dpni_get_attributes(dflt_mc_io, priv->dpni_handle,
528*c517771aSPrabhakar Kushwaha 				  &priv->dpni_attrs);
529*c517771aSPrabhakar Kushwaha 	if (err) {
530*c517771aSPrabhakar Kushwaha 		printf("dpni_get_attributes() failed (err=%d)\n", err);
531*c517771aSPrabhakar Kushwaha 		goto err_get_attr;
532*c517771aSPrabhakar Kushwaha 	}
533*c517771aSPrabhakar Kushwaha 
534*c517771aSPrabhakar Kushwaha 	/* Configure our buffers' layout */
535*c517771aSPrabhakar Kushwaha 	priv->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
536*c517771aSPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
537*c517771aSPrabhakar Kushwaha 				   DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
538*c517771aSPrabhakar Kushwaha 	priv->buf_layout.pass_parser_result = true;
539*c517771aSPrabhakar Kushwaha 	priv->buf_layout.pass_frame_status = true;
540*c517771aSPrabhakar Kushwaha 	priv->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
541*c517771aSPrabhakar Kushwaha 	/* ...rx, ... */
542*c517771aSPrabhakar Kushwaha 	err = dpni_set_rx_buffer_layout(dflt_mc_io, priv->dpni_handle,
543*c517771aSPrabhakar Kushwaha 					&priv->buf_layout);
544*c517771aSPrabhakar Kushwaha 	if (err) {
545*c517771aSPrabhakar Kushwaha 		printf("dpni_set_rx_buffer_layout() failed");
546*c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
547*c517771aSPrabhakar Kushwaha 	}
548*c517771aSPrabhakar Kushwaha 
549*c517771aSPrabhakar Kushwaha 	/* ... tx, ... */
550*c517771aSPrabhakar Kushwaha 	priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT;
551*c517771aSPrabhakar Kushwaha 	err = dpni_set_tx_buffer_layout(dflt_mc_io, priv->dpni_handle,
552*c517771aSPrabhakar Kushwaha 					&priv->buf_layout);
553*c517771aSPrabhakar Kushwaha 	if (err) {
554*c517771aSPrabhakar Kushwaha 		printf("dpni_set_tx_buffer_layout() failed");
555*c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
556*c517771aSPrabhakar Kushwaha 	}
557*c517771aSPrabhakar Kushwaha 
558*c517771aSPrabhakar Kushwaha 	/* ... tx-confirm. */
559*c517771aSPrabhakar Kushwaha 	priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
560*c517771aSPrabhakar Kushwaha 	err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, priv->dpni_handle,
561*c517771aSPrabhakar Kushwaha 					     &priv->buf_layout);
562*c517771aSPrabhakar Kushwaha 	if (err) {
563*c517771aSPrabhakar Kushwaha 		printf("dpni_set_tx_conf_buffer_layout() failed");
564*c517771aSPrabhakar Kushwaha 		goto err_buf_layout;
565*c517771aSPrabhakar Kushwaha 	}
566*c517771aSPrabhakar Kushwaha 
567*c517771aSPrabhakar Kushwaha 	/* Now that we've set our tx buffer layout, retrieve the minimum
568*c517771aSPrabhakar Kushwaha 	 * required tx data offset.
569*c517771aSPrabhakar Kushwaha 	 */
570*c517771aSPrabhakar Kushwaha 	err = dpni_get_tx_data_offset(dflt_mc_io, priv->dpni_handle,
571*c517771aSPrabhakar Kushwaha 				      &priv->tx_data_offset);
572*c517771aSPrabhakar Kushwaha 	if (err) {
573*c517771aSPrabhakar Kushwaha 		printf("dpni_get_tx_data_offset() failed\n");
574*c517771aSPrabhakar Kushwaha 		goto err_data_offset;
575*c517771aSPrabhakar Kushwaha 	}
576*c517771aSPrabhakar Kushwaha 
577*c517771aSPrabhakar Kushwaha 	/* Warn in case TX data offset is not multiple of 64 bytes. */
578*c517771aSPrabhakar Kushwaha 	WARN_ON(priv->tx_data_offset % 64);
579*c517771aSPrabhakar Kushwaha 
580*c517771aSPrabhakar Kushwaha 	/* Accomodate SWA space. */
581*c517771aSPrabhakar Kushwaha 	priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
582*c517771aSPrabhakar Kushwaha 	debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
583*c517771aSPrabhakar Kushwaha 
584*c517771aSPrabhakar Kushwaha 	return 0;
585*c517771aSPrabhakar Kushwaha 
586*c517771aSPrabhakar Kushwaha err_data_offset:
587*c517771aSPrabhakar Kushwaha err_buf_layout:
588*c517771aSPrabhakar Kushwaha err_get_attr:
589*c517771aSPrabhakar Kushwaha 	dpni_close(dflt_mc_io, priv->dpni_handle);
590*c517771aSPrabhakar Kushwaha err_open:
591*c517771aSPrabhakar Kushwaha 	return err;
592*c517771aSPrabhakar Kushwaha }
593*c517771aSPrabhakar Kushwaha 
594*c517771aSPrabhakar Kushwaha static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
595*c517771aSPrabhakar Kushwaha {
596*c517771aSPrabhakar Kushwaha 	struct dpni_pools_cfg pools_params;
597*c517771aSPrabhakar Kushwaha 	struct dpni_tx_flow_cfg dflt_tx_flow;
598*c517771aSPrabhakar Kushwaha 	int err = 0;
599*c517771aSPrabhakar Kushwaha 
600*c517771aSPrabhakar Kushwaha 	pools_params.num_dpbp = 1;
601*c517771aSPrabhakar Kushwaha 	pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
602*c517771aSPrabhakar Kushwaha 	pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
603*c517771aSPrabhakar Kushwaha 	err = dpni_set_pools(dflt_mc_io, priv->dpni_handle, &pools_params);
604*c517771aSPrabhakar Kushwaha 	if (err) {
605*c517771aSPrabhakar Kushwaha 		printf("dpni_set_pools() failed\n");
606*c517771aSPrabhakar Kushwaha 		return err;
607*c517771aSPrabhakar Kushwaha 	}
608*c517771aSPrabhakar Kushwaha 
609*c517771aSPrabhakar Kushwaha 	priv->tx_flow_id = DPNI_NEW_FLOW_ID;
610*c517771aSPrabhakar Kushwaha 	memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
611*c517771aSPrabhakar Kushwaha 
612*c517771aSPrabhakar Kushwaha 	err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle,
613*c517771aSPrabhakar Kushwaha 			       &priv->tx_flow_id, &dflt_tx_flow);
614*c517771aSPrabhakar Kushwaha 	if (err) {
615*c517771aSPrabhakar Kushwaha 		printf("dpni_set_tx_flow() failed\n");
616*c517771aSPrabhakar Kushwaha 		return err;
617*c517771aSPrabhakar Kushwaha 	}
618*c517771aSPrabhakar Kushwaha 
619*c517771aSPrabhakar Kushwaha 	return 0;
620*c517771aSPrabhakar Kushwaha }
621*c517771aSPrabhakar Kushwaha 
622*c517771aSPrabhakar Kushwaha static int ldpaa_eth_netdev_init(struct eth_device *net_dev)
623*c517771aSPrabhakar Kushwaha {
624*c517771aSPrabhakar Kushwaha 	int err;
625*c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
626*c517771aSPrabhakar Kushwaha 
627*c517771aSPrabhakar Kushwaha 	if (priv->type == LDPAA_ETH_1G_E)
628*c517771aSPrabhakar Kushwaha 		sprintf(net_dev->name, "DTSEC%d", priv->dpni_id);
629*c517771aSPrabhakar Kushwaha 	else
630*c517771aSPrabhakar Kushwaha 		sprintf(net_dev->name, "TGEC%d", priv->dpni_id);
631*c517771aSPrabhakar Kushwaha 
632*c517771aSPrabhakar Kushwaha 	net_dev->iobase = 0;
633*c517771aSPrabhakar Kushwaha 	net_dev->init = ldpaa_eth_open;
634*c517771aSPrabhakar Kushwaha 	net_dev->halt = ldpaa_eth_stop;
635*c517771aSPrabhakar Kushwaha 	net_dev->send = ldpaa_eth_tx;
636*c517771aSPrabhakar Kushwaha 	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
637*c517771aSPrabhakar Kushwaha /*
638*c517771aSPrabhakar Kushwaha 	TODO: PHY MDIO information
639*c517771aSPrabhakar Kushwaha 	priv->bus = info->bus;
640*c517771aSPrabhakar Kushwaha 	priv->phyaddr = info->phy_addr;
641*c517771aSPrabhakar Kushwaha 	priv->enet_if = info->enet_if;
642*c517771aSPrabhakar Kushwaha */
643*c517771aSPrabhakar Kushwaha 
644*c517771aSPrabhakar Kushwaha 	if (init_phy(net_dev))
645*c517771aSPrabhakar Kushwaha 		return 0;
646*c517771aSPrabhakar Kushwaha 
647*c517771aSPrabhakar Kushwaha 	err = eth_register(net_dev);
648*c517771aSPrabhakar Kushwaha 	if (err < 0) {
649*c517771aSPrabhakar Kushwaha 		printf("eth_register() = %d\n", err);
650*c517771aSPrabhakar Kushwaha 		return err;
651*c517771aSPrabhakar Kushwaha 	}
652*c517771aSPrabhakar Kushwaha 
653*c517771aSPrabhakar Kushwaha 	return 0;
654*c517771aSPrabhakar Kushwaha }
655*c517771aSPrabhakar Kushwaha 
656*c517771aSPrabhakar Kushwaha int ldpaa_eth_init(struct dprc_obj_desc obj_desc)
657*c517771aSPrabhakar Kushwaha {
658*c517771aSPrabhakar Kushwaha 	struct eth_device		*net_dev = NULL;
659*c517771aSPrabhakar Kushwaha 	struct ldpaa_eth_priv		*priv = NULL;
660*c517771aSPrabhakar Kushwaha 	int				err = 0;
661*c517771aSPrabhakar Kushwaha 
662*c517771aSPrabhakar Kushwaha 
663*c517771aSPrabhakar Kushwaha 	/* Net device */
664*c517771aSPrabhakar Kushwaha 	net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
665*c517771aSPrabhakar Kushwaha 	if (!net_dev) {
666*c517771aSPrabhakar Kushwaha 		printf("eth_device malloc() failed\n");
667*c517771aSPrabhakar Kushwaha 		return -ENOMEM;
668*c517771aSPrabhakar Kushwaha 	}
669*c517771aSPrabhakar Kushwaha 	memset(net_dev, 0, sizeof(struct eth_device));
670*c517771aSPrabhakar Kushwaha 
671*c517771aSPrabhakar Kushwaha 	/* alloc the ldpaa ethernet private struct */
672*c517771aSPrabhakar Kushwaha 	priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
673*c517771aSPrabhakar Kushwaha 	if (!priv) {
674*c517771aSPrabhakar Kushwaha 		printf("ldpaa_eth_priv malloc() failed\n");
675*c517771aSPrabhakar Kushwaha 		return -ENOMEM;
676*c517771aSPrabhakar Kushwaha 	}
677*c517771aSPrabhakar Kushwaha 	memset(priv, 0, sizeof(struct ldpaa_eth_priv));
678*c517771aSPrabhakar Kushwaha 
679*c517771aSPrabhakar Kushwaha 	net_dev->priv = (void *)priv;
680*c517771aSPrabhakar Kushwaha 	priv->net_dev = (struct eth_device *)net_dev;
681*c517771aSPrabhakar Kushwaha 	priv->dpni_id = obj_desc.id;
682*c517771aSPrabhakar Kushwaha 
683*c517771aSPrabhakar Kushwaha 	err = ldpaa_eth_netdev_init(net_dev);
684*c517771aSPrabhakar Kushwaha 	if (err)
685*c517771aSPrabhakar Kushwaha 		goto err_netdev_init;
686*c517771aSPrabhakar Kushwaha 
687*c517771aSPrabhakar Kushwaha 	debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
688*c517771aSPrabhakar Kushwaha 	return 0;
689*c517771aSPrabhakar Kushwaha 
690*c517771aSPrabhakar Kushwaha err_netdev_init:
691*c517771aSPrabhakar Kushwaha 	free(priv);
692*c517771aSPrabhakar Kushwaha 	net_dev->priv = NULL;
693*c517771aSPrabhakar Kushwaha 	free(net_dev);
694*c517771aSPrabhakar Kushwaha 
695*c517771aSPrabhakar Kushwaha 	return err;
696*c517771aSPrabhakar Kushwaha }
697