Prepare v2023.10
[platform/kernel/u-boot.git] / drivers / net / fsl-mc / mc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2014 Freescale Semiconductor, Inc.
4  * Copyright 2017-2018, 2020-2021 NXP
5  */
6 #include <common.h>
7 #include <command.h>
8 #include <cpu_func.h>
9 #include <env.h>
10 #include <errno.h>
11 #include <image.h>
12 #include <log.h>
13 #include <malloc.h>
14 #include <mapmem.h>
15 #include <asm/global_data.h>
16 #include <linux/bug.h>
17 #include <asm/io.h>
18 #include <linux/delay.h>
19 #include <linux/libfdt.h>
20 #include <net.h>
21 #include <fdt_support.h>
22 #include <fsl-mc/fsl_mc.h>
23 #include <fsl-mc/fsl_mc_sys.h>
24 #include <fsl-mc/fsl_mc_private.h>
25 #include <fsl-mc/fsl_dpmng.h>
26 #include <fsl-mc/fsl_dprc.h>
27 #include <fsl-mc/fsl_dpio.h>
28 #include <fsl-mc/fsl_dpni.h>
29 #include <fsl-mc/fsl_dpsparser.h>
30 #include <fsl-mc/fsl_qbman_portal.h>
31 #include <fsl-mc/ldpaa_wriop.h>
32 #include <net/ldpaa_eth.h>
33
34 #define MC_RAM_BASE_ADDR_ALIGNMENT  (512UL * 1024 * 1024)
35 #define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1))
36 #define MC_RAM_SIZE_ALIGNMENT       (256UL * 1024 * 1024)
37
38 #define MC_MEM_SIZE_ENV_VAR     "mcmemsize"
39 #define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout"
40 #define MC_BOOT_ENV_VAR         "mcinitcmd"
41 #define MC_DRAM_BLOCK_DEFAULT_SIZE (512UL * 1024 * 1024)
42
43 #define MC_BUFFER_SIZE   (1024 * 1024 * 16)
44 #define MAGIC_MC 0x4d430100
45 #define MC_FW_ADDR_MASK_LOW 0xE0000000
46 #define MC_FW_ADDR_MASK_HIGH 0X1FFFF
47 #define MC_STRUCT_BUFFER_OFFSET 0x01000000
48 #define MC_OFFSET_DELTA MC_STRUCT_BUFFER_OFFSET
49
50 #define LOG_HEADER_FLAG_BUFFER_WRAPAROUND 0x80000000
51 #define LAST_BYTE(a) ((a) & ~(LOG_HEADER_FLAG_BUFFER_WRAPAROUND))
52
53 DECLARE_GLOBAL_DATA_PTR;
54 static int mc_memset_resv_ram;
55 static struct mc_version mc_ver_info;
56 static int mc_boot_status = -1;
57 static int mc_dpl_applied = -1;
58 #ifdef CFG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
59 static int mc_aiop_applied = -1;
60 #endif
61 struct fsl_mc_io *root_mc_io = NULL;
62 struct fsl_mc_io *dflt_mc_io = NULL; /* child container */
63 uint16_t root_dprc_handle = 0;
64 uint16_t dflt_dprc_handle = 0;
65 int child_dprc_id;
66 struct fsl_dpbp_obj *dflt_dpbp = NULL;
67 struct fsl_dpio_obj *dflt_dpio = NULL;
68 struct fsl_dpni_obj *dflt_dpni = NULL;
69 static u64 mc_lazy_dpl_addr;
70 static u32 dpsparser_obj_id;
71 static u16 dpsparser_handle;
72 static char *mc_err_msg_apply_spb[] = MC_ERROR_MSG_APPLY_SPB;
73
74 #ifdef DEBUG
75 void dump_ram_words(const char *title, void *addr)
76 {
77         int i;
78         uint32_t *words = addr;
79
80         printf("Dumping beginning of %s (%p):\n", title, addr);
81         for (i = 0; i < 16; i++)
82                 printf("%#x ", words[i]);
83
84         printf("\n");
85 }
86
87 void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs)
88 {
89         printf("MC CCSR registers:\n"
90                 "reg_gcr1 %#x\n"
91                 "reg_gsr %#x\n"
92                 "reg_sicbalr %#x\n"
93                 "reg_sicbahr %#x\n"
94                 "reg_sicapr %#x\n"
95                 "reg_mcfbalr %#x\n"
96                 "reg_mcfbahr %#x\n"
97                 "reg_mcfapr %#x\n"
98                 "reg_psr %#x\n",
99                 mc_ccsr_regs->reg_gcr1,
100                 mc_ccsr_regs->reg_gsr,
101                 mc_ccsr_regs->reg_sicbalr,
102                 mc_ccsr_regs->reg_sicbahr,
103                 mc_ccsr_regs->reg_sicapr,
104                 mc_ccsr_regs->reg_mcfbalr,
105                 mc_ccsr_regs->reg_mcfbahr,
106                 mc_ccsr_regs->reg_mcfapr,
107                 mc_ccsr_regs->reg_psr);
108 }
109 #else
110
111 #define dump_ram_words(title, addr)
112 #define dump_mc_ccsr_regs(mc_ccsr_regs)
113
114 #endif /* DEBUG */
115
116 /**
117  * Copying MC firmware or DPL image to DDR
118  */
119 static int mc_copy_image(const char *title,
120                          u64 image_addr, u32 image_size, u64 mc_ram_addr)
121 {
122         debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
123         memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
124         flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size);
125         return 0;
126 }
127
128 #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
129 /**
130  * MC firmware FIT image parser checks if the image is in FIT
131  * format, verifies integrity of the image and calculates
132  * raw image address and size values.
133  * Returns 0 on success and a negative errno on error.
134  * task fail.
135  **/
136 int parse_mc_firmware_fit_image(u64 mc_fw_addr,
137                                 const void **raw_image_addr,
138                                 size_t *raw_image_size)
139 {
140         int format;
141         void *fit_hdr = (void *)mc_fw_addr;
142
143         /* Check if Image is in FIT format */
144         format = genimg_get_format(fit_hdr);
145
146         if (format != IMAGE_FORMAT_FIT) {
147                 printf("fsl-mc: ERR: Bad firmware image (not a FIT image)\n");
148                 return -EINVAL;
149         }
150
151         if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
152                 printf("fsl-mc: ERR: Bad firmware image (bad FIT header)\n");
153                 return -EINVAL;
154         }
155
156         return fit_get_data_node(fit_hdr, "firmware", raw_image_addr,
157                                  raw_image_size);
158 }
159 #endif
160
161 #define MC_DT_INCREASE_SIZE     64
162
163 enum mc_fixup_type {
164         MC_FIXUP_DPL,
165         MC_FIXUP_DPC
166 };
167
168 static int mc_fixup_mac_addr(void *blob, int nodeoffset,
169                              const char *propname, struct udevice *eth_dev,
170                              enum mc_fixup_type type)
171 {
172         struct eth_pdata *plat = dev_get_plat(eth_dev);
173         unsigned char *enetaddr = plat->enetaddr;
174         int eth_index = dev_seq(eth_dev);
175         int err = 0, len = 0, size, i;
176         unsigned char env_enetaddr[ARP_HLEN];
177         unsigned int enetaddr_32[ARP_HLEN];
178         void *val = NULL;
179
180         switch (type) {
181         case MC_FIXUP_DPL:
182                 /* DPL likes its addresses on 32 * ARP_HLEN bits */
183                 for (i = 0; i < ARP_HLEN; i++)
184                         enetaddr_32[i] = cpu_to_fdt32(enetaddr[i]);
185                 val = enetaddr_32;
186                 len = sizeof(enetaddr_32);
187                 break;
188         case MC_FIXUP_DPC:
189                 val = enetaddr;
190                 len = ARP_HLEN;
191                 break;
192         }
193
194         /* MAC address property present */
195         if (fdt_get_property(blob, nodeoffset, propname, NULL)) {
196                 /* u-boot MAC addr randomly assigned - leave the present one */
197                 if (!eth_env_get_enetaddr_by_index("eth", eth_index,
198                                                    env_enetaddr))
199                         return err;
200         } else {
201                 size = MC_DT_INCREASE_SIZE + strlen(propname) + len;
202                 /* make room for mac address property */
203                 err = fdt_increase_size(blob, size);
204                 if (err) {
205                         printf("fdt_increase_size: err=%s\n",
206                                fdt_strerror(err));
207                         return err;
208                 }
209         }
210
211         err = fdt_setprop(blob, nodeoffset, propname, val, len);
212         if (err) {
213                 printf("fdt_setprop: err=%s\n", fdt_strerror(err));
214                 return err;
215         }
216
217         return err;
218 }
219
220 #define is_dpni(s) (s != NULL ? !strncmp(s, "dpni@", 5) : 0)
221
222 const char *dpl_get_connection_endpoint(void *blob, char *endpoint)
223 {
224         int connoffset = fdt_path_offset(blob, "/connections"), off;
225         const char *s1, *s2;
226
227         for (off = fdt_first_subnode(blob, connoffset);
228              off >= 0;
229              off = fdt_next_subnode(blob, off)) {
230                 s1 = fdt_stringlist_get(blob, off, "endpoint1", 0, NULL);
231                 s2 = fdt_stringlist_get(blob, off, "endpoint2", 0, NULL);
232
233                 if (!s1 || !s2)
234                         continue;
235
236                 if (strcmp(endpoint, s1) == 0)
237                         return s2;
238
239                 if (strcmp(endpoint, s2) == 0)
240                         return s1;
241         }
242
243         return NULL;
244 }
245
246 static int mc_fixup_dpl_mac_addr(void *blob, int dpmac_id,
247                                  struct udevice *eth_dev)
248 {
249         int objoff = fdt_path_offset(blob, "/objects");
250         int dpmacoff = -1, dpnioff = -1;
251         const char *endpoint;
252         char mac_name[10];
253         int err;
254
255         sprintf(mac_name, "dpmac@%d", dpmac_id);
256         dpmacoff = fdt_subnode_offset(blob, objoff, mac_name);
257         if (dpmacoff < 0)
258                 /* dpmac not defined in DPL, so skip it. */
259                 return 0;
260
261         err = mc_fixup_mac_addr(blob, dpmacoff, "mac_addr", eth_dev,
262                                 MC_FIXUP_DPL);
263         if (err) {
264                 printf("Error fixing up dpmac mac_addr in DPL\n");
265                 return err;
266         }
267
268         /* now we need to figure out if there is any
269          * DPNI connected to this MAC, so we walk the
270          * connection list
271          */
272         endpoint = dpl_get_connection_endpoint(blob, mac_name);
273         if (!is_dpni(endpoint))
274                 return 0;
275
276         /* let's see if we can fixup the DPNI as well */
277         dpnioff = fdt_subnode_offset(blob, objoff, endpoint);
278         if (dpnioff < 0)
279                 /* DPNI not defined in DPL in the objects area */
280                 return 0;
281
282         return mc_fixup_mac_addr(blob, dpnioff, "mac_addr", eth_dev,
283                                  MC_FIXUP_DPL);
284 }
285
286 void fdt_fixup_mc_ddr(u64 *base, u64 *size)
287 {
288         u64 mc_size = mc_get_dram_block_size();
289
290         if (mc_size < MC_DRAM_BLOCK_DEFAULT_SIZE) {
291                 *base = mc_get_dram_addr() + mc_size;
292                 *size = MC_DRAM_BLOCK_DEFAULT_SIZE - mc_size;
293         }
294 }
295
296 void fdt_fsl_mc_fixup_iommu_map_entry(void *blob)
297 {
298         u32 *prop;
299         u32 iommu_map[4], phandle;
300         int offset;
301         int lenp;
302
303         /* find fsl-mc node */
304         offset = fdt_path_offset(blob, "/soc/fsl-mc");
305         if (offset < 0)
306                 offset = fdt_path_offset(blob, "/fsl-mc");
307         if (offset < 0) {
308                 printf("%s: fsl-mc: ERR: fsl-mc node not found in DT, err %d\n",
309                        __func__, offset);
310                 return;
311         }
312
313         prop = fdt_getprop_w(blob, offset, "iommu-map", &lenp);
314         if (!prop) {
315                 debug("%s: fsl-mc: ERR: missing iommu-map in fsl-mc bus node\n",
316                       __func__);
317                 return;
318         }
319
320         iommu_map[0] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_START);
321         iommu_map[1] = *++prop;
322         iommu_map[2] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_START);
323         iommu_map[3] = cpu_to_fdt32(FSL_DPAA2_STREAM_ID_END -
324                 FSL_DPAA2_STREAM_ID_START + 1);
325
326         fdt_setprop_inplace(blob, offset, "iommu-map",
327                             iommu_map, sizeof(iommu_map));
328
329         /* get phandle to MSI controller */
330         prop = (u32 *)fdt_getprop(blob, offset, "msi-parent", 0);
331         if (!prop) {
332                 debug("\n%s: ERROR: missing msi-parent\n", __func__);
333                 return;
334         }
335         phandle = fdt32_to_cpu(*prop);
336
337         /* also set msi-map property */
338         fdt_appendprop_u32(blob, offset, "msi-map", FSL_DPAA2_STREAM_ID_START);
339         fdt_appendprop_u32(blob, offset, "msi-map", phandle);
340         fdt_appendprop_u32(blob, offset, "msi-map", FSL_DPAA2_STREAM_ID_START);
341         fdt_appendprop_u32(blob, offset, "msi-map", FSL_DPAA2_STREAM_ID_END -
342                            FSL_DPAA2_STREAM_ID_START + 1);
343 }
344
345 static int mc_fixup_dpc_mac_addr(void *blob, int dpmac_id,
346                                  struct udevice *eth_dev)
347 {
348         int nodeoffset = fdt_path_offset(blob, "/board_info/ports"), noff;
349         int err = 0;
350         char mac_name[10];
351         const char link_type_mode[] = "MAC_LINK_TYPE_FIXED";
352
353         sprintf(mac_name, "mac@%d", dpmac_id);
354
355         /* node not found - create it */
356         noff = fdt_subnode_offset(blob, nodeoffset, (const char *)mac_name);
357         if (noff < 0) {
358                 err = fdt_increase_size(blob, 200);
359                 if (err) {
360                         printf("fdt_increase_size: err=%s\n", fdt_strerror(err));
361                         return err;
362                 }
363
364                 noff = fdt_add_subnode(blob, nodeoffset, mac_name);
365                 if (noff < 0) {
366                         printf("fdt_add_subnode: err=%s\n",
367                                fdt_strerror(err));
368                         return err;
369                 }
370
371                 /* add default property of fixed link */
372                 err = fdt_appendprop_string(blob, noff,
373                                             "link_type", link_type_mode);
374                 if (err) {
375                         printf("fdt_appendprop_string: err=%s\n",
376                                fdt_strerror(err));
377                         return err;
378                 }
379         }
380
381         return mc_fixup_mac_addr(blob, noff, "port_mac_address", eth_dev,
382                                  MC_FIXUP_DPC);
383 }
384
385 static int mc_fixup_mac_addrs(void *blob, enum mc_fixup_type type)
386 {
387         struct udevice *eth_dev;
388         int err = 0, ret = 0;
389         struct uclass *uc;
390         uint32_t dpmac_id;
391
392         uclass_get(UCLASS_ETH, &uc);
393         uclass_foreach_dev(eth_dev, uc) {
394                 if (!eth_dev->driver || !eth_dev->driver->name ||
395                     strcmp(eth_dev->driver->name, LDPAA_ETH_DRIVER_NAME))
396                         continue;
397
398                 dpmac_id = ldpaa_eth_get_dpmac_id(eth_dev);
399                 switch (type) {
400                 case MC_FIXUP_DPL:
401                         err = mc_fixup_dpl_mac_addr(blob, dpmac_id, eth_dev);
402                         break;
403                 case MC_FIXUP_DPC:
404                         err = mc_fixup_dpc_mac_addr(blob, dpmac_id, eth_dev);
405                         break;
406                 default:
407                         break;
408                 }
409
410                 if (err)
411                         printf("fsl-mc: ERROR fixing mac address for %s\n", eth_dev->name);
412                 ret |= err;
413         }
414
415         return ret;
416 }
417
418 static int mc_fixup_dpc(u64 dpc_addr)
419 {
420         void *blob = (void *)dpc_addr;
421         int nodeoffset, err = 0;
422
423         /* delete any existing ICID pools */
424         nodeoffset = fdt_path_offset(blob, "/resources/icid_pools");
425         if (fdt_del_node(blob, nodeoffset) < 0)
426                 printf("\nfsl-mc: WARNING: could not delete ICID pool\n");
427
428         /* add a new pool */
429         nodeoffset = fdt_path_offset(blob, "/resources");
430         if (nodeoffset < 0) {
431                 printf("\nfsl-mc: ERROR: DPC is missing /resources\n");
432                 return -EINVAL;
433         }
434         nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools");
435         nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0");
436         do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
437                              "base_icid", FSL_DPAA2_STREAM_ID_START, 1);
438         do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
439                              "num",
440                              FSL_DPAA2_STREAM_ID_END -
441                              FSL_DPAA2_STREAM_ID_START + 1, 1);
442
443         /* fixup MAC addresses for dpmac ports */
444         nodeoffset = fdt_path_offset(blob, "/board_info/ports");
445         if (nodeoffset < 0) {
446                 err = fdt_increase_size(blob, 512);
447                 if (err) {
448                         printf("fdt_increase_size: err=%s\n",
449                                fdt_strerror(err));
450                         goto out;
451                 }
452                 nodeoffset = fdt_path_offset(blob, "/board_info");
453                 if (nodeoffset < 0)
454                         nodeoffset = fdt_add_subnode(blob, 0, "board_info");
455
456                 nodeoffset = fdt_add_subnode(blob, nodeoffset, "ports");
457         }
458
459         err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPC);
460
461 out:
462         flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob));
463
464         return err;
465 }
466
467 static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpc_addr)
468 {
469         u64 mc_dpc_offset;
470 #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR
471         int error;
472         void *dpc_fdt_hdr;
473         int dpc_size;
474 #endif
475
476 #ifdef CFG_SYS_LS_MC_DRAM_DPC_OFFSET
477         BUILD_BUG_ON((CFG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 ||
478                      CFG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff);
479
480         mc_dpc_offset = CFG_SYS_LS_MC_DRAM_DPC_OFFSET;
481 #else
482 #error "CFG_SYS_LS_MC_DRAM_DPC_OFFSET not defined"
483 #endif
484
485         /*
486          * Load the MC DPC blob in the MC private DRAM block:
487          */
488 #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR
489         printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset);
490 #else
491         /*
492          * Get address and size of the DPC blob stored in flash:
493          */
494         dpc_fdt_hdr = (void *)mc_dpc_addr;
495
496         error = fdt_check_header(dpc_fdt_hdr);
497         if (error != 0) {
498                 /*
499                  * Don't return with error here, since the MC firmware can
500                  * still boot without a DPC
501                  */
502                 printf("\nfsl-mc: WARNING: No DPC image found");
503                 return 0;
504         }
505
506         dpc_size = fdt_totalsize(dpc_fdt_hdr);
507         if (dpc_size > CFG_SYS_LS_MC_DPC_MAX_LENGTH) {
508                 printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n",
509                        dpc_size);
510                 return -EINVAL;
511         }
512
513         mc_copy_image("MC DPC blob",
514                       (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
515 #endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
516
517         if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset))
518                 return -EINVAL;
519
520         dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
521         return 0;
522 }
523
524 static int mc_fixup_dpl(u64 dpl_addr)
525 {
526         void *blob = (void *)dpl_addr;
527         u32 ver = fdt_getprop_u32_default(blob, "/", "dpl-version", 0);
528         int err = 0;
529
530         /* The DPL fixup for mac addresses is only relevant
531          * for old-style DPLs
532          */
533         if (ver >= 10)
534                 return 0;
535
536         err = mc_fixup_mac_addrs(blob, MC_FIXUP_DPL);
537         flush_dcache_range(dpl_addr, dpl_addr + fdt_totalsize(blob));
538
539         return err;
540 }
541
542 static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size, u64 mc_dpl_addr)
543 {
544         u64 mc_dpl_offset;
545 #ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR
546         int error;
547         void *dpl_fdt_hdr;
548         int dpl_size;
549 #endif
550
551 #ifdef CFG_SYS_LS_MC_DRAM_DPL_OFFSET
552         BUILD_BUG_ON((CFG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
553                      CFG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
554
555         mc_dpl_offset = CFG_SYS_LS_MC_DRAM_DPL_OFFSET;
556 #else
557 #error "CFG_SYS_LS_MC_DRAM_DPL_OFFSET not defined"
558 #endif
559
560         /*
561          * Load the MC DPL blob in the MC private DRAM block:
562          */
563 #ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR
564         printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset);
565 #else
566         /*
567          * Get address and size of the DPL blob stored in flash:
568          */
569         dpl_fdt_hdr = (void *)mc_dpl_addr;
570
571         error = fdt_check_header(dpl_fdt_hdr);
572         if (error != 0) {
573                 printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n");
574                 return error;
575         }
576
577         dpl_size = fdt_totalsize(dpl_fdt_hdr);
578         if (dpl_size > CFG_SYS_LS_MC_DPL_MAX_LENGTH) {
579                 printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n",
580                        dpl_size);
581                 return -EINVAL;
582         }
583
584         mc_copy_image("MC DPL blob",
585                       (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
586 #endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */
587
588         if (mc_fixup_dpl(mc_ram_addr + mc_dpl_offset))
589                 return -EINVAL;
590         dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset));
591         return 0;
592 }
593
594 /**
595  * Return the MC boot timeout value in milliseconds
596  */
597 static unsigned long get_mc_boot_timeout_ms(void)
598 {
599         unsigned long timeout_ms = CFG_SYS_LS_MC_BOOT_TIMEOUT_MS;
600
601         char *timeout_ms_env_var = env_get(MC_BOOT_TIMEOUT_ENV_VAR);
602
603         if (timeout_ms_env_var) {
604                 timeout_ms = dectoul(timeout_ms_env_var, NULL);
605                 if (timeout_ms == 0) {
606                         printf("fsl-mc: WARNING: Invalid value for \'"
607                                MC_BOOT_TIMEOUT_ENV_VAR
608                                "\' environment variable: %lu\n",
609                                timeout_ms);
610
611                         timeout_ms = CFG_SYS_LS_MC_BOOT_TIMEOUT_MS;
612                 }
613         }
614
615         return timeout_ms;
616 }
617
618 #ifdef CFG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
619
620 __weak bool soc_has_aiop(void)
621 {
622         return false;
623 }
624
625 static int load_mc_aiop_img(u64 aiop_fw_addr)
626 {
627         u64 mc_ram_addr = mc_get_dram_addr();
628 #ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR
629         void *aiop_img;
630 #endif
631
632         /* Check if AIOP is available */
633         if (!soc_has_aiop())
634                 return -ENODEV;
635         /*
636          * Load the MC AIOP image in the MC private DRAM block:
637          */
638
639 #ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR
640         printf("MC AIOP is preloaded to %#llx\n", mc_ram_addr +
641                CFG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET);
642 #else
643         aiop_img = (void *)aiop_fw_addr;
644         mc_copy_image("MC AIOP image",
645                       (u64)aiop_img, CFG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH,
646                       mc_ram_addr + CFG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET);
647 #endif
648         mc_aiop_applied = 0;
649
650         return 0;
651 }
652 #endif
653
654 static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
655 {
656         u32 reg_gsr;
657         u32 mc_fw_boot_status;
658         unsigned long timeout_ms = get_mc_boot_timeout_ms();
659         struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
660
661         dmb();
662         assert(timeout_ms > 0);
663         for (;;) {
664                 udelay(1000);   /* throttle polling */
665                 reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
666                 mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
667                 if (mc_fw_boot_status & 0x1)
668                         break;
669
670                 timeout_ms--;
671                 if (timeout_ms == 0)
672                         break;
673         }
674
675         if (timeout_ms == 0) {
676                 printf("ERROR: timeout\n");
677
678                 /* TODO: Get an error status from an MC CCSR register */
679                 return -ETIMEDOUT;
680         }
681
682         if (mc_fw_boot_status != 0x1) {
683                 /*
684                  * TODO: Identify critical errors from the GSR register's FS
685                  * field and for those errors, set error to -ENODEV or other
686                  * appropriate errno, so that the status property is set to
687                  * failure in the fsl,dprc device tree node.
688                  */
689                 printf("WARNING: Firmware returned an error (GSR: %#x)\n",
690                        reg_gsr);
691         } else {
692                 printf("SUCCESS\n");
693         }
694
695         *final_reg_gsr = reg_gsr;
696         return 0;
697 }
698
699 int mc_init(u64 mc_fw_addr, u64 mc_dpc_addr)
700 {
701         int error = 0;
702         int portal_id = 0;
703         struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
704         u64 mc_ram_addr = mc_get_dram_addr();
705         u32 reg_gsr;
706         u32 reg_mcfbalr;
707 #ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
708         const void *raw_image_addr;
709         size_t raw_image_size = 0;
710 #endif
711         u8 mc_ram_num_256mb_blocks;
712         size_t mc_ram_size = mc_get_dram_block_size();
713
714         mc_ram_num_256mb_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT;
715
716         if (mc_ram_num_256mb_blocks >= 0xff) {
717                 error = -EINVAL;
718                 printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
719                        mc_ram_size);
720                 goto out;
721         }
722
723         /*
724          * To support 128 MB DDR Size for MC
725          */
726         if (mc_ram_num_256mb_blocks == 0)
727                 mc_ram_num_256mb_blocks = 0xFF;
728
729         /*
730          * Management Complex cores should be held at reset out of POR.
731          * U-Boot should be the first software to touch MC. To be safe,
732          * we reset all cores again by setting GCR1 to 0. It doesn't do
733          * anything if they are held at reset. After we setup the firmware
734          * we kick off MC by deasserting the reset bit for core 0, and
735          * deasserting the reset bits for Command Portal Managers.
736          * The stop bits are not touched here. They are used to stop the
737          * cores when they are active. Setting stop bits doesn't stop the
738          * cores from fetching instructions when they are released from
739          * reset.
740          */
741         out_le32(&mc_ccsr_regs->reg_gcr1, 0);
742         dmb();
743
744 #ifdef CONFIG_SYS_LS_MC_FW_IN_DDR
745         printf("MC firmware is preloaded to %#llx\n", mc_ram_addr);
746 #else
747         error = parse_mc_firmware_fit_image(mc_fw_addr, &raw_image_addr,
748                                             &raw_image_size);
749         if (error != 0)
750                 goto out;
751         /*
752          * Load the MC FW at the beginning of the MC private DRAM block:
753          */
754         mc_copy_image("MC Firmware",
755                       (u64)raw_image_addr, raw_image_size, mc_ram_addr);
756 #endif
757         dump_ram_words("firmware", (void *)mc_ram_addr);
758
759         error = load_mc_dpc(mc_ram_addr, mc_ram_size, mc_dpc_addr);
760         if (error != 0)
761                 goto out;
762
763         debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
764         dump_mc_ccsr_regs(mc_ccsr_regs);
765
766         /*
767          * Tell MC what is the address range of the DRAM block assigned to it:
768          */
769         if (mc_ram_num_256mb_blocks < 0xFF) {
770                 reg_mcfbalr = (u32)mc_ram_addr |
771                                 (mc_ram_num_256mb_blocks - 1);
772         } else {
773                 reg_mcfbalr = (u32)mc_ram_addr |
774                                 (mc_ram_num_256mb_blocks);
775         }
776
777         out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
778         out_le32(&mc_ccsr_regs->reg_mcfbahr,
779                  (u32)(mc_ram_addr >> 32));
780         out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ);
781
782         /*
783          * Tell the MC that we want delayed DPL deployment.
784          */
785         out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
786
787         printf("\nfsl-mc: Booting Management Complex ... ");
788
789         /*
790          * Deassert reset and release MC core 0 to run
791          */
792         out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
793         error = wait_for_mc(true, &reg_gsr);
794         if (error != 0)
795                 goto out;
796
797         /*
798          * TODO: need to obtain the portal_id for the root container from the
799          * DPL
800          */
801         portal_id = 0;
802
803         /*
804          * Initialize the global default MC portal
805          * And check that the MC firmware is responding portal commands:
806          */
807         root_mc_io = calloc(sizeof(struct fsl_mc_io), 1);
808         if (!root_mc_io) {
809                 printf(" No memory: calloc() failed\n");
810                 return -ENOMEM;
811         }
812
813         root_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
814         debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
815               portal_id, root_mc_io->mmio_regs);
816
817         error = mc_get_version(root_mc_io, MC_CMD_NO_FLAGS, &mc_ver_info);
818         if (error != 0) {
819                 printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
820                        error);
821                 goto out;
822         }
823
824         printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
825                mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
826                reg_gsr & GSR_FS_MASK);
827
828 out:
829         if (error != 0)
830                 mc_boot_status = error;
831         else
832                 mc_boot_status = 0;
833
834         return error;
835 }
836
837 int mc_apply_dpl(u64 mc_dpl_addr)
838 {
839         struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
840         int error = 0;
841         u32 reg_gsr;
842         u64 mc_ram_addr = mc_get_dram_addr();
843         size_t mc_ram_size = mc_get_dram_block_size();
844
845         if (!mc_dpl_addr)
846                 return -1;
847
848         error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr);
849         if (error != 0)
850                 return error;
851
852         /*
853          * Tell the MC to deploy the DPL:
854          */
855         out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
856         printf("fsl-mc: Deploying data path layout ... ");
857         error = wait_for_mc(false, &reg_gsr);
858
859         if (!error)
860                 mc_dpl_applied = 0;
861
862         return error;
863 }
864
865 int get_mc_boot_status(void)
866 {
867         return mc_boot_status;
868 }
869
870 #ifdef CFG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
871 int get_aiop_apply_status(void)
872 {
873         return mc_aiop_applied;
874 }
875 #endif
876
877 int get_dpl_apply_status(void)
878 {
879         return mc_dpl_applied;
880 }
881
882 int is_lazy_dpl_addr_valid(void)
883 {
884         return !!mc_lazy_dpl_addr;
885 }
886
887 /*
888  * Return the MC address of private DRAM block.
889  * As per MC design document, MC initial base address
890  * should be least significant 512MB address of MC private
891  * memory, i.e. address should point to end address masked
892  * with 512MB offset in private DRAM block.
893  */
894 u64 mc_get_dram_addr(void)
895 {
896         size_t mc_ram_size = mc_get_dram_block_size();
897
898         if (!mc_memset_resv_ram || (get_mc_boot_status() < 0)) {
899                 mc_memset_resv_ram = 1;
900                 memset((void *)gd->arch.resv_ram, 0, mc_ram_size);
901         }
902
903         return (gd->arch.resv_ram + mc_ram_size - 1) &
904                 MC_RAM_BASE_ADDR_ALIGNMENT_MASK;
905 }
906
907 /**
908  * Return the actual size of the MC private DRAM block.
909  */
910 unsigned long mc_get_dram_block_size(void)
911 {
912         unsigned long dram_block_size = CFG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
913
914         char *dram_block_size_env_var = env_get(MC_MEM_SIZE_ENV_VAR);
915
916         if (dram_block_size_env_var) {
917                 dram_block_size = hextoul(dram_block_size_env_var, NULL);
918
919                 if (dram_block_size < CFG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) {
920                         printf("fsl-mc: WARNING: Invalid value for \'"
921                                MC_MEM_SIZE_ENV_VAR
922                                "\' environment variable: %lu\n",
923                                dram_block_size);
924
925                         dram_block_size = MC_DRAM_BLOCK_DEFAULT_SIZE;
926                 }
927         }
928
929         return dram_block_size;
930 }
931
932 int fsl_mc_ldpaa_init(struct bd_info *bis)
933 {
934         int i;
935
936         for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++)
937                 if (wriop_is_enabled_dpmac(i) == 1)
938                         ldpaa_eth_init(i, wriop_get_enet_if(i));
939         return 0;
940 }
941
942 static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle)
943 {
944         int error;
945         uint16_t major_ver, minor_ver;
946
947         error = dprc_get_api_version(mc_io, 0,
948                                      &major_ver,
949                                      &minor_ver);
950         if (error < 0) {
951                 printf("dprc_get_api_version() failed: %d\n", error);
952                 return error;
953         }
954
955         if (major_ver < DPRC_VER_MAJOR || (major_ver == DPRC_VER_MAJOR &&
956                                            minor_ver < DPRC_VER_MINOR)) {
957                 printf("DPRC version mismatch found %u.%u,",
958                        major_ver, minor_ver);
959                 printf("supported version is %u.%u\n",
960                        DPRC_VER_MAJOR, DPRC_VER_MINOR);
961         }
962
963         return error;
964 }
965
966 static int dpio_init(void)
967 {
968         struct qbman_swp_desc p_des;
969         struct dpio_attr attr;
970         struct dpio_cfg dpio_cfg;
971         int err = 0;
972         uint16_t major_ver, minor_ver;
973
974         dflt_dpio = calloc(sizeof(struct fsl_dpio_obj), 1);
975         if (!dflt_dpio) {
976                 printf("No memory: calloc() failed\n");
977                 err = -ENOMEM;
978                 goto err_calloc;
979         }
980         dpio_cfg.channel_mode = DPIO_LOCAL_CHANNEL;
981         dpio_cfg.num_priorities = 8;
982
983         err = dpio_create(dflt_mc_io,
984                           dflt_dprc_handle,
985                           MC_CMD_NO_FLAGS,
986                           &dpio_cfg,
987                           &dflt_dpio->dpio_id);
988         if (err < 0) {
989                 printf("dpio_create() failed: %d\n", err);
990                 err = -ENODEV;
991                 goto err_create;
992         }
993
994         err = dpio_get_api_version(dflt_mc_io, 0,
995                                    &major_ver,
996                                    &minor_ver);
997         if (err < 0) {
998                 printf("dpio_get_api_version() failed: %d\n", err);
999                 goto err_get_api_ver;
1000         }
1001
1002         if (major_ver < DPIO_VER_MAJOR || (major_ver == DPIO_VER_MAJOR &&
1003                                            minor_ver < DPIO_VER_MINOR)) {
1004                 printf("DPRC version mismatch found %u.%u,",
1005                        major_ver,
1006                        minor_ver);
1007         }
1008
1009         err = dpio_open(dflt_mc_io,
1010                         MC_CMD_NO_FLAGS,
1011                         dflt_dpio->dpio_id,
1012                         &dflt_dpio->dpio_handle);
1013         if (err) {
1014                 printf("dpio_open() failed\n");
1015                 goto err_open;
1016         }
1017
1018         memset(&attr, 0, sizeof(struct dpio_attr));
1019         err = dpio_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
1020                                   dflt_dpio->dpio_handle, &attr);
1021         if (err < 0) {
1022                 printf("dpio_get_attributes() failed: %d\n", err);
1023                 goto err_get_attr;
1024         }
1025
1026         if (dflt_dpio->dpio_id != attr.id) {
1027                 printf("dnpi object id and attribute id are not same\n");
1028                 goto err_attr_not_same;
1029         }
1030
1031 #ifdef DEBUG
1032         printf("Init: DPIO.%d\n", dflt_dpio->dpio_id);
1033 #endif
1034         err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
1035         if (err < 0) {
1036                 printf("dpio_enable() failed %d\n", err);
1037                 goto err_get_enable;
1038         }
1039         debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n",
1040               attr.qbman_portal_ce_offset,
1041               attr.qbman_portal_ci_offset,
1042               attr.qbman_portal_id,
1043               attr.num_priorities);
1044
1045         p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
1046                                         + attr.qbman_portal_ce_offset);
1047         p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
1048                                         + attr.qbman_portal_ci_offset);
1049
1050         dflt_dpio->sw_portal = qbman_swp_init(&p_des);
1051         if (dflt_dpio->sw_portal == NULL) {
1052                 printf("qbman_swp_init() failed\n");
1053                 goto err_get_swp_init;
1054         }
1055         return 0;
1056
1057 err_get_swp_init:
1058         dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
1059 err_get_enable:
1060 err_get_attr:
1061 err_attr_not_same:
1062         dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
1063 err_open:
1064 err_get_api_ver:
1065         dpio_destroy(dflt_mc_io,
1066                      dflt_dprc_handle,
1067                      MC_CMD_NO_FLAGS,
1068                      dflt_dpio->dpio_id);
1069 err_create:
1070         free(dflt_dpio);
1071 err_calloc:
1072         return err;
1073 }
1074
1075 static int dpio_exit(void)
1076 {
1077         int err;
1078
1079         err = dpio_disable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
1080         if (err < 0) {
1081                 printf("dpio_disable() failed: %d\n", err);
1082                 goto err;
1083         }
1084
1085         err = dpio_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
1086         if (err < 0) {
1087                 printf("dpio_close() failed: %d\n", err);
1088                 goto err;
1089         }
1090
1091         err = dpio_destroy(dflt_mc_io,
1092                            dflt_dprc_handle,
1093                            MC_CMD_NO_FLAGS,
1094                            dflt_dpio->dpio_id);
1095         if (err < 0) {
1096                 printf("dpio_destroy() failed: %d\n", err);
1097                 goto err;
1098         }
1099
1100 #ifdef DEBUG
1101         printf("Exit: DPIO.%d\n", dflt_dpio->dpio_id);
1102 #endif
1103
1104         if (dflt_dpio)
1105                 free(dflt_dpio);
1106
1107         return 0;
1108 err:
1109         return err;
1110 }
1111
1112 static int dprc_init(void)
1113 {
1114         int err, child_portal_id, container_id;
1115         struct dprc_cfg cfg;
1116         uint64_t mc_portal_offset;
1117
1118         /* Open root container */
1119         err = dprc_get_container_id(root_mc_io, MC_CMD_NO_FLAGS, &container_id);
1120         if (err < 0) {
1121                 printf("dprc_get_container_id(): Root failed: %d\n", err);
1122                 goto err_root_container_id;
1123         }
1124
1125 #ifdef DEBUG
1126         printf("Root container id = %d\n", container_id);
1127 #endif
1128         err = dprc_open(root_mc_io, MC_CMD_NO_FLAGS, container_id,
1129                         &root_dprc_handle);
1130         if (err < 0) {
1131                 printf("dprc_open(): Root Container failed: %d\n", err);
1132                 goto err_root_open;
1133         }
1134
1135         if (!root_dprc_handle) {
1136                 printf("dprc_open(): Root Container Handle is not valid\n");
1137                 goto err_root_open;
1138         }
1139
1140         err = dprc_version_check(root_mc_io, root_dprc_handle);
1141         if (err < 0) {
1142                 printf("dprc_version_check() failed: %d\n", err);
1143                 goto err_root_open;
1144         }
1145
1146         memset(&cfg, 0, sizeof(struct dprc_cfg));
1147         cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED |
1148                       DPRC_CFG_OPT_OBJ_CREATE_ALLOWED |
1149                       DPRC_CFG_OPT_ALLOC_ALLOWED;
1150         cfg.icid = DPRC_GET_ICID_FROM_POOL;
1151         cfg.portal_id = DPRC_GET_PORTAL_ID_FROM_POOL;
1152         err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS,
1153                                     root_dprc_handle, &cfg,
1154                                     &child_dprc_id,
1155                                     &mc_portal_offset);
1156         if (err < 0) {
1157                 printf("dprc_create_container() failed: %d\n", err);
1158                 goto err_create;
1159         }
1160
1161         dflt_mc_io = calloc(sizeof(struct fsl_mc_io), 1);
1162         if (!dflt_mc_io) {
1163                 err  = -ENOMEM;
1164                 printf(" No memory: calloc() failed\n");
1165                 goto err_calloc;
1166         }
1167
1168         child_portal_id = MC_PORTAL_OFFSET_TO_PORTAL_ID(mc_portal_offset);
1169         dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(child_portal_id);
1170
1171 #ifdef DEBUG
1172         printf("MC portal of child DPRC container: %d, physical addr %p)\n",
1173                child_dprc_id, dflt_mc_io->mmio_regs);
1174 #endif
1175
1176         err = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, child_dprc_id,
1177                         &dflt_dprc_handle);
1178         if (err < 0) {
1179                 printf("dprc_open(): Child container failed: %d\n", err);
1180                 goto err_child_open;
1181         }
1182
1183         if (!dflt_dprc_handle) {
1184                 printf("dprc_open(): Child container Handle is not valid\n");
1185                 goto err_child_open;
1186         }
1187
1188         return 0;
1189 err_child_open:
1190         free(dflt_mc_io);
1191 err_calloc:
1192         dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS,
1193                                root_dprc_handle, child_dprc_id);
1194 err_create:
1195         dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle);
1196 err_root_open:
1197 err_root_container_id:
1198         return err;
1199 }
1200
1201 static int dprc_exit(void)
1202 {
1203         int err;
1204
1205         err = dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle);
1206         if (err < 0) {
1207                 printf("dprc_close(): Child failed: %d\n", err);
1208                 goto err;
1209         }
1210
1211         err = dprc_destroy_container(root_mc_io, MC_CMD_NO_FLAGS,
1212                                      root_dprc_handle, child_dprc_id);
1213         if (err < 0) {
1214                 printf("dprc_destroy_container() failed: %d\n", err);
1215                 goto err;
1216         }
1217
1218         err = dprc_close(root_mc_io, MC_CMD_NO_FLAGS, root_dprc_handle);
1219         if (err < 0) {
1220                 printf("dprc_close(): Root failed: %d\n", err);
1221                 goto err;
1222         }
1223
1224         if (dflt_mc_io)
1225                 free(dflt_mc_io);
1226
1227         if (root_mc_io)
1228                 free(root_mc_io);
1229
1230         return 0;
1231
1232 err:
1233         return err;
1234 }
1235
1236 static int dpbp_init(void)
1237 {
1238         int err;
1239         struct dpbp_attr dpbp_attr;
1240         struct dpbp_cfg dpbp_cfg;
1241         uint16_t major_ver, minor_ver;
1242
1243         dflt_dpbp = calloc(sizeof(struct fsl_dpbp_obj), 1);
1244         if (!dflt_dpbp) {
1245                 printf("No memory: calloc() failed\n");
1246                 err = -ENOMEM;
1247                 goto err_calloc;
1248         }
1249
1250         dpbp_cfg.options = 512;
1251
1252         err = dpbp_create(dflt_mc_io,
1253                           dflt_dprc_handle,
1254                           MC_CMD_NO_FLAGS,
1255                           &dpbp_cfg,
1256                           &dflt_dpbp->dpbp_id);
1257
1258         if (err < 0) {
1259                 err = -ENODEV;
1260                 printf("dpbp_create() failed: %d\n", err);
1261                 goto err_create;
1262         }
1263
1264         err = dpbp_get_api_version(dflt_mc_io, 0,
1265                                    &major_ver,
1266                                    &minor_ver);
1267         if (err < 0) {
1268                 printf("dpbp_get_api_version() failed: %d\n", err);
1269                 goto err_get_api_ver;
1270         }
1271
1272         if (major_ver < DPBP_VER_MAJOR || (major_ver == DPBP_VER_MAJOR &&
1273                                            minor_ver < DPBP_VER_MINOR)) {
1274                 printf("DPBP version mismatch found %u.%u,",
1275                        major_ver, minor_ver);
1276                 printf("supported version is %u.%u\n",
1277                        DPBP_VER_MAJOR, DPBP_VER_MINOR);
1278         }
1279
1280         err = dpbp_open(dflt_mc_io,
1281                         MC_CMD_NO_FLAGS,
1282                         dflt_dpbp->dpbp_id,
1283                         &dflt_dpbp->dpbp_handle);
1284         if (err) {
1285                 printf("dpbp_open() failed\n");
1286                 goto err_open;
1287         }
1288
1289         memset(&dpbp_attr, 0, sizeof(struct dpbp_attr));
1290         err = dpbp_get_attributes(dflt_mc_io, MC_CMD_NO_FLAGS,
1291                                   dflt_dpbp->dpbp_handle,
1292                                   &dpbp_attr);
1293         if (err < 0) {
1294                 printf("dpbp_get_attributes() failed: %d\n", err);
1295                 goto err_get_attr;
1296         }
1297
1298         if (dflt_dpbp->dpbp_id != dpbp_attr.id) {
1299                 printf("dpbp object id and attribute id are not same\n");
1300                 goto err_attr_not_same;
1301         }
1302
1303 #ifdef DEBUG
1304         printf("Init: DPBP.%d\n", dflt_dpbp->dpbp_attr.id);
1305 #endif
1306
1307         err = dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
1308         if (err < 0) {
1309                 printf("dpbp_close() failed: %d\n", err);
1310                 goto err_close;
1311         }
1312
1313         return 0;
1314
1315 err_get_attr:
1316 err_attr_not_same:
1317         dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
1318         dpbp_destroy(dflt_mc_io,
1319                      dflt_dprc_handle,
1320                      MC_CMD_NO_FLAGS,
1321                      dflt_dpbp->dpbp_id);
1322 err_get_api_ver:
1323 err_close:
1324 err_open:
1325 err_create:
1326         free(dflt_dpbp);
1327 err_calloc:
1328         return err;
1329 }
1330
1331 static int dpbp_exit(void)
1332 {
1333         int err;
1334
1335         err = dpbp_destroy(dflt_mc_io, dflt_dprc_handle, MC_CMD_NO_FLAGS,
1336                            dflt_dpbp->dpbp_id);
1337         if (err < 0) {
1338                 printf("dpbp_destroy() failed: %d\n", err);
1339                 goto err;
1340         }
1341
1342 #ifdef DEBUG
1343         printf("Exit: DPBP.%d\n", dflt_dpbp->dpbp_attr.id);
1344 #endif
1345
1346         if (dflt_dpbp)
1347                 free(dflt_dpbp);
1348         return 0;
1349
1350 err:
1351         return err;
1352 }
1353
1354 static int dpni_init(void)
1355 {
1356         struct dpni_cfg dpni_cfg = {0};
1357         uint16_t major_ver, minor_ver;
1358         int err;
1359
1360         dflt_dpni = calloc(sizeof(struct fsl_dpni_obj), 1);
1361         if (!dflt_dpni) {
1362                 printf("No memory: calloc() failed\n");
1363                 err = -ENOMEM;
1364                 goto err_calloc;
1365         }
1366
1367         err = dpni_create(dflt_mc_io,
1368                           dflt_dprc_handle,
1369                           MC_CMD_NO_FLAGS,
1370                           &dpni_cfg,
1371                           &dflt_dpni->dpni_id);
1372         if (err < 0) {
1373                 err = -ENODEV;
1374                 printf("dpni create() failed: %d\n", err);
1375                 goto err_create;
1376         }
1377
1378         err = dpni_get_api_version(dflt_mc_io, 0,
1379                                    &major_ver,
1380                                    &minor_ver);
1381         if (err < 0) {
1382                 printf("dpni_get_api_version() failed: %d\n", err);
1383                 goto err_get_version;
1384         }
1385
1386         if (major_ver < DPNI_VER_MAJOR || (major_ver == DPNI_VER_MAJOR &&
1387                                            minor_ver < DPNI_VER_MINOR)) {
1388                 printf("DPNI version mismatch found %u.%u,",
1389                        major_ver, minor_ver);
1390                 printf("supported version is %u.%u\n",
1391                        DPNI_VER_MAJOR, DPNI_VER_MINOR);
1392         }
1393
1394         err = dpni_open(dflt_mc_io,
1395                         MC_CMD_NO_FLAGS,
1396                         dflt_dpni->dpni_id,
1397                         &dflt_dpni->dpni_handle);
1398         if (err) {
1399                 printf("dpni_open() failed\n");
1400                 goto err_open;
1401         }
1402
1403 #ifdef DEBUG
1404         printf("Init: DPNI.%d\n", dflt_dpni->dpni_id);
1405 #endif
1406         err = dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
1407         if (err < 0) {
1408                 printf("dpni_close() failed: %d\n", err);
1409                 goto err_close;
1410         }
1411
1412         return 0;
1413
1414 err_close:
1415         dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
1416 err_open:
1417 err_get_version:
1418         dpni_destroy(dflt_mc_io,
1419                      dflt_dprc_handle,
1420                      MC_CMD_NO_FLAGS,
1421                      dflt_dpni->dpni_id);
1422 err_create:
1423         free(dflt_dpni);
1424 err_calloc:
1425         return err;
1426 }
1427
1428 static int dpni_exit(void)
1429 {
1430         int err;
1431
1432         err = dpni_destroy(dflt_mc_io, dflt_dprc_handle, MC_CMD_NO_FLAGS,
1433                            dflt_dpni->dpni_id);
1434         if (err < 0) {
1435                 printf("dpni_destroy() failed: %d\n", err);
1436                 goto err;
1437         }
1438
1439 #ifdef DEBUG
1440         printf("Exit: DPNI.%d\n", dflt_dpni->dpni_id);
1441 #endif
1442
1443         if (dflt_dpni)
1444                 free(dflt_dpni);
1445         return 0;
1446
1447 err:
1448         return err;
1449 }
1450
1451 static bool is_dpsparser_supported(void)
1452 {
1453         /* dpsparser support was first introduced in MC version: 10.12.0 */
1454         if (mc_ver_info.major < 10)
1455                 return false;
1456         if (mc_ver_info.major == 10)
1457                 return (mc_ver_info.minor >= 12);
1458         return true;
1459 }
1460
1461 static int dpsparser_version_check(struct fsl_mc_io *mc_io)
1462 {
1463         int error;
1464         u16 major_ver, minor_ver;
1465
1466         if (!is_dpsparser_supported())
1467                 return 0;
1468
1469         error = dpsparser_get_api_version(mc_io, 0,
1470                                           &major_ver,
1471                                           &minor_ver);
1472         if (error < 0) {
1473                 printf("dpsparser_get_api_version() failed: %d\n", error);
1474                 return error;
1475         }
1476
1477         if (major_ver < DPSPARSER_VER_MAJOR || (major_ver ==
1478             DPSPARSER_VER_MAJOR && minor_ver < DPSPARSER_VER_MINOR)) {
1479                 printf("DPSPARSER version mismatch found %u.%u,",
1480                        major_ver, minor_ver);
1481                 printf("supported version is %u.%u\n",
1482                        DPSPARSER_VER_MAJOR, DPSPARSER_VER_MINOR);
1483         }
1484
1485         return error;
1486 }
1487
1488 static int dpsparser_init(void)
1489 {
1490         int err = 0;
1491
1492         if (!is_dpsparser_supported())
1493                 return 0;
1494
1495         err = dpsparser_create(dflt_mc_io,
1496                                dflt_dprc_handle,
1497                                MC_CMD_NO_FLAGS,
1498                                &dpsparser_obj_id);
1499         if (err)
1500                 printf("dpsparser_create() failed\n");
1501
1502         err = dpsparser_version_check(dflt_mc_io);
1503         if (err < 0) {
1504                 printf("dpsparser_version_check() failed: %d\n", err);
1505                 goto err_version_check;
1506         }
1507
1508         err = dpsparser_open(dflt_mc_io,
1509                              MC_CMD_NO_FLAGS,
1510                              &dpsparser_handle);
1511         if (err < 0) {
1512                 printf("dpsparser_open() failed: %d\n", err);
1513                 goto err_open;
1514         }
1515
1516         return err;
1517
1518 err_open:
1519 err_version_check:
1520         dpsparser_destroy(dflt_mc_io,
1521                           dflt_dprc_handle,
1522                           MC_CMD_NO_FLAGS, dpsparser_obj_id);
1523
1524         return err;
1525 }
1526
1527 #ifdef DPSPARSER_DESTROY
1528 /* TODO: refactoring needed in the future to allow DPSPARSER object destroy
1529  * Workaround: DO NOT destroy DPSPARSER object because it needs to be available
1530  * on Apply DPL
1531  */
1532 static int dpsparser_exit(void)
1533 {
1534         int err;
1535
1536         if (!is_dpsparser_supported())
1537                 return 0;
1538
1539         dpsparser_close(dflt_mc_io, MC_CMD_NO_FLAGS, dpsparser_handle);
1540         if (err < 0) {
1541                 printf("dpsparser_close() failed: %d\n", err);
1542                 goto err;
1543         }
1544
1545         err = dpsparser_destroy(dflt_mc_io, dflt_dprc_handle,
1546                                 MC_CMD_NO_FLAGS, dpsparser_obj_id);
1547         if (err < 0) {
1548                 printf("dpsparser_destroy() failed: %d\n", err);
1549                 goto err;
1550         }
1551         return 0;
1552
1553 err:
1554         return err;
1555 }
1556 #endif
1557
1558 int mc_apply_spb(u64 mc_spb_addr)
1559 {
1560         int err = 0;
1561         u16 error, err_arr_size;
1562         u64 mc_spb_offset;
1563         u32 spb_size;
1564         struct sp_blob_header *sp_blob;
1565         u64 mc_ram_addr = mc_get_dram_addr();
1566
1567         if (!is_dpsparser_supported())
1568                 return 0;
1569
1570         if (!mc_spb_addr) {
1571                 printf("fsl-mc: Invalid Blob address\n");
1572                 return -1;
1573         }
1574
1575 #ifdef CONFIG_MC_DRAM_SPB_OFFSET
1576         mc_spb_offset = CONFIG_MC_DRAM_SPB_OFFSET;
1577 #else
1578 #error "CONFIG_MC_DRAM_SPB_OFFSET not defined"
1579 #endif
1580
1581         // Read blob header and get size of SPB blob
1582         sp_blob = (struct sp_blob_header *)mc_spb_addr;
1583         spb_size = le32_to_cpu(sp_blob->length);
1584         if (spb_size > CONFIG_MC_SPB_MAX_SIZE) {
1585                 printf("\nfsl-mc: ERROR: Bad SPB image (too large: %d)\n",
1586                        spb_size);
1587                 return -EINVAL;
1588         }
1589
1590         mc_copy_image("MC SP Blob", mc_spb_addr, spb_size,
1591                       mc_ram_addr + mc_spb_offset);
1592
1593         //Invoke MC command to apply SPB blob
1594         printf("fsl-mc: Applying soft parser blob... ");
1595         err = dpsparser_apply_spb(dflt_mc_io, MC_CMD_NO_FLAGS, dpsparser_handle,
1596                                   mc_spb_offset, &error);
1597         if (err)
1598                 return err;
1599
1600         if (error == 0) {
1601                 printf("SUCCESS\n");
1602         } else {
1603                 printf("FAILED with error code = %d:\n", error);
1604                 err_arr_size = (u16)ARRAY_SIZE(mc_err_msg_apply_spb);
1605
1606                 if (error > 0 && error < err_arr_size)
1607                         printf(mc_err_msg_apply_spb[error]);
1608                 else
1609                         printf(MC_ERROR_MSG_SPB_UNKNOWN);
1610         }
1611
1612         return err;
1613 }
1614
1615 static int mc_init_object(void)
1616 {
1617         int err = 0;
1618
1619         err = dprc_init();
1620         if (err < 0) {
1621                 printf("dprc_init() failed: %d\n", err);
1622                 goto err;
1623         }
1624
1625         err = dpbp_init();
1626         if (err < 0) {
1627                 printf("dpbp_init() failed: %d\n", err);
1628                 goto err;
1629         }
1630
1631         err = dpio_init();
1632         if (err < 0) {
1633                 printf("dpio_init() failed: %d\n", err);
1634                 goto err;
1635         }
1636
1637         err = dpni_init();
1638         if (err < 0) {
1639                 printf("dpni_init() failed: %d\n", err);
1640                 goto err;
1641         }
1642
1643         err = dpsparser_init();
1644         if (err < 0) {
1645                 printf("dpsparser_init() failed: %d\n", err);
1646                 goto err;
1647         }
1648
1649         return 0;
1650 err:
1651         return err;
1652 }
1653
1654 int fsl_mc_ldpaa_exit(struct bd_info *bd)
1655 {
1656         int err = 0;
1657         bool is_dpl_apply_status = false;
1658         bool mc_boot_status = false;
1659
1660         if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) {
1661                 err = mc_apply_dpl(mc_lazy_dpl_addr);
1662                 if (!err)
1663                         fdt_fixup_board_enet(working_fdt);
1664                 mc_lazy_dpl_addr = 0;
1665         }
1666
1667         if (!get_mc_boot_status())
1668                 mc_boot_status = true;
1669
1670         /* MC is not loaded intentionally, So return success. */
1671         if (bd && !mc_boot_status)
1672                 return 0;
1673
1674         /* If DPL is deployed, set is_dpl_apply_status as TRUE. */
1675         if (!get_dpl_apply_status())
1676                 is_dpl_apply_status = true;
1677
1678         /*
1679          * For case MC is loaded but DPL is not deployed, return success and
1680          * print message on console. Else FDT fix-up code execution hanged.
1681          */
1682         if (bd && mc_boot_status && !is_dpl_apply_status) {
1683                 printf("fsl-mc: DPL not deployed, DPAA2 ethernet not work\n");
1684                 goto mc_obj_cleanup;
1685         }
1686
1687         if (bd && mc_boot_status && is_dpl_apply_status)
1688                 return 0;
1689
1690 mc_obj_cleanup:
1691         err = dpbp_exit();
1692         if (err < 0) {
1693                 printf("dpbp_exit() failed: %d\n", err);
1694                 goto err;
1695         }
1696
1697         err = dpio_exit();
1698         if (err < 0) {
1699                 printf("dpio_exit() failed: %d\n", err);
1700                 goto err;
1701         }
1702
1703         err = dpni_exit();
1704         if (err < 0) {
1705                 printf("dpni_exit() failed: %d\n", err);
1706                 goto err;
1707         }
1708
1709         err = dprc_exit();
1710         if (err < 0) {
1711                 printf("dprc_exit() failed: %d\n", err);
1712                 goto err;
1713         }
1714
1715         return 0;
1716 err:
1717         return err;
1718 }
1719
1720 static void print_k_bytes(const void *buf, ssize_t *size)
1721 {
1722         while (*size > 0) {
1723                 int count = printf("%s", (char *)buf);
1724
1725                 buf += count;
1726                 *size -= count;
1727         }
1728 }
1729
1730 static void mc_dump_log(void)
1731 {
1732         struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
1733         u64 high = in_le64(&mc_ccsr_regs->reg_mcfbahr) & MC_FW_ADDR_MASK_HIGH;
1734         u64 low = in_le64(&mc_ccsr_regs->reg_mcfbalr) & MC_FW_ADDR_MASK_LOW;
1735         u32 buf_len, wrapped, last_byte, magic, buf_start;
1736         u64 mc_addr = (high << 32) | low;
1737         struct log_header *header;
1738         ssize_t size, bytes_end;
1739         const void *end_of_data;
1740         const void *map_addr;
1741         const void *end_addr;
1742         const void *cur_ptr;
1743         const void *buf;
1744
1745         map_addr = map_sysmem(mc_addr + MC_STRUCT_BUFFER_OFFSET,
1746                               MC_BUFFER_SIZE);
1747         header = (struct log_header *)map_addr;
1748         last_byte = in_le32(&header->last_byte);
1749         buf_len = in_le32(&header->buf_length);
1750         magic = in_le32(&header->magic_word);
1751         buf_start = in_le32(&header->buf_start);
1752         buf = map_addr + buf_start - MC_OFFSET_DELTA;
1753         end_addr = buf + buf_len;
1754         wrapped = last_byte & LOG_HEADER_FLAG_BUFFER_WRAPAROUND;
1755         end_of_data = buf + LAST_BYTE(last_byte);
1756
1757         if (magic != MAGIC_MC) {
1758                 puts("Magic number is not valid\n");
1759                 printf("expected = %08x, received = %08x\n", MAGIC_MC, magic);
1760                 goto err_magic;
1761         }
1762
1763         if (wrapped && end_of_data != end_addr)
1764                 cur_ptr = end_of_data + 1;
1765         else
1766                 cur_ptr = buf;
1767
1768         if (cur_ptr <= end_of_data)
1769                 size = end_of_data - cur_ptr;
1770         else
1771                 size = (end_addr - cur_ptr) + (end_of_data - buf);
1772
1773         bytes_end = end_addr - cur_ptr;
1774         if (size > bytes_end) {
1775                 print_k_bytes(cur_ptr, &bytes_end);
1776
1777                 size -= bytes_end;
1778         }
1779
1780         print_k_bytes(buf, &size);
1781
1782 err_magic:
1783         unmap_sysmem(map_addr);
1784 }
1785
1786 static int do_fsl_mc(struct cmd_tbl *cmdtp, int flag, int argc,
1787                      char *const argv[])
1788 {
1789         int err = 0;
1790         if (argc < 2)
1791                 goto usage;
1792
1793         switch (argv[1][0]) {
1794         case 's': {
1795                         char sub_cmd;
1796                         u64 mc_fw_addr, mc_dpc_addr;
1797 #ifdef CFG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
1798                         u64 aiop_fw_addr;
1799 #endif
1800                         if (argc < 3)
1801                                 goto usage;
1802
1803                         sub_cmd = argv[2][0];
1804
1805                         switch (sub_cmd) {
1806                         case 'm':
1807                                 if (argc < 5)
1808                                         goto usage;
1809
1810                                 if (get_mc_boot_status() == 0) {
1811                                         printf("fsl-mc: MC is already booted");
1812                                         printf("\n");
1813                                         return err;
1814                                 }
1815                                 mc_fw_addr = simple_strtoull(argv[3], NULL, 16);
1816                                 mc_dpc_addr = simple_strtoull(argv[4], NULL,
1817                                                               16);
1818
1819                                 if (!mc_init(mc_fw_addr, mc_dpc_addr))
1820                                         err = mc_init_object();
1821                                 break;
1822
1823 #ifdef CFG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET
1824                         case 'a':
1825                                 if (argc < 4)
1826                                         goto usage;
1827                                 if (get_aiop_apply_status() == 0) {
1828                                         printf("fsl-mc: AIOP FW is already");
1829                                         printf(" applied\n");
1830                                         return err;
1831                                 }
1832
1833                                 aiop_fw_addr = simple_strtoull(argv[3], NULL,
1834                                                                16);
1835
1836                                 /* if SoC doesn't have AIOP, err = -ENODEV */
1837                                 err = load_mc_aiop_img(aiop_fw_addr);
1838                                 if (!err)
1839                                         printf("fsl-mc: AIOP FW applied\n");
1840                                 break;
1841 #endif
1842                         default:
1843                                 printf("Invalid option: %s\n", argv[2]);
1844                                 goto usage;
1845
1846                                 break;
1847                         }
1848                 }
1849                 break;
1850
1851         case 'l': {
1852                 /* lazyapply */
1853                 u64 mc_dpl_addr;
1854
1855                 if (argc < 4)
1856                         goto usage;
1857
1858                 if (get_dpl_apply_status() == 0) {
1859                         printf("fsl-mc: DPL already applied\n");
1860                         return err;
1861                 }
1862
1863                 mc_dpl_addr = simple_strtoull(argv[3], NULL, 16);
1864
1865                 if (get_mc_boot_status() != 0) {
1866                         printf("fsl-mc: Deploying data path layout ..");
1867                         printf("ERROR (MC is not booted)\n");
1868                         return -ENODEV;
1869                 }
1870
1871                 /*
1872                  * We will do the actual dpaa exit and dpl apply
1873                  * later from announce_and_cleanup().
1874                  */
1875                 mc_lazy_dpl_addr = mc_dpl_addr;
1876                 break;
1877                 }
1878
1879         case 'a': {
1880                 /* apply */
1881                 char sub_cmd;
1882                 u64 mc_apply_addr;
1883
1884                 if (argc < 4)
1885                         goto usage;
1886
1887                 sub_cmd = argv[2][0];
1888
1889                 switch (sub_cmd) {
1890                 case 'd':
1891                 case 'D':
1892                         if (get_dpl_apply_status() == 0) {
1893                                 printf("fsl-mc: DPL already applied\n");
1894                                 return err;
1895                         }
1896                         if (get_mc_boot_status() != 0) {
1897                                 printf("fsl-mc: Deploying data path layout ..");
1898                                 printf("ERROR (MC is not booted)\n");
1899                                 return -ENODEV;
1900                         }
1901
1902                         mc_apply_addr = simple_strtoull(argv[3], NULL, 16);
1903
1904                         /* The user wants DPL applied now */
1905                         if (!fsl_mc_ldpaa_exit(NULL))
1906                                 err = mc_apply_dpl(mc_apply_addr);
1907                         break;
1908
1909                 case 's':
1910                         if (!is_dpsparser_supported()) {
1911                                 printf("fsl-mc: apply spb command .. ");
1912                                 printf("ERROR: requires at least MC 10.12.0\n");
1913                                 return err;
1914                         }
1915                         if (get_mc_boot_status() != 0) {
1916                                 printf("fsl-mc: Deploying Soft Parser Blob...");
1917                                 printf("ERROR (MC is not booted)\n");
1918                                 return err;
1919                         }
1920
1921                         mc_apply_addr = simple_strtoull(argv[3], NULL, 16);
1922
1923                         /* Apply spb (Soft Parser Blob) */
1924                         err = mc_apply_spb(mc_apply_addr);
1925                         break;
1926
1927                 default:
1928                         printf("Invalid option: %s\n", argv[2]);
1929                         goto usage;
1930                 }
1931                 break;
1932                 }
1933         case 'd':
1934                 if (argc > 2)
1935                         goto usage;
1936
1937                 mc_dump_log();
1938                 break;
1939         default:
1940                 printf("Invalid option: %s\n", argv[1]);
1941                 goto usage;
1942         }
1943         return err;
1944  usage:
1945         return CMD_RET_USAGE;
1946 }
1947
1948 U_BOOT_CMD(
1949         fsl_mc,  CONFIG_SYS_MAXARGS,  1,   do_fsl_mc,
1950         "DPAA2 command to manage Management Complex (MC)",
1951         "start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
1952         "fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
1953         "fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
1954         "fsl_mc apply spb [spb_addr] - Apply SPB Soft Parser Blob\n"
1955         "fsl_mc start aiop [FW_addr] - Start AIOP\n"
1956         "fsl_mc dump_log - Dump MC Log\n"
1957 );
1958
1959 void mc_env_boot(void)
1960 {
1961 #if defined(CONFIG_FSL_MC_ENET)
1962         char *mc_boot_env_var;
1963         /* The MC may only be initialized in the reset PHY function
1964          * because otherwise U-Boot has not yet set up all the MAC
1965          * address info properly. Without MAC addresses, the MC code
1966          * can not properly initialize the DPC.
1967          */
1968         mc_boot_env_var = env_get(MC_BOOT_ENV_VAR);
1969         if (mc_boot_env_var)
1970                 run_command_list(mc_boot_env_var, -1, 0);
1971 #endif /* CONFIG_FSL_MC_ENET */
1972 }