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