// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2012 CERN (www.cern.ch)
 * Author: Alessandro Rubini <rubini@gnudd.com>
 *
 * This work is part of the White Rabbit project, a research effort led
 * by CERN, the European Institute for Nuclear Research.
 */
#include <linux/module.h>
#include <linux/string.h>
#include <linux/firmware.h>
#include <linux/init.h>
#include <linux/fmc.h>
#include <asm/unaligned.h>

/*
 * This module uses the firmware loader to program the whole or part
 * of the FMC eeprom. The meat is in the _run functions.  However, no
 * default file name is provided, to avoid accidental mishaps. Also,
 * you must pass the busid argument
 */
static struct fmc_driver fwe_drv;

FMC_PARAM_BUSID(fwe_drv);

/* The "file=" is like the generic "gateware=" used elsewhere */
static char *fwe_file[FMC_MAX_CARDS];
static int fwe_file_n;
module_param_array_named(file, fwe_file, charp, &fwe_file_n, 0444);

static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw,
	int write)
{
	const uint8_t *p = fw->data;
	int len = fw->size;
	uint16_t thislen, thisaddr;
	int err;

	/* format is: 'w' addr16 len16 data... */
	while (len > 5) {
		thisaddr = get_unaligned_le16(p+1);
		thislen = get_unaligned_le16(p+3);
		if (p[0] != 'w' || thislen + 5 > len) {
			dev_err(&fmc->dev, "invalid tlv at offset %ti\n",
				p - fw->data);
			return -EINVAL;
		}
		err = 0;
		if (write) {
			dev_info(&fmc->dev, "write %i bytes at 0x%04x\n",
				 thislen, thisaddr);
			err = fmc_write_ee(fmc, thisaddr, p + 5, thislen);
		}
		if (err < 0) {
			dev_err(&fmc->dev, "write failure @0x%04x\n",
				thisaddr);
			return err;
		}
		p += 5 + thislen;
		len -= 5 + thislen;
	}
	if (write)
		dev_info(&fmc->dev, "write_eeprom: success\n");
	return 0;
}

static int fwe_run_bin(struct fmc_device *fmc, const struct firmware *fw)
{
	int ret;

	dev_info(&fmc->dev, "programming %zi bytes\n", fw->size);
	ret = fmc_write_ee(fmc, 0, (void *)fw->data, fw->size);
	if (ret < 0) {
		dev_info(&fmc->dev, "write_eeprom: error %i\n", ret);
		return ret;
	}
	dev_info(&fmc->dev, "write_eeprom: success\n");
	return 0;
}

static int fwe_run(struct fmc_device *fmc, const struct firmware *fw, char *s)
{
	char *last4 = s + strlen(s) - 4;
	int err;

	if (!strcmp(last4, ".bin"))
		return fwe_run_bin(fmc, fw);
	if (!strcmp(last4, ".tlv")) {
		err = fwe_run_tlv(fmc, fw, 0);
		if (!err)
			err = fwe_run_tlv(fmc, fw, 1);
		return err;
	}
	dev_err(&fmc->dev, "invalid file name \"%s\"\n", s);
	return -EINVAL;
}

/*
 * Programming is done at probe time. Morever, only those listed with
 * busid= are programmed.
 * card is probed for, only one is programmed. Unfortunately, it's
 * difficult to know in advance when probing the first card if others
 * are there.
 */
static int fwe_probe(struct fmc_device *fmc)
{
	int err, index = 0;
	const struct firmware *fw;
	struct device *dev = &fmc->dev;
	char *s;

	if (!fwe_drv.busid_n) {
		dev_err(dev, "%s: no busid passed, refusing all cards\n",
			KBUILD_MODNAME);
		return -ENODEV;
	}

	index = fmc_validate(fmc, &fwe_drv);
	if (index < 0) {
		pr_err("%s: refusing device \"%s\"\n", KBUILD_MODNAME,
		       dev_name(dev));
		return -ENODEV;
	}
	if (index >= fwe_file_n) {
		pr_err("%s: no filename for device index %i\n",
			KBUILD_MODNAME, index);
		return -ENODEV;
	}
	s = fwe_file[index];
	if (!s) {
		pr_err("%s: no filename for \"%s\" not programming\n",
		       KBUILD_MODNAME, dev_name(dev));
		return -ENOENT;
	}
	err = request_firmware(&fw, s, dev);
	if (err < 0) {
		dev_err(&fmc->dev, "request firmware \"%s\": error %i\n",
			s, err);
		return err;
	}
	fwe_run(fmc, fw, s);
	release_firmware(fw);
	return 0;
}

static int fwe_remove(struct fmc_device *fmc)
{
	return 0;
}

static struct fmc_driver fwe_drv = {
	.version = FMC_VERSION,
	.driver.name = KBUILD_MODNAME,
	.probe = fwe_probe,
	.remove = fwe_remove,
	/* no table, as the current match just matches everything */
};

static int fwe_init(void)
{
	int ret;

	ret = fmc_driver_register(&fwe_drv);
	return ret;
}

static void fwe_exit(void)
{
	fmc_driver_unregister(&fwe_drv);
}

module_init(fwe_init);
module_exit(fwe_exit);

MODULE_LICENSE("GPL");
