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