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