diff options
author | Tom Rini <trini@konsulko.com> | 2016-02-24 14:25:54 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-02-24 18:44:15 -0500 |
commit | e1417c7b66f4e0051a3aa242f655e85c1c96eef2 (patch) | |
tree | 2ce107939d41320686cd367bbf882ed53ef6e6c9 /drivers/net | |
parent | 20434c8a0b9f6ff4a14d65fdb24c189f283412b2 (diff) | |
parent | a08b1921b4a477abe1ac4482fae9ec4bcb3cd27e (diff) | |
download | u-boot-imx-e1417c7b66f4e0051a3aa242f655e85c1c96eef2.zip u-boot-imx-e1417c7b66f4e0051a3aa242f655e85c1c96eef2.tar.gz u-boot-imx-e1417c7b66f4e0051a3aa242f655e85c1c96eef2.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/fm/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/fm/fdt.c | 129 | ||||
-rw-r--r-- | drivers/net/fm/fm.c | 2 |
3 files changed, 131 insertions, 1 deletions
diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index a3c9f99..493cdc6 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -6,6 +6,7 @@ obj-y += dtsec.o obj-y += eth.o +obj-y += fdt.o obj-y += fm.o obj-y += init.o obj-y += tgec.o diff --git a/drivers/net/fm/fdt.c b/drivers/net/fm/fdt.c new file mode 100644 index 0000000..9918d80 --- /dev/null +++ b/drivers/net/fm/fdt.c @@ -0,0 +1,129 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <asm/io.h> +#include <fsl_qe.h> /* For struct qe_firmware */ + +#ifdef CONFIG_SYS_DPAA_FMAN +/** + * fdt_fixup_fman_firmware -- insert the Fman firmware into the device tree + * + * The binding for an Fman firmware node is documented in + * Documentation/powerpc/dts-bindings/fsl/dpaa/fman.txt. This node contains + * the actual Fman firmware binary data. The operating system is expected to + * be able to parse the binary data to determine any attributes it needs. + */ +void fdt_fixup_fman_firmware(void *blob) +{ + int rc, fmnode, fwnode = -1; + uint32_t phandle; + struct qe_firmware *fmanfw; + const struct qe_header *hdr; + unsigned int length; + uint32_t crc; + const char *p; + + /* The first Fman we find will contain the actual firmware. */ + fmnode = fdt_node_offset_by_compatible(blob, -1, "fsl,fman"); + if (fmnode < 0) + /* Exit silently if there are no Fman devices */ + return; + + /* If we already have a firmware node, then also exit silently. */ + if (fdt_node_offset_by_compatible(blob, -1, "fsl,fman-firmware") > 0) + return; + + /* If the environment variable is not set, then exit silently */ + p = getenv("fman_ucode"); + if (!p) + return; + + fmanfw = (struct qe_firmware *)simple_strtoul(p, NULL, 16); + if (!fmanfw) + return; + + hdr = &fmanfw->header; + length = fdt32_to_cpu(hdr->length); + + /* Verify the firmware. */ + if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || + (hdr->magic[2] != 'F')) { + printf("Data at %p is not an Fman firmware\n", fmanfw); + return; + } + + if (length > CONFIG_SYS_QE_FMAN_FW_LENGTH) { + printf("Fman firmware at %p is too large (size=%u)\n", + fmanfw, length); + return; + } + + length -= sizeof(u32); /* Subtract the size of the CRC */ + crc = fdt32_to_cpu(*(u32 *)((void *)fmanfw + length)); + if (crc != crc32_no_comp(0, (void *)fmanfw, length)) { + printf("Fman firmware at %p has invalid CRC\n", fmanfw); + return; + } + + length += sizeof(u32); + + /* Increase the size of the fdt to make room for the node. */ + rc = fdt_increase_size(blob, length); + if (rc < 0) { + printf("Unable to make room for Fman firmware: %s\n", + fdt_strerror(rc)); + return; + } + + /* Create the firmware node. */ + fwnode = fdt_add_subnode(blob, fmnode, "fman-firmware"); + if (fwnode < 0) { + char s[64]; + fdt_get_path(blob, fmnode, s, sizeof(s)); + printf("Could not add firmware node to %s: %s\n", s, + fdt_strerror(fwnode)); + return; + } + rc = fdt_setprop_string(blob, fwnode, "compatible", + "fsl,fman-firmware"); + if (rc < 0) { + char s[64]; + fdt_get_path(blob, fwnode, s, sizeof(s)); + printf("Could not add compatible property to node %s: %s\n", s, + fdt_strerror(rc)); + return; + } + phandle = fdt_create_phandle(blob, fwnode); + if (!phandle) { + char s[64]; + fdt_get_path(blob, fwnode, s, sizeof(s)); + printf("Could not add phandle property to node %s: %s\n", s, + fdt_strerror(rc)); + return; + } + rc = fdt_setprop(blob, fwnode, "fsl,firmware", fmanfw, length); + if (rc < 0) { + char s[64]; + fdt_get_path(blob, fwnode, s, sizeof(s)); + printf("Could not add firmware property to node %s: %s\n", s, + fdt_strerror(rc)); + return; + } + + /* Find all other Fman nodes and point them to the firmware node. */ + while ((fmnode = fdt_node_offset_by_compatible(blob, fmnode, + "fsl,fman")) > 0) { + rc = fdt_setprop_cell(blob, fmnode, "fsl,firmware-phandle", + phandle); + if (rc < 0) { + char s[64]; + fdt_get_path(blob, fmnode, s, sizeof(s)); + printf("Could not add pointer property to node %s: %s\n", + s, fdt_strerror(rc)); + return; + } + } +} +#endif diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index 40fbf19..e2a8ed3 100644 --- a/drivers/net/fm/fm.c +++ b/drivers/net/fm/fm.c @@ -10,7 +10,7 @@ #include <asm/errno.h> #include "fm.h" -#include "../../qe/qe.h" /* For struct qe_firmware */ +#include <fsl_qe.h> /* For struct qe_firmware */ #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND #include <nand.h> |