/****************************************************************************
 * Driver for Solarflare Solarstorm network controllers and boards
 * Copyright 2005-2006 Fen Systems Ltd.
 * Copyright 2006-2009 Solarflare Communications Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation, incorporated herein by reference.
 */

#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>

#define EFX_DRIVER_NAME "sfc_mtd"
#include "net_driver.h"
#include "spi.h"
#include "efx.h"
#include "nic.h"
#include "mcdi.h"
#include "mcdi_pcol.h"

#define EFX_SPI_VERIFY_BUF_LEN 16

struct efx_mtd_partition {
	struct mtd_info mtd;
	union {
		struct {
			bool updating;
			u8 nvram_type;
			u16 fw_subtype;
		} mcdi;
		size_t offset;
	};
	const char *type_name;
	char name[IFNAMSIZ + 20];
};

struct efx_mtd_ops {
	int (*read)(struct mtd_info *mtd, loff_t start, size_t len,
		    size_t *retlen, u8 *buffer);
	int (*erase)(struct mtd_info *mtd, loff_t start, size_t len);
	int (*write)(struct mtd_info *mtd, loff_t start, size_t len,
		     size_t *retlen, const u8 *buffer);
	int (*sync)(struct mtd_info *mtd);
};

struct efx_mtd {
	struct list_head node;
	struct efx_nic *efx;
	const struct efx_spi_device *spi;
	const char *name;
	const struct efx_mtd_ops *ops;
	size_t n_parts;
	struct efx_mtd_partition part[0];
};

#define efx_for_each_partition(part, efx_mtd)			\
	for ((part) = &(efx_mtd)->part[0];			\
	     (part) != &(efx_mtd)->part[(efx_mtd)->n_parts];	\
	     (part)++)

#define to_efx_mtd_partition(mtd)				\
	container_of(mtd, struct efx_mtd_partition, mtd)

static int falcon_mtd_probe(struct efx_nic *efx);
static int siena_mtd_probe(struct efx_nic *efx);

/* SPI utilities */

static int efx_spi_slow_wait(struct efx_mtd *efx_mtd, bool uninterruptible)
{
	const struct efx_spi_device *spi = efx_mtd->spi;
	struct efx_nic *efx = efx_mtd->efx;
	u8 status;
	int rc, i;

	/* Wait up to 4s for flash/EEPROM to finish a slow operation. */
	for (i = 0; i < 40; i++) {
		__set_current_state(uninterruptible ?
				    TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
		schedule_timeout(HZ / 10);
		rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
				    &status, sizeof(status));
		if (rc)
			return rc;
		if (!(status & SPI_STATUS_NRDY))
			return 0;
		if (signal_pending(current))
			return -EINTR;
	}
	EFX_ERR(efx, "timed out waiting for %s\n", efx_mtd->name);
	return -ETIMEDOUT;
}

static int
efx_spi_unlock(struct efx_nic *efx, const struct efx_spi_device *spi)
{
	const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 |
				SPI_STATUS_BP0);
	u8 status;
	int rc;

	rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
			    &status, sizeof(status));
	if (rc)
		return rc;

	if (!(status & unlock_mask))
		return 0; /* already unlocked */

	rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
	if (rc)
		return rc;
	rc = falcon_spi_cmd(efx, spi, SPI_SST_EWSR, -1, NULL, NULL, 0);
	if (rc)
		return rc;

	status &= ~unlock_mask;
	rc = falcon_spi_cmd(efx, spi, SPI_WRSR, -1, &status,
			    NULL, sizeof(status));
	if (rc)
		return rc;
	rc = falcon_spi_wait_write(efx, spi);
	if (rc)
		return rc;

	return 0;
}

static int efx_spi_erase(struct efx_mtd *efx_mtd, loff_t start, size_t len)
{
	const struct efx_spi_device *spi = efx_mtd->spi;
	struct efx_nic *efx = efx_mtd->efx;
	unsigned pos, block_len;
	u8 empty[EFX_SPI_VERIFY_BUF_LEN];
	u8 buffer[EFX_SPI_VERIFY_BUF_LEN];
	int rc;

	if (len != spi->erase_size)
		return -EINVAL;

	if (spi->erase_command == 0)
		return -EOPNOTSUPP;

	rc = efx_spi_unlock(efx, spi);
	if (rc)
		return rc;
	rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
	if (rc)
		return rc;
	rc = falcon_spi_cmd(efx, spi, spi->erase_command, start, NULL,
			    NULL, 0);
	if (rc)
		return rc;
	rc = efx_spi_slow_wait(efx_mtd, false);

	/* Verify the entire region has been wiped */
	memset(empty, 0xff, sizeof(empty));
	for (pos = 0; pos < len; pos += block_len) {
		block_len = min(len - pos, sizeof(buffer));
		rc = falcon_spi_read(efx, spi, start + pos, block_len,
				     NULL, buffer);
		if (rc)
			return rc;
		if (memcmp(empty, buffer, block_len))
			return -EIO;

		/* Avoid locking up the system */
		cond_resched();
		if (signal_pending(current))
			return -EINTR;
	}

	return rc;
}

/* MTD interface */

static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
{
	struct efx_mtd *efx_mtd = mtd->priv;
	int rc;

	rc = efx_mtd->ops->erase(mtd, erase->addr, erase->len);
	if (rc == 0) {
		erase->state = MTD_ERASE_DONE;
	} else {
		erase->state = MTD_ERASE_FAILED;
		erase->fail_addr = 0xffffffff;
	}
	mtd_erase_callback(erase);
	return rc;
}

static void efx_mtd_sync(struct mtd_info *mtd)
{
	struct efx_mtd *efx_mtd = mtd->priv;
	struct efx_nic *efx = efx_mtd->efx;
	int rc;

	rc = efx_mtd->ops->sync(mtd);
	if (rc)
		EFX_ERR(efx, "%s sync failed (%d)\n", efx_mtd->name, rc);
}

static void efx_mtd_remove_partition(struct efx_mtd_partition *part)
{
	int rc;

	for (;;) {
		rc = del_mtd_device(&part->mtd);
		if (rc != -EBUSY)
			break;
		ssleep(1);
	}
	WARN_ON(rc);
}

static void efx_mtd_remove_device(struct efx_mtd *efx_mtd)
{
	struct efx_mtd_partition *part;

	efx_for_each_partition(part, efx_mtd)
		efx_mtd_remove_partition(part);
	list_del(&efx_mtd->node);
	kfree(efx_mtd);
}

static void efx_mtd_rename_device(struct efx_mtd *efx_mtd)
{
	struct efx_mtd_partition *part;

	efx_for_each_partition(part, efx_mtd)
		if (efx_nic_rev(efx_mtd->efx) >= EFX_REV_SIENA_A0)
			snprintf(part->name, sizeof(part->name),
				 "%s %s:%02x", efx_mtd->efx->name,
				 part->type_name, part->mcdi.fw_subtype);
		else
			snprintf(part->name, sizeof(part->name),
				 "%s %s", efx_mtd->efx->name,
				 part->type_name);
}

static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd)
{
	struct efx_mtd_partition *part;

	efx_mtd->efx = efx;

	efx_mtd_rename_device(efx_mtd);

	efx_for_each_partition(part, efx_mtd) {
		part->mtd.writesize = 1;

		part->mtd.owner = THIS_MODULE;
		part->mtd.priv = efx_mtd;
		part->mtd.name = part->name;
		part->mtd.erase = efx_mtd_erase;
		part->mtd.read = efx_mtd->ops->read;
		part->mtd.write = efx_mtd->ops->write;
		part->mtd.sync = efx_mtd_sync;

		if (add_mtd_device(&part->mtd))
			goto fail;
	}

	list_add(&efx_mtd->node, &efx->mtd_list);
	return 0;

fail:
	while (part != &efx_mtd->part[0]) {
		--part;
		efx_mtd_remove_partition(part);
	}
	/* add_mtd_device() returns 1 if the MTD table is full */
	return -ENOMEM;
}

void efx_mtd_remove(struct efx_nic *efx)
{
	struct efx_mtd *efx_mtd, *next;

	WARN_ON(efx_dev_registered(efx));

	list_for_each_entry_safe(efx_mtd, next, &efx->mtd_list, node)
		efx_mtd_remove_device(efx_mtd);
}

void efx_mtd_rename(struct efx_nic *efx)
{
	struct efx_mtd *efx_mtd;

	ASSERT_RTNL();

	list_for_each_entry(efx_mtd, &efx->mtd_list, node)
		efx_mtd_rename_device(efx_mtd);
}

int efx_mtd_probe(struct efx_nic *efx)
{
	if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0)
		return siena_mtd_probe(efx);
	else
		return falcon_mtd_probe(efx);
}

/* Implementation of MTD operations for Falcon */

static int falcon_mtd_read(struct mtd_info *mtd, loff_t start,
			   size_t len, size_t *retlen, u8 *buffer)
{
	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
	struct efx_mtd *efx_mtd = mtd->priv;
	const struct efx_spi_device *spi = efx_mtd->spi;
	struct efx_nic *efx = efx_mtd->efx;
	int rc;

	rc = mutex_lock_interruptible(&efx->spi_lock);
	if (rc)
		return rc;
	rc = falcon_spi_read(efx, spi, part->offset + start, len,
			     retlen, buffer);
	mutex_unlock(&efx->spi_lock);
	return rc;
}

static int falcon_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
{
	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
	struct efx_mtd *efx_mtd = mtd->priv;
	struct efx_nic *efx = efx_mtd->efx;
	int rc;

	rc = mutex_lock_interruptible(&efx->spi_lock);
	if (rc)
		return rc;
	rc = efx_spi_erase(efx_mtd, part->offset + start, len);
	mutex_unlock(&efx->spi_lock);
	return rc;
}

static int falcon_mtd_write(struct mtd_info *mtd, loff_t start,
			    size_t len, size_t *retlen, const u8 *buffer)
{
	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
	struct efx_mtd *efx_mtd = mtd->priv;
	const struct efx_spi_device *spi = efx_mtd->spi;
	struct efx_nic *efx = efx_mtd->efx;
	int rc;

	rc = mutex_lock_interruptible(&efx->spi_lock);
	if (rc)
		return rc;
	rc = falcon_spi_write(efx, spi, part->offset + start, len,
			      retlen, buffer);
	mutex_unlock(&efx->spi_lock);
	return rc;
}

static int falcon_mtd_sync(struct mtd_info *mtd)
{
	struct efx_mtd *efx_mtd = mtd->priv;
	struct efx_nic *efx = efx_mtd->efx;
	int rc;

	mutex_lock(&efx->spi_lock);
	rc = efx_spi_slow_wait(efx_mtd, true);
	mutex_unlock(&efx->spi_lock);
	return rc;
}

static struct efx_mtd_ops falcon_mtd_ops = {
	.read	= falcon_mtd_read,
	.erase	= falcon_mtd_erase,
	.write	= falcon_mtd_write,
	.sync	= falcon_mtd_sync,
};

static int falcon_mtd_probe(struct efx_nic *efx)
{
	struct efx_spi_device *spi = efx->spi_flash;
	struct efx_mtd *efx_mtd;
	int rc;

	ASSERT_RTNL();

	if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START)
		return -ENODEV;

	efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]),
			  GFP_KERNEL);
	if (!efx_mtd)
		return -ENOMEM;

	efx_mtd->spi = spi;
	efx_mtd->name = "flash";
	efx_mtd->ops = &falcon_mtd_ops;

	efx_mtd->n_parts = 1;
	efx_mtd->part[0].mtd.type = MTD_NORFLASH;
	efx_mtd->part[0].mtd.flags = MTD_CAP_NORFLASH;
	efx_mtd->part[0].mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
	efx_mtd->part[0].mtd.erasesize = spi->erase_size;
	efx_mtd->part[0].offset = FALCON_FLASH_BOOTCODE_START;
	efx_mtd->part[0].type_name = "sfc_flash_bootrom";

	rc = efx_mtd_probe_device(efx, efx_mtd);
	if (rc)
		kfree(efx_mtd);
	return rc;
}

/* Implementation of MTD operations for Siena */

static int siena_mtd_read(struct mtd_info *mtd, loff_t start,
			  size_t len, size_t *retlen, u8 *buffer)
{
	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
	struct efx_mtd *efx_mtd = mtd->priv;
	struct efx_nic *efx = efx_mtd->efx;
	loff_t offset = start;
	loff_t end = min_t(loff_t, start + len, mtd->size);
	size_t chunk;
	int rc = 0;

	while (offset < end) {
		chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
		rc = efx_mcdi_nvram_read(efx, part->mcdi.nvram_type, offset,
					 buffer, chunk);
		if (rc)
			goto out;
		offset += chunk;
		buffer += chunk;
	}
out:
	*retlen = offset - start;
	return rc;
}

static int siena_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
{
	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
	struct efx_mtd *efx_mtd = mtd->priv;
	struct efx_nic *efx = efx_mtd->efx;
	loff_t offset = start & ~((loff_t)(mtd->erasesize - 1));
	loff_t end = min_t(loff_t, start + len, mtd->size);
	size_t chunk = part->mtd.erasesize;
	int rc = 0;

	if (!part->mcdi.updating) {
		rc = efx_mcdi_nvram_update_start(efx, part->mcdi.nvram_type);
		if (rc)
			goto out;
		part->mcdi.updating = 1;
	}

	/* The MCDI interface can in fact do multiple erase blocks at once;
	 * but erasing may be slow, so we make multiple calls here to avoid
	 * tripping the MCDI RPC timeout. */
	while (offset < end) {
		rc = efx_mcdi_nvram_erase(efx, part->mcdi.nvram_type, offset,
					  chunk);
		if (rc)
			goto out;
		offset += chunk;
	}
out:
	return rc;
}

static int siena_mtd_write(struct mtd_info *mtd, loff_t start,
			   size_t len, size_t *retlen, const u8 *buffer)
{
	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
	struct efx_mtd *efx_mtd = mtd->priv;
	struct efx_nic *efx = efx_mtd->efx;
	loff_t offset = start;
	loff_t end = min_t(loff_t, start + len, mtd->size);
	size_t chunk;
	int rc = 0;

	if (!part->mcdi.updating) {
		rc = efx_mcdi_nvram_update_start(efx, part->mcdi.nvram_type);
		if (rc)
			goto out;
		part->mcdi.updating = 1;
	}

	while (offset < end) {
		chunk = min_t(size_t, end - offset, EFX_MCDI_NVRAM_LEN_MAX);
		rc = efx_mcdi_nvram_write(efx, part->mcdi.nvram_type, offset,
					  buffer, chunk);
		if (rc)
			goto out;
		offset += chunk;
		buffer += chunk;
	}
out:
	*retlen = offset - start;
	return rc;
}

static int siena_mtd_sync(struct mtd_info *mtd)
{
	struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
	struct efx_mtd *efx_mtd = mtd->priv;
	struct efx_nic *efx = efx_mtd->efx;
	int rc = 0;

	if (part->mcdi.updating) {
		part->mcdi.updating = 0;
		rc = efx_mcdi_nvram_update_finish(efx, part->mcdi.nvram_type);
	}

	return rc;
}

static struct efx_mtd_ops siena_mtd_ops = {
	.read	= siena_mtd_read,
	.erase	= siena_mtd_erase,
	.write	= siena_mtd_write,
	.sync	= siena_mtd_sync,
};

struct siena_nvram_type_info {
	int port;
	const char *name;
};

static struct siena_nvram_type_info siena_nvram_types[] = {
	[MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO]	= { 0, "sfc_dummy_phy" },
	[MC_CMD_NVRAM_TYPE_MC_FW]		= { 0, "sfc_mcfw" },
	[MC_CMD_NVRAM_TYPE_MC_FW_BACKUP]	= { 0, "sfc_mcfw_backup" },
	[MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0]	= { 0, "sfc_static_cfg" },
	[MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1]	= { 1, "sfc_static_cfg" },
	[MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0]	= { 0, "sfc_dynamic_cfg" },
	[MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1]	= { 1, "sfc_dynamic_cfg" },
	[MC_CMD_NVRAM_TYPE_EXP_ROM]		= { 0, "sfc_exp_rom" },
	[MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0]	= { 0, "sfc_exp_rom_cfg" },
	[MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1]	= { 1, "sfc_exp_rom_cfg" },
	[MC_CMD_NVRAM_TYPE_PHY_PORT0]		= { 0, "sfc_phy_fw" },
	[MC_CMD_NVRAM_TYPE_PHY_PORT1]		= { 1, "sfc_phy_fw" },
};

static int siena_mtd_probe_partition(struct efx_nic *efx,
				     struct efx_mtd *efx_mtd,
				     unsigned int part_id,
				     unsigned int type)
{
	struct efx_mtd_partition *part = &efx_mtd->part[part_id];
	struct siena_nvram_type_info *info;
	size_t size, erase_size;
	bool protected;
	int rc;

	if (type >= ARRAY_SIZE(siena_nvram_types))
		return -ENODEV;

	info = &siena_nvram_types[type];

	if (info->port != efx_port_num(efx))
		return -ENODEV;

	rc = efx_mcdi_nvram_info(efx, type, &size, &erase_size, &protected);
	if (rc)
		return rc;
	if (protected)
		return -ENODEV; /* hide it */

	part->mcdi.nvram_type = type;
	part->type_name = info->name;

	part->mtd.type = MTD_NORFLASH;
	part->mtd.flags = MTD_CAP_NORFLASH;
	part->mtd.size = size;
	part->mtd.erasesize = erase_size;

	return 0;
}

static int siena_mtd_get_fw_subtypes(struct efx_nic *efx,
				     struct efx_mtd *efx_mtd)
{
	struct efx_mtd_partition *part;
	uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN /
				 sizeof(uint16_t)];
	int rc;

	rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list);
	if (rc)
		return rc;

	efx_for_each_partition(part, efx_mtd)
		part->mcdi.fw_subtype = fw_subtype_list[part->mcdi.nvram_type];

	return 0;
}

static int siena_mtd_probe(struct efx_nic *efx)
{
	struct efx_mtd *efx_mtd;
	int rc = -ENODEV;
	u32 nvram_types;
	unsigned int type;

	ASSERT_RTNL();

	rc = efx_mcdi_nvram_types(efx, &nvram_types);
	if (rc)
		return rc;

	efx_mtd = kzalloc(sizeof(*efx_mtd) +
			  hweight32(nvram_types) * sizeof(efx_mtd->part[0]),
			  GFP_KERNEL);
	if (!efx_mtd)
		return -ENOMEM;

	efx_mtd->name = "Siena NVRAM manager";

	efx_mtd->ops = &siena_mtd_ops;

	type = 0;
	efx_mtd->n_parts = 0;

	while (nvram_types != 0) {
		if (nvram_types & 1) {
			rc = siena_mtd_probe_partition(efx, efx_mtd,
						       efx_mtd->n_parts, type);
			if (rc == 0)
				efx_mtd->n_parts++;
			else if (rc != -ENODEV)
				goto fail;
		}
		type++;
		nvram_types >>= 1;
	}

	rc = siena_mtd_get_fw_subtypes(efx, efx_mtd);
	if (rc)
		goto fail;

	rc = efx_mtd_probe_device(efx, efx_mtd);
fail:
	if (rc)
		kfree(efx_mtd);
	return rc;
}

