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