1 /*
2  * Copyright (C) 2014-2016 Freescale Semiconductor
3  * Copyright 2017 NXP
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 #include <asm/io.h>
10 #include <asm/types.h>
11 #include <malloc.h>
12 #include <net.h>
13 #include <hwconfig.h>
14 #include <phy.h>
15 #include <linux/compat.h>
16 #include <fsl-mc/fsl_dpmac.h>
17 
18 #include <fsl-mc/ldpaa_wriop.h>
19 #include "ldpaa_eth.h"
20 
21 #ifdef CONFIG_PHYLIB
22 static int init_phy(struct eth_device *dev)
23 {
24 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
25 	struct phy_device *phydev = NULL;
26 	struct mii_dev *bus;
27 
28 	bus = wriop_get_mdio(priv->dpmac_id);
29 	if (bus == NULL)
30 		return 0;
31 
32 	phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id),
33 			     dev, wriop_get_enet_if(priv->dpmac_id));
34 	if (!phydev) {
35 		printf("Failed to connect\n");
36 		return -1;
37 	}
38 
39 	priv->phydev = phydev;
40 
41 	return phy_config(phydev);
42 }
43 #endif
44 
45 #ifdef DEBUG
46 
47 #define DPNI_STATS_PER_PAGE 6
48 
49 static const char *dpni_statistics[][DPNI_STATS_PER_PAGE] = {
50 	{
51 	"DPNI_CNT_ING_ALL_FRAMES",
52 	"DPNI_CNT_ING_ALL_BYTES",
53 	"DPNI_CNT_ING_MCAST_FRAMES",
54 	"DPNI_CNT_ING_MCAST_BYTES",
55 	"DPNI_CNT_ING_BCAST_FRAMES",
56 	"DPNI_CNT_ING_BCAST_BYTES",
57 	}, {
58 	"DPNI_CNT_EGR_ALL_FRAMES",
59 	"DPNI_CNT_EGR_ALL_BYTES",
60 	"DPNI_CNT_EGR_MCAST_FRAMES",
61 	"DPNI_CNT_EGR_MCAST_BYTES",
62 	"DPNI_CNT_EGR_BCAST_FRAMES",
63 	"DPNI_CNT_EGR_BCAST_BYTES",
64 	}, {
65 	"DPNI_CNT_ING_FILTERED_FRAMES",
66 	"DPNI_CNT_ING_DISCARDED_FRAMES",
67 	"DPNI_CNT_ING_NOBUFFER_DISCARDS",
68 	"DPNI_CNT_EGR_DISCARDED_FRAMES",
69 	"DPNI_CNT_EGR_CNF_FRAMES",
70 	""
71 	},
72 };
73 
74 static void print_dpni_stats(const char *strings[],
75 			     struct dpni_statistics dpni_stats)
76 {
77 	uint64_t *stat;
78 	int i;
79 
80 	stat = (uint64_t *)&dpni_stats;
81 	for (i = 0; i < DPNI_STATS_PER_PAGE; i++) {
82 		if (strcmp(strings[i], "\0") == 0)
83 			break;
84 		printf("%s= %llu\n", strings[i], *stat);
85 		stat++;
86 	}
87 }
88 
89 static void ldpaa_eth_get_dpni_counter(void)
90 {
91 	int err = 0;
92 	unsigned int page = 0;
93 	struct dpni_statistics dpni_stats;
94 
95 	printf("DPNI counters ..\n");
96 	for (page = 0; page < 3; page++) {
97 		err = dpni_get_statistics(dflt_mc_io, MC_CMD_NO_FLAGS,
98 					  dflt_dpni->dpni_handle, page,
99 					  &dpni_stats);
100 		if (err < 0) {
101 			printf("dpni_get_statistics: failed:");
102 			printf("%d for page[%d]\n", err, page);
103 			return;
104 		}
105 		print_dpni_stats(dpni_statistics[page], dpni_stats);
106 	}
107 }
108 
109 static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev)
110 {
111 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
112 	int err = 0;
113 	u64 value;
114 
115 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
116 		     priv->dpmac_handle,
117 		     DPMAC_CNT_ING_BYTE,
118 		     &value);
119 	if (err < 0) {
120 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
121 		return;
122 	}
123 	printf("\nDPMAC counters ..\n");
124 	printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
125 
126 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
127 		     priv->dpmac_handle,
128 		     DPMAC_CNT_ING_FRAME_DISCARD,
129 		     &value);
130 	if (err < 0) {
131 		printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
132 		return;
133 	}
134 	printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value);
135 
136 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
137 		     priv->dpmac_handle,
138 		     DPMAC_CNT_ING_ALIGN_ERR,
139 		     &value);
140 	if (err < 0) {
141 		printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
142 		return;
143 	}
144 	printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value);
145 
146 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
147 		     priv->dpmac_handle,
148 		     DPMAC_CNT_ING_BYTE,
149 		     &value);
150 	if (err < 0) {
151 		printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
152 		return;
153 	}
154 	printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
155 
156 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
157 		     priv->dpmac_handle,
158 		     DPMAC_CNT_ING_ERR_FRAME,
159 		     &value);
160 	if (err < 0) {
161 		printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
162 		return;
163 	}
164 	printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value);
165 
166 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
167 		     priv->dpmac_handle,
168 		     DPMAC_CNT_EGR_BYTE ,
169 		     &value);
170 	if (err < 0) {
171 		printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
172 		return;
173 	}
174 	printf("DPMAC_CNT_EGR_BYTE =%lld\n", value);
175 
176 	err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
177 		     priv->dpmac_handle,
178 		     DPMAC_CNT_EGR_ERR_FRAME ,
179 		     &value);
180 	if (err < 0) {
181 		printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
182 		return;
183 	}
184 	printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
185 }
186 #endif
187 
188 static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
189 			 const struct dpaa_fd *fd)
190 {
191 	u64 fd_addr;
192 	uint16_t fd_offset;
193 	uint32_t fd_length;
194 	struct ldpaa_fas *fas;
195 	uint32_t status, err;
196 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
197 	u32 time_start;
198 	struct qbman_release_desc releasedesc;
199 	struct qbman_swp *swp = dflt_dpio->sw_portal;
200 
201 	fd_addr = ldpaa_fd_get_addr(fd);
202 	fd_offset = ldpaa_fd_get_offset(fd);
203 	fd_length = ldpaa_fd_get_len(fd);
204 
205 	debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
206 
207 	if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
208 		/* Read the frame annotation status word and check for errors */
209 		fas = (struct ldpaa_fas *)
210 				((uint8_t *)(fd_addr) +
211 				dflt_dpni->buf_layout.private_data_size);
212 		status = le32_to_cpu(fas->status);
213 		if (status & LDPAA_ETH_RX_ERR_MASK) {
214 			printf("Rx frame error(s): 0x%08x\n",
215 			       status & LDPAA_ETH_RX_ERR_MASK);
216 			goto error;
217 		} else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
218 			printf("Unsupported feature in bitmask: 0x%08x\n",
219 			       status & LDPAA_ETH_RX_UNSUPP_MASK);
220 			goto error;
221 		}
222 	}
223 
224 	debug("Rx frame: To Upper layer\n");
225 	net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
226 				    fd_length);
227 
228 error:
229 	flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
230 	qbman_release_desc_clear(&releasedesc);
231 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
232 	time_start = get_timer(0);
233 	do {
234 		/* Release buffer into the QBMAN */
235 		err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
236 	} while (get_timer(time_start) < timeo && err == -EBUSY);
237 
238 	if (err == -EBUSY)
239 		printf("Rx frame: QBMAN buffer release fails\n");
240 
241 	return;
242 }
243 
244 static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
245 {
246 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
247 	const struct ldpaa_dq *dq;
248 	const struct dpaa_fd *fd;
249 	int i = 5, err = 0, status;
250 	u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
251 	u32 time_start;
252 	static struct qbman_pull_desc pulldesc;
253 	struct qbman_swp *swp = dflt_dpio->sw_portal;
254 
255 	while (--i) {
256 		qbman_pull_desc_clear(&pulldesc);
257 		qbman_pull_desc_set_numframes(&pulldesc, 1);
258 		qbman_pull_desc_set_fq(&pulldesc, priv->rx_dflt_fqid);
259 
260 		err = qbman_swp_pull(swp, &pulldesc);
261 		if (err < 0) {
262 			printf("Dequeue frames error:0x%08x\n", err);
263 			continue;
264 		}
265 
266 		time_start = get_timer(0);
267 
268 		 do {
269 			dq = qbman_swp_dqrr_next(swp);
270 		} while (get_timer(time_start) < timeo && !dq);
271 
272 		if (dq) {
273 			/* Check for valid frame. If not sent a consume
274 			 * confirmation to QBMAN otherwise give it to NADK
275 			 * application and then send consume confirmation to
276 			 * QBMAN.
277 			 */
278 			status = (uint8_t)ldpaa_dq_flags(dq);
279 			if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
280 				debug("Dequeue RX frames:");
281 				debug("No frame delivered\n");
282 
283 				qbman_swp_dqrr_consume(swp, dq);
284 				continue;
285 			}
286 
287 			fd = ldpaa_dq_fd(dq);
288 
289 			/* Obtain FD and process it */
290 			ldpaa_eth_rx(priv, fd);
291 			qbman_swp_dqrr_consume(swp, dq);
292 			break;
293 		} else {
294 			err = -ENODATA;
295 			debug("No DQRR entries\n");
296 			break;
297 		}
298 	}
299 
300 	return err;
301 }
302 
303 static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
304 {
305 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
306 	struct dpaa_fd fd;
307 	u64 buffer_start;
308 	int data_offset, err;
309 	u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
310 	u32 time_start;
311 	struct qbman_swp *swp = dflt_dpio->sw_portal;
312 	struct qbman_eq_desc ed;
313 	struct qbman_release_desc releasedesc;
314 
315 	/* Setup the FD fields */
316 	memset(&fd, 0, sizeof(fd));
317 
318 	data_offset = priv->tx_data_offset;
319 
320 	do {
321 		err = qbman_swp_acquire(dflt_dpio->sw_portal,
322 					dflt_dpbp->dpbp_attr.bpid,
323 					&buffer_start, 1);
324 	} while (err == -EBUSY);
325 
326 	if (err <= 0) {
327 		printf("qbman_swp_acquire() failed\n");
328 		return -ENOMEM;
329 	}
330 
331 	debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
332 
333 	memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
334 
335 	flush_dcache_range(buffer_start, buffer_start +
336 					LDPAA_ETH_RX_BUFFER_SIZE);
337 
338 	ldpaa_fd_set_addr(&fd, (u64)buffer_start);
339 	ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
340 	ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
341 	ldpaa_fd_set_len(&fd, len);
342 
343 	fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
344 				LDPAA_FD_CTRL_PTV1;
345 
346 	qbman_eq_desc_clear(&ed);
347 	qbman_eq_desc_set_no_orp(&ed, 0);
348 	qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
349 
350 	time_start = get_timer(0);
351 
352 	while (get_timer(time_start) < timeo) {
353 		err = qbman_swp_enqueue(swp, &ed,
354 				(const struct qbman_fd *)(&fd));
355 		if (err != -EBUSY)
356 			break;
357 	}
358 
359 	if (err < 0) {
360 		printf("error enqueueing Tx frame\n");
361 		goto error;
362 	}
363 
364 	return err;
365 
366 error:
367 	qbman_release_desc_clear(&releasedesc);
368 	qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
369 	time_start = get_timer(0);
370 	do {
371 		/* Release buffer into the QBMAN */
372 		err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
373 	} while (get_timer(time_start) < timeo && err == -EBUSY);
374 
375 	if (err == -EBUSY)
376 		printf("TX data: QBMAN buffer release fails\n");
377 
378 	return err;
379 }
380 
381 static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
382 {
383 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
384 	struct dpmac_link_state	dpmac_link_state = { 0 };
385 #ifdef DEBUG
386 	struct dpni_link_state link_state;
387 #endif
388 	int err = 0;
389 	struct mii_dev *bus;
390 	phy_interface_t enet_if;
391 	struct dpni_queue d_queue;
392 
393 	if (net_dev->state == ETH_STATE_ACTIVE)
394 		return 0;
395 
396 	if (get_mc_boot_status() != 0) {
397 		printf("ERROR (MC is not booted)\n");
398 		return -ENODEV;
399 	}
400 
401 	if (get_dpl_apply_status() == 0) {
402 		printf("ERROR (DPL is deployed. No device available)\n");
403 		return -ENODEV;
404 	}
405 
406 	/* DPMAC initialization */
407 	err = ldpaa_dpmac_setup(priv);
408 	if (err < 0)
409 		goto err_dpmac_setup;
410 
411 #ifdef CONFIG_PHYLIB
412 	if (priv->phydev) {
413 		err = phy_startup(priv->phydev);
414 		if (err) {
415 			printf("%s: Could not initialize\n",
416 			       priv->phydev->dev->name);
417 			goto err_dpamc_bind;
418 		}
419 	}
420 #else
421 	priv->phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
422 	memset(priv->phydev, 0, sizeof(struct phy_device));
423 
424 	priv->phydev->speed = SPEED_1000;
425 	priv->phydev->link = 1;
426 	priv->phydev->duplex = DUPLEX_FULL;
427 #endif
428 
429 	bus = wriop_get_mdio(priv->dpmac_id);
430 	enet_if = wriop_get_enet_if(priv->dpmac_id);
431 	if ((bus == NULL) &&
432 	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
433 		priv->phydev = (struct phy_device *)
434 				malloc(sizeof(struct phy_device));
435 		memset(priv->phydev, 0, sizeof(struct phy_device));
436 
437 		priv->phydev->speed = SPEED_10000;
438 		priv->phydev->link = 1;
439 		priv->phydev->duplex = DUPLEX_FULL;
440 	}
441 
442 	if (!priv->phydev->link) {
443 		printf("%s: No link.\n", priv->phydev->dev->name);
444 		err = -1;
445 		goto err_dpamc_bind;
446 	}
447 
448 	/* DPMAC binding DPNI */
449 	err = ldpaa_dpmac_bind(priv);
450 	if (err)
451 		goto err_dpamc_bind;
452 
453 	/* DPNI initialization */
454 	err = ldpaa_dpni_setup(priv);
455 	if (err < 0)
456 		goto err_dpni_setup;
457 
458 	err = ldpaa_dpbp_setup();
459 	if (err < 0)
460 		goto err_dpbp_setup;
461 
462 	/* DPNI binding DPBP */
463 	err = ldpaa_dpni_bind(priv);
464 	if (err)
465 		goto err_dpni_bind;
466 
467 	err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS,
468 				dflt_dpni->dpni_handle, net_dev->enetaddr);
469 	if (err) {
470 		printf("dpni_add_mac_addr() failed\n");
471 		return err;
472 	}
473 
474 	err = dpni_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
475 	if (err < 0) {
476 		printf("dpni_enable() failed\n");
477 		return err;
478 	}
479 
480 	dpmac_link_state.rate = priv->phydev->speed;
481 
482 	if (priv->phydev->autoneg == AUTONEG_DISABLE)
483 		dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
484 	else
485 		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
486 
487 	if (priv->phydev->duplex == DUPLEX_HALF)
488 		dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
489 
490 	dpmac_link_state.up = priv->phydev->link;
491 
492 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
493 				  priv->dpmac_handle, &dpmac_link_state);
494 	if (err < 0) {
495 		printf("dpmac_set_link_state() failed\n");
496 		return err;
497 	}
498 
499 #ifdef DEBUG
500 	printf("DPMAC link status: %d - ", dpmac_link_state.up);
501 	dpmac_link_state.up == 0 ? printf("down\n") :
502 	dpmac_link_state.up == 1 ? printf("up\n") : printf("error state\n");
503 
504 	err = dpni_get_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
505 				  dflt_dpni->dpni_handle, &link_state);
506 	if (err < 0) {
507 		printf("dpni_get_link_state() failed\n");
508 		return err;
509 	}
510 
511 	printf("DPNI link status: %d - ", link_state.up);
512 	link_state.up == 0 ? printf("down\n") :
513 	link_state.up == 1 ? printf("up\n") : printf("error state\n");
514 #endif
515 
516 	memset(&d_queue, 0, sizeof(struct dpni_queue));
517 	err = dpni_get_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
518 			     dflt_dpni->dpni_handle, DPNI_QUEUE_RX,
519 			     0, 0, &d_queue);
520 	if (err) {
521 		printf("dpni_get_queue failed\n");
522 		goto err_get_queue;
523 	}
524 
525 	priv->rx_dflt_fqid = d_queue.fqid;
526 
527 	err = dpni_get_qdid(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle,
528 			    &priv->tx_qdid);
529 	if (err) {
530 		printf("dpni_get_qdid() failed\n");
531 		goto err_qdid;
532 	}
533 
534 	return priv->phydev->link;
535 
536 err_qdid:
537 err_get_queue:
538 	dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
539 err_dpni_bind:
540 	ldpaa_dpbp_free();
541 err_dpbp_setup:
542 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
543 err_dpni_setup:
544 err_dpamc_bind:
545 	dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
546 	dpmac_destroy(dflt_mc_io,
547 		      dflt_dprc_handle,
548 		      MC_CMD_NO_FLAGS, priv->dpmac_id);
549 err_dpmac_setup:
550 	return err;
551 }
552 
553 static void ldpaa_eth_stop(struct eth_device *net_dev)
554 {
555 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
556 	int err = 0;
557 #ifdef CONFIG_PHYLIB
558 	struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
559 #endif
560 
561 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
562 	    (net_dev->state == ETH_STATE_INIT))
563 		return;
564 
565 #ifdef DEBUG
566 	ldpaa_eth_get_dpni_counter();
567 	ldpaa_eth_get_dpmac_counter(net_dev);
568 #endif
569 
570 	err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
571 			      dflt_dprc_handle, &dpmac_endpoint);
572 	if (err < 0)
573 		printf("dprc_disconnect() failed dpmac_endpoint\n");
574 
575 	err = dpmac_close(dflt_mc_io, MC_CMD_NO_FLAGS, priv->dpmac_handle);
576 	if (err < 0)
577 		printf("dpmac_close() failed\n");
578 
579 	err = dpmac_destroy(dflt_mc_io,
580 			    dflt_dprc_handle,
581 			    MC_CMD_NO_FLAGS,
582 			    priv->dpmac_id);
583 	if (err < 0)
584 		printf("dpmac_destroy() failed\n");
585 
586 	/* Stop Tx and Rx traffic */
587 	err = dpni_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
588 	if (err < 0)
589 		printf("dpni_disable() failed\n");
590 
591 #ifdef CONFIG_PHYLIB
592 	if (priv->phydev && bus != NULL)
593 		phy_shutdown(priv->phydev);
594 	else {
595 		free(priv->phydev);
596 		priv->phydev = NULL;
597 	}
598 #endif
599 
600 	/* Free DPBP handle and reset. */
601 	ldpaa_dpbp_free();
602 
603 	dpni_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
604 	if (err < 0)
605 		printf("dpni_reset() failed\n");
606 
607 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
608 	if (err < 0)
609 		printf("dpni_close() failed\n");
610 }
611 
612 static void ldpaa_dpbp_drain_cnt(int count)
613 {
614 	uint64_t buf_array[7];
615 	void *addr;
616 	int ret, i;
617 
618 	BUG_ON(count > 7);
619 
620 	do {
621 		ret = qbman_swp_acquire(dflt_dpio->sw_portal,
622 					dflt_dpbp->dpbp_attr.bpid,
623 					buf_array, count);
624 		if (ret < 0) {
625 			printf("qbman_swp_acquire() failed\n");
626 			return;
627 		}
628 		for (i = 0; i < ret; i++) {
629 			addr = (void *)buf_array[i];
630 			debug("Free: buffer addr =0x%p\n", addr);
631 			free(addr);
632 		}
633 	} while (ret);
634 }
635 
636 static void ldpaa_dpbp_drain(void)
637 {
638 	int i;
639 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
640 		ldpaa_dpbp_drain_cnt(7);
641 }
642 
643 static int ldpaa_bp_add_7(uint16_t bpid)
644 {
645 	uint64_t buf_array[7];
646 	u8 *addr;
647 	int i;
648 	struct qbman_release_desc rd;
649 
650 	for (i = 0; i < 7; i++) {
651 		addr = memalign(LDPAA_ETH_BUF_ALIGN, LDPAA_ETH_RX_BUFFER_SIZE);
652 		if (!addr) {
653 			printf("addr allocation failed\n");
654 			goto err_alloc;
655 		}
656 		memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
657 		flush_dcache_range((u64)addr,
658 				   (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
659 
660 		buf_array[i] = (uint64_t)addr;
661 		debug("Release: buffer addr =0x%p\n", addr);
662 	}
663 
664 release_bufs:
665 	/* In case the portal is busy, retry until successful.
666 	 * This function is guaranteed to succeed in a reasonable amount
667 	 * of time.
668 	 */
669 
670 	do {
671 		mdelay(1);
672 		qbman_release_desc_clear(&rd);
673 		qbman_release_desc_set_bpid(&rd, bpid);
674 	} while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
675 
676 	return i;
677 
678 err_alloc:
679 	if (i)
680 		goto release_bufs;
681 
682 	return 0;
683 }
684 
685 static int ldpaa_dpbp_seed(uint16_t bpid)
686 {
687 	int i;
688 	int count;
689 
690 	for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
691 		count = ldpaa_bp_add_7(bpid);
692 		if (count < 7)
693 			printf("Buffer Seed= %d\n", count);
694 	}
695 
696 	return 0;
697 }
698 
699 static int ldpaa_dpbp_setup(void)
700 {
701 	int err;
702 
703 	err = dpbp_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_attr.id,
704 			&dflt_dpbp->dpbp_handle);
705 	if (err) {
706 		printf("dpbp_open() failed\n");
707 		goto err_open;
708 	}
709 
710 	err = dpbp_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
711 	if (err) {
712 		printf("dpbp_enable() failed\n");
713 		goto err_enable;
714 	}
715 
716 	err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
717 				  dflt_dpbp->dpbp_handle,
718 				  &dflt_dpbp->dpbp_attr);
719 	if (err) {
720 		printf("dpbp_get_attributes() failed\n");
721 		goto err_get_attr;
722 	}
723 
724 	err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
725 
726 	if (err) {
727 		printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
728 		       dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
729 		goto err_seed;
730 	}
731 
732 	return 0;
733 
734 err_seed:
735 err_get_attr:
736 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
737 err_enable:
738 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
739 err_open:
740 	return err;
741 }
742 
743 static void ldpaa_dpbp_free(void)
744 {
745 	ldpaa_dpbp_drain();
746 	dpbp_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
747 	dpbp_reset(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
748 	dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
749 }
750 
751 static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
752 				     struct ldpaa_eth_priv *priv)
753 {
754 	int error;
755 	uint16_t major_ver, minor_ver;
756 
757 	error = dpmac_get_api_version(dflt_mc_io, 0,
758 					&major_ver,
759 					&minor_ver);
760 	if ((major_ver < DPMAC_VER_MAJOR) ||
761 	    (major_ver == DPMAC_VER_MAJOR && minor_ver < DPMAC_VER_MINOR)) {
762 		printf("DPMAC version mismatch found %u.%u,",
763 		       major_ver, minor_ver);
764 		printf("supported version is %u.%u\n",
765 		       DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
766 		return error;
767 	}
768 
769 	return error;
770 }
771 
772 static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
773 {
774 	int err = 0;
775 	struct dpmac_cfg dpmac_cfg;
776 
777 	dpmac_cfg.mac_id = priv->dpmac_id;
778 
779 	err = dpmac_create(dflt_mc_io,
780 			   dflt_dprc_handle,
781 			   MC_CMD_NO_FLAGS, &dpmac_cfg,
782 			   &priv->dpmac_id);
783 	if (err)
784 		printf("dpmac_create() failed\n");
785 
786 	err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
787 	if (err < 0) {
788 		printf("ldpaa_dpmac_version_check() failed: %d\n", err);
789 		goto err_version_check;
790 	}
791 
792 	err = dpmac_open(dflt_mc_io,
793 			 MC_CMD_NO_FLAGS,
794 			 priv->dpmac_id,
795 			 &priv->dpmac_handle);
796 	if (err < 0) {
797 		printf("dpmac_open() failed: %d\n", err);
798 		goto err_open;
799 	}
800 
801 	return err;
802 
803 err_open:
804 err_version_check:
805 	dpmac_destroy(dflt_mc_io,
806 		      dflt_dprc_handle,
807 		      MC_CMD_NO_FLAGS, priv->dpmac_id);
808 
809 	return err;
810 }
811 
812 static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
813 {
814 	int err = 0;
815 	struct dprc_connection_cfg dprc_connection_cfg = {
816 		/* If both rates are zero the connection */
817 		/* will be configured in "best effort" mode. */
818 		.committed_rate = 0,
819 		.max_rate = 0
820 	};
821 
822 #ifdef DEBUG
823 	struct dprc_endpoint dbg_endpoint;
824 	int state = 0;
825 #endif
826 
827 	memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
828 	strcpy(dpmac_endpoint.type, "dpmac");
829 	dpmac_endpoint.id = priv->dpmac_id;
830 
831 	memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
832 	strcpy(dpni_endpoint.type, "dpni");
833 	dpni_endpoint.id = dflt_dpni->dpni_id;
834 
835 	err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
836 			     dflt_dprc_handle,
837 			     &dpmac_endpoint,
838 			     &dpni_endpoint,
839 			     &dprc_connection_cfg);
840 	if (err)
841 		printf("dprc_connect() failed\n");
842 
843 #ifdef DEBUG
844 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
845 				    dflt_dprc_handle, &dpni_endpoint,
846 				    &dbg_endpoint, &state);
847 	printf("%s, DPMAC Type= %s\n", __func__, dbg_endpoint.type);
848 	printf("%s, DPMAC ID= %d\n", __func__, dbg_endpoint.id);
849 	printf("%s, DPMAC State= %d\n", __func__, state);
850 
851 	memset(&dbg_endpoint, 0, sizeof(struct dprc_endpoint));
852 	err = dprc_get_connection(dflt_mc_io, MC_CMD_NO_FLAGS,
853 				    dflt_dprc_handle, &dpmac_endpoint,
854 				    &dbg_endpoint, &state);
855 	printf("%s, DPNI Type= %s\n", __func__, dbg_endpoint.type);
856 	printf("%s, DPNI ID= %d\n", __func__, dbg_endpoint.id);
857 	printf("%s, DPNI State= %d\n", __func__, state);
858 #endif
859 	return err;
860 }
861 
862 static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
863 {
864 	int err;
865 
866 	/* and get a handle for the DPNI this interface is associate with */
867 	err = dpni_open(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_id,
868 			&dflt_dpni->dpni_handle);
869 	if (err) {
870 		printf("dpni_open() failed\n");
871 		goto err_open;
872 	}
873 	err = dpni_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
874 				  dflt_dpni->dpni_handle,
875 				  &dflt_dpni->dpni_attrs);
876 	if (err) {
877 		printf("dpni_get_attributes() failed (err=%d)\n", err);
878 		goto err_get_attr;
879 	}
880 
881 	/* Configure our buffers' layout */
882 	dflt_dpni->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
883 				   DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
884 				   DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE |
885 				   DPNI_BUF_LAYOUT_OPT_DATA_ALIGN;
886 	dflt_dpni->buf_layout.pass_parser_result = true;
887 	dflt_dpni->buf_layout.pass_frame_status = true;
888 	dflt_dpni->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
889 	/* HW erratum mandates data alignment in multiples of 256 */
890 	dflt_dpni->buf_layout.data_align = LDPAA_ETH_BUF_ALIGN;
891 
892 	/* ...rx, ... */
893 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
894 				     dflt_dpni->dpni_handle,
895 				     &dflt_dpni->buf_layout, DPNI_QUEUE_RX);
896 	if (err) {
897 		printf("dpni_set_buffer_layout() failed");
898 		goto err_buf_layout;
899 	}
900 
901 	/* ... tx, ... */
902 	/* remove Rx-only options */
903 	dflt_dpni->buf_layout.options &= ~(DPNI_BUF_LAYOUT_OPT_DATA_ALIGN |
904 				      DPNI_BUF_LAYOUT_OPT_PARSER_RESULT);
905 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
906 				     dflt_dpni->dpni_handle,
907 				     &dflt_dpni->buf_layout, DPNI_QUEUE_TX);
908 	if (err) {
909 		printf("dpni_set_buffer_layout() failed");
910 		goto err_buf_layout;
911 	}
912 
913 	/* ... tx-confirm. */
914 	dflt_dpni->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
915 	err = dpni_set_buffer_layout(dflt_mc_io, MC_CMD_NO_FLAGS,
916 				     dflt_dpni->dpni_handle,
917 				     &dflt_dpni->buf_layout,
918 				     DPNI_QUEUE_TX_CONFIRM);
919 	if (err) {
920 		printf("dpni_set_buffer_layout() failed");
921 		goto err_buf_layout;
922 	}
923 
924 	/* Now that we've set our tx buffer layout, retrieve the minimum
925 	 * required tx data offset.
926 	 */
927 	err = dpni_get_tx_data_offset(dflt_mc_io, MC_CMD_NO_FLAGS,
928 				      dflt_dpni->dpni_handle,
929 				      &priv->tx_data_offset);
930 	if (err) {
931 		printf("dpni_get_tx_data_offset() failed\n");
932 		goto err_data_offset;
933 	}
934 
935 	/* Warn in case TX data offset is not multiple of 64 bytes. */
936 	WARN_ON(priv->tx_data_offset % 64);
937 
938 	/* Accomodate SWA space. */
939 	priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
940 	debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
941 
942 	return 0;
943 
944 err_data_offset:
945 err_buf_layout:
946 err_get_attr:
947 	dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
948 err_open:
949 	return err;
950 }
951 
952 static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
953 {
954 	struct dpni_pools_cfg pools_params;
955 	struct dpni_queue tx_queue;
956 	int err = 0;
957 
958 	memset(&pools_params, 0, sizeof(pools_params));
959 	pools_params.num_dpbp = 1;
960 	pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
961 	pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
962 	err = dpni_set_pools(dflt_mc_io, MC_CMD_NO_FLAGS,
963 			     dflt_dpni->dpni_handle, &pools_params);
964 	if (err) {
965 		printf("dpni_set_pools() failed\n");
966 		return err;
967 	}
968 
969 	memset(&tx_queue, 0, sizeof(struct dpni_queue));
970 
971 	err = dpni_set_queue(dflt_mc_io, MC_CMD_NO_FLAGS,
972 			     dflt_dpni->dpni_handle,
973 			     DPNI_QUEUE_TX, 0, 0, &tx_queue);
974 
975 	if (err) {
976 		printf("dpni_set_queue() failed\n");
977 		return err;
978 	}
979 
980 	err = dpni_set_tx_confirmation_mode(dflt_mc_io, MC_CMD_NO_FLAGS,
981 					    dflt_dpni->dpni_handle,
982 					    DPNI_CONF_DISABLE);
983 	if (err) {
984 		printf("dpni_set_tx_confirmation_mode() failed\n");
985 		return err;
986 	}
987 
988 	return 0;
989 }
990 
991 static int ldpaa_eth_netdev_init(struct eth_device *net_dev,
992 				 phy_interface_t enet_if)
993 {
994 	int err;
995 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
996 
997 	sprintf(net_dev->name, "DPMAC%d@%s", priv->dpmac_id,
998 		phy_interface_strings[enet_if]);
999 
1000 	net_dev->iobase = 0;
1001 	net_dev->init = ldpaa_eth_open;
1002 	net_dev->halt = ldpaa_eth_stop;
1003 	net_dev->send = ldpaa_eth_tx;
1004 	net_dev->recv = ldpaa_eth_pull_dequeue_rx;
1005 
1006 #ifdef CONFIG_PHYLIB
1007 	err = init_phy(net_dev);
1008 	if (err < 0)
1009 		return err;
1010 #endif
1011 
1012 	err = eth_register(net_dev);
1013 	if (err < 0) {
1014 		printf("eth_register() = %d\n", err);
1015 		return err;
1016 	}
1017 
1018 	return 0;
1019 }
1020 
1021 int ldpaa_eth_init(int dpmac_id, phy_interface_t enet_if)
1022 {
1023 	struct eth_device		*net_dev = NULL;
1024 	struct ldpaa_eth_priv		*priv = NULL;
1025 	int				err = 0;
1026 
1027 	/* Net device */
1028 	net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
1029 	if (!net_dev) {
1030 		printf("eth_device malloc() failed\n");
1031 		return -ENOMEM;
1032 	}
1033 	memset(net_dev, 0, sizeof(struct eth_device));
1034 
1035 	/* alloc the ldpaa ethernet private struct */
1036 	priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
1037 	if (!priv) {
1038 		printf("ldpaa_eth_priv malloc() failed\n");
1039 		return -ENOMEM;
1040 	}
1041 	memset(priv, 0, sizeof(struct ldpaa_eth_priv));
1042 
1043 	net_dev->priv = (void *)priv;
1044 	priv->net_dev = (struct eth_device *)net_dev;
1045 	priv->dpmac_id = dpmac_id;
1046 	debug("%s dpmac_id=%d\n", __func__, dpmac_id);
1047 
1048 	err = ldpaa_eth_netdev_init(net_dev, enet_if);
1049 	if (err)
1050 		goto err_netdev_init;
1051 
1052 	debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
1053 	return 0;
1054 
1055 err_netdev_init:
1056 	free(priv);
1057 	net_dev->priv = NULL;
1058 	free(net_dev);
1059 
1060 	return err;
1061 }
1062