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