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