// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2015-2016 Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 */

/*
 * @file
 *  Contains all the functions to handle parsing and loading of PE firmware
 * files.
 */

#include <net/pfe_eth/pfe_eth.h>
#include <net/pfe_eth/pfe_firmware.h>

#define PFE_FIRMEWARE_FIT_CNF_NAME	"config@1"

static const void *pfe_fit_addr = (void *)CONFIG_SYS_LS_PFE_FW_ADDR;

/*
 * PFE elf firmware loader.
 * Loads an elf firmware image into a list of PE's (specified using a bitmask)
 *
 * @param pe_mask	Mask of PE id's to load firmware to
 * @param pfe_firmware	Pointer to the firmware image
 *
 * @return		0 on success, a negative value on error
 */
static int pfe_load_elf(int pe_mask, uint8_t *pfe_firmware)
{
	Elf32_Ehdr *elf_hdr = (Elf32_Ehdr *)pfe_firmware;
	Elf32_Half sections = be16_to_cpu(elf_hdr->e_shnum);
	Elf32_Shdr *shdr = (Elf32_Shdr *)(pfe_firmware +
						be32_to_cpu(elf_hdr->e_shoff));
	int id, section;
	int ret;

	debug("%s: no of sections: %d\n", __func__, sections);

	/* Some sanity checks */
	if (strncmp((char *)&elf_hdr->e_ident[EI_MAG0], ELFMAG, SELFMAG)) {
		printf("%s: incorrect elf magic number\n", __func__);
		return -1;
	}

	if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32) {
		printf("%s: incorrect elf class(%x)\n", __func__,
		       elf_hdr->e_ident[EI_CLASS]);
		return -1;
	}

	if (elf_hdr->e_ident[EI_DATA] != ELFDATA2MSB) {
		printf("%s: incorrect elf data(%x)\n", __func__,
		       elf_hdr->e_ident[EI_DATA]);
		return -1;
	}

	if (be16_to_cpu(elf_hdr->e_type) != ET_EXEC) {
		printf("%s: incorrect elf file type(%x)\n", __func__,
		       be16_to_cpu(elf_hdr->e_type));
		return -1;
	}

	for (section = 0; section < sections; section++, shdr++) {
		if (!(be32_to_cpu(shdr->sh_flags) & (SHF_WRITE | SHF_ALLOC |
			SHF_EXECINSTR)))
			continue;
		for (id = 0; id < MAX_PE; id++)
			if (pe_mask & BIT(id)) {
				ret = pe_load_elf_section(id,
							  pfe_firmware, shdr);
				if (ret < 0)
					goto err;
			}
	}
	return 0;

err:
	return ret;
}

/*
 * Get PFE firmware from FIT image
 *
 * @param data pointer to PFE firmware
 * @param size pointer to size of the firmware
 * @param fw_name pfe firmware name, either class or tmu
 *
 * @return 0 on success, a negative value on error
 */
static int pfe_get_fw(const void **data,
		      size_t *size, char *fw_name)
{
	int conf_node_off, fw_node_off;
	char *conf_node_name = NULL;
	char *desc;
	int ret = 0;

	conf_node_name = PFE_FIRMEWARE_FIT_CNF_NAME;

	conf_node_off = fit_conf_get_node(pfe_fit_addr, conf_node_name);
	if (conf_node_off < 0) {
		printf("PFE Firmware: %s: no such config\n", conf_node_name);
		return -ENOENT;
	}

	fw_node_off = fit_conf_get_prop_node(pfe_fit_addr, conf_node_off,
					     fw_name);
	if (fw_node_off < 0) {
		printf("PFE Firmware: No '%s' in config\n",
		       fw_name);
		return -ENOLINK;
	}

	if (!(fit_image_verify(pfe_fit_addr, fw_node_off))) {
		printf("PFE Firmware: Bad firmware image (bad CRC)\n");
		return -EINVAL;
	}

	if (fit_image_get_data(pfe_fit_addr, fw_node_off, data, size)) {
		printf("PFE Firmware: Can't get %s subimage data/size",
		       fw_name);
		return -ENOENT;
	}

	ret = fit_get_desc(pfe_fit_addr, fw_node_off, &desc);
	if (ret)
		printf("PFE Firmware: Can't get description\n");
	else
		printf("%s\n", desc);

	return ret;
}

/*
 * Check PFE FIT image
 *
 * @return 0 on success, a negative value on error
 */
static int pfe_fit_check(void)
{
	int ret = 0;

	ret = fdt_check_header(pfe_fit_addr);
	if (ret) {
		printf("PFE Firmware: Bad firmware image (not a FIT image)\n");
		return ret;
	}

	if (!fit_check_format(pfe_fit_addr)) {
		printf("PFE Firmware: Bad firmware image (bad FIT header)\n");
		ret = -1;
		return ret;
	}

	return ret;
}

/*
 * PFE firmware initialization.
 * Loads different firmware files from FIT image.
 * Initializes PE IMEM/DMEM and UTIL-PE DDR
 * Initializes control path symbol addresses (by looking them up in the elf
 * firmware files
 * Takes PE's out of reset
 *
 * @return 0 on success, a negative value on error
 */
int pfe_firmware_init(void)
{
	char *pfe_firmware_name;
	const void *raw_image_addr;
	size_t raw_image_size = 0;
	u8 *pfe_firmware;
	int ret = 0;
	int fw_count;

	ret = pfe_fit_check();
	if (ret)
		goto err;

	for (fw_count = 0; fw_count < 2; fw_count++) {
		if (fw_count == 0)
			pfe_firmware_name = "class";
		else if (fw_count == 1)
			pfe_firmware_name = "tmu";

		pfe_get_fw(&raw_image_addr, &raw_image_size, pfe_firmware_name);
		pfe_firmware = malloc(raw_image_size);
		if (!pfe_firmware)
			return -ENOMEM;
		memcpy((void *)pfe_firmware, (void *)raw_image_addr,
		       raw_image_size);

		if (fw_count == 0)
			ret = pfe_load_elf(CLASS_MASK, pfe_firmware);
		else if (fw_count == 1)
			ret = pfe_load_elf(TMU_MASK, pfe_firmware);

		if (ret < 0) {
			printf("%s: %s firmware load failed\n", __func__,
			       pfe_firmware_name);
			goto err;
		}
		debug("%s: %s firmware loaded\n", __func__, pfe_firmware_name);
		free(pfe_firmware);
	}

	tmu_enable(0xb);
	class_enable();
	gpi_enable(HGPI_BASE_ADDR);

err:
	return ret;
}

/*
 * PFE firmware cleanup
 * Puts PE's in reset
 */
void pfe_firmware_exit(void)
{
	debug("%s\n", __func__);

	class_disable();
	tmu_disable(0xf);
	hif_tx_disable();
	hif_rx_disable();
}
