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