/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2013 Ricardo Ribalda - Qtechnology A/S
 * Copyright (C) 2011, 2014 Stefan Tauner
 *
 * Based on nicinctel_spi.c and ichspi.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * Datasheet: Intel 82580 Quad/Dual Gigabit Ethernet LAN Controller Datasheet
 * 3.3.1.4: General EEPROM Software Access
 * 4.7: Access to shared resources (FIXME: we should probably use this semaphore interface)
 * 7.4: Register Descriptions
 */
/*
 * Datasheet: Intel Ethernet Controller I210: Datasheet
 * 8.4.3: EEPROM-Mode Read Register
 * 8.4.6: EEPROM-Mode Write Register
 * Write process inspired on kernel e1000_i210.c
 */

#include <stdlib.h>
#include <unistd.h>
#include "flash.h"
#include "spi.h"
#include "programmer.h"
#include "hwaccess.h"

#define PCI_VENDOR_ID_INTEL 0x8086
#define MEMMAP_SIZE 0x1c /* Only EEC, EERD and EEWR are needed. */

#define EEC	0x10 /* EEPROM/Flash Control Register */
#define EERD	0x14 /* EEPROM Read Register */
#define EEWR	0x18 /* EEPROM Write Register */

/* EPROM/Flash Control Register bits */
#define EE_SCK	0
#define EE_CS	1
#define EE_SI	2
#define EE_SO	3
#define EE_REQ	6
#define EE_GNT	7
#define EE_PRES	8
#define EE_SIZE 11
#define EE_SIZE_MASK 0xf
#define EE_FLUPD   23
#define EE_FLUDONE 26

/* EEPROM Read Register bits */
#define EERD_START 0
#define EERD_DONE 1
#define EERD_ADDR 2
#define EERD_DATA 16

/* EEPROM Write Register bits */
#define EEWR_CMDV 0
#define EEWR_DONE 1
#define EEWR_ADDR 2
#define EEWR_DATA 16

#define BIT(x) (1<<x)
#define EE_PAGE_MASK 0x3f

static uint8_t *nicintel_eebar;
static struct pci_dev *nicintel_pci;
static bool done_i20_write = false;

#define UNPROG_DEVICE 0x1509

/*
 * Warning: is_i210() below makes assumptions on these PCI ids.
 *          It may have to be updated when this list is extended.
 */
static const struct dev_entry nics_intel_ee[] = {
	{PCI_VENDOR_ID_INTEL, 0x150e, OK, "Intel", "82580 Quad Gigabit Ethernet Controller (Copper)"},
	{PCI_VENDOR_ID_INTEL, 0x150f, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Fiber)"},
	{PCI_VENDOR_ID_INTEL, 0x1510, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Backplane)"},
	{PCI_VENDOR_ID_INTEL, 0x1511, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Ext. PHY)"},
	{PCI_VENDOR_ID_INTEL, 0x1511, NT , "Intel", "82580 Dual Gigabit Ethernet Controller (Copper)"},
	{PCI_VENDOR_ID_INTEL, UNPROG_DEVICE, OK, "Intel", "Unprogrammed 82580 Quad/Dual Gigabit Ethernet Controller"},
	{PCI_VENDOR_ID_INTEL, 0x1531, OK, "Intel", "I210 Gigabit Network Connection Unprogrammed"},
	{PCI_VENDOR_ID_INTEL, 0x1532, NT, "Intel", "I211 Gigabit Network Connection Unprogrammed"},
	{PCI_VENDOR_ID_INTEL, 0x1533, OK, "Intel", "I210 Gigabit Network Connection"},
	{PCI_VENDOR_ID_INTEL, 0x1536, NT, "Intel", "I210 Gigabit Network Connection SERDES Fiber"},
	{PCI_VENDOR_ID_INTEL, 0x1537, NT, "Intel", "I210 Gigabit Network Connection SERDES Backplane"},
	{PCI_VENDOR_ID_INTEL, 0x1538, NT, "Intel", "I210 Gigabit Network Connection SGMII"},
	{PCI_VENDOR_ID_INTEL, 0x1539, NT, "Intel", "I211 Gigabit Network Connection"},
	{0},
};

static inline bool is_i210(uint16_t device_id)
{
	return (device_id & 0xfff0) == 0x1530;
}

static int nicintel_ee_probe_i210(struct flashctx *flash)
{
	/* Emulated eeprom has a fixed size of 4 KB */
	flash->chip->total_size = 4;
	flash->chip->page_size = flash->chip->total_size * 1024;
	flash->chip->tested = TEST_OK_PREW;
	flash->chip->gran = write_gran_1byte_implicit_erase;
	flash->chip->block_erasers->eraseblocks[0].size = flash->chip->page_size;
	flash->chip->block_erasers->eraseblocks[0].count = 1;

	return 1;
}

static int nicintel_ee_probe_82580(struct flashctx *flash)
{
	if (nicintel_pci->device_id == UNPROG_DEVICE)
		flash->chip->total_size = 16; /* Fall back to minimum supported size. */
	else {
		uint32_t tmp = pci_mmio_readl(nicintel_eebar + EEC);
		tmp = ((tmp >> EE_SIZE) & EE_SIZE_MASK);
		switch (tmp) {
		case 7:
			flash->chip->total_size = 16;
			break;
		case 8:
			flash->chip->total_size = 32;
			break;
		default:
			msg_cerr("Unsupported chip size 0x%x\n", tmp);
			return 0;
		}
	}

	flash->chip->page_size = EE_PAGE_MASK + 1;
	flash->chip->tested = TEST_OK_PREW;
	flash->chip->gran = write_gran_1byte_implicit_erase;
	flash->chip->block_erasers->eraseblocks[0].size = (EE_PAGE_MASK + 1);
	flash->chip->block_erasers->eraseblocks[0].count = (flash->chip->total_size * 1024) / (EE_PAGE_MASK + 1);

	return 1;
}

#define MAX_ATTEMPTS 10000000
static int nicintel_ee_read_word(unsigned int addr, uint16_t *data)
{
	uint32_t tmp = BIT(EERD_START) | (addr << EERD_ADDR);
	pci_mmio_writel(tmp, nicintel_eebar + EERD);

	/* Poll done flag. 10.000.000 cycles seem to be enough. */
	uint32_t i;
	for (i = 0; i < MAX_ATTEMPTS; i++) {
		tmp = pci_mmio_readl(nicintel_eebar + EERD);
		if (tmp & BIT(EERD_DONE)) {
			*data = (tmp >> EERD_DATA) & 0xffff;
			return 0;
		}
	}

	return -1;
}

static int nicintel_ee_read(struct flashctx *flash, uint8_t *buf, unsigned int addr, unsigned int len)
{
	uint16_t data;

	/* The NIC interface always reads 16 b words so we need to convert the address and handle odd address
	 * explicitly at the start (and also at the end in the loop below). */
	if (addr & 1) {
		if (nicintel_ee_read_word(addr / 2, &data))
			return -1;
		*buf++ = data & 0xff;
		addr++;
		len--;
	}

	while (len > 0) {
		if (nicintel_ee_read_word(addr / 2, &data))
			return -1;
		*buf++ = data & 0xff;
		addr++;
		len--;
		if (len > 0) {
			*buf++ = (data >> 8) & 0xff;
			addr++;
			len--;
		}
	}

	return 0;
}

static int nicintel_ee_write_word_i210(unsigned int addr, uint16_t data)
{
	uint32_t eewr;

	eewr = addr << EEWR_ADDR;
	eewr |= data << EEWR_DATA;
	eewr |= BIT(EEWR_CMDV);
	pci_mmio_writel(eewr, nicintel_eebar + EEWR);

	programmer_delay(5);
	int i;
	for (i = 0; i < MAX_ATTEMPTS; i++)
		if (pci_mmio_readl(nicintel_eebar + EEWR) & BIT(EEWR_DONE))
			return 0;
	return -1;
}

static int nicintel_ee_write_i210(struct flashctx *flash, const uint8_t *buf,
				  unsigned int addr, unsigned int len)
{
	done_i20_write = true;

	if (addr & 1) {
		uint16_t data;

		if (nicintel_ee_read_word(addr / 2, &data)) {
			msg_perr("Timeout reading heading byte\n");
			return -1;
		}

		data &= 0xff;
		data |= (buf ? (buf[0]) : 0xff) << 8;

		if (nicintel_ee_write_word_i210(addr / 2, data)) {
			msg_perr("Timeout writing heading word\n");
			return -1;
		}

		if (buf)
			buf ++;
		addr ++;
		len --;
	}

	while (len > 0) {
		uint16_t data;

		if (len == 1) {
			if (nicintel_ee_read_word(addr / 2, &data)) {
				msg_perr("Timeout reading tail byte\n");
				return -1;
			}

			data &= 0xff00;
			data |= buf ? (buf[0]) : 0xff;
		} else {
			if (buf)
				data = buf[0] | (buf[1] << 8);
			else
				data = 0xffff;
		}

		if (nicintel_ee_write_word_i210(addr / 2, data)) {
			msg_perr("Timeout writing Shadow RAM\n");
			return -1;
		}

		if (buf)
			buf += 2;
		if (len > 2)
			len -= 2;
		else
			len = 0;
		addr += 2;
	}

	return 0;
}

static int nicintel_ee_erase_i210(struct flashctx *flash, unsigned int addr, unsigned int len)
{
	return nicintel_ee_write_i210(flash, NULL, addr, len);
}

static int nicintel_ee_bitset(int reg, int bit, bool val)
{
	uint32_t tmp;

	tmp = pci_mmio_readl(nicintel_eebar + reg);
	if (val)
		tmp |= BIT(bit);
	else
		tmp &= ~BIT(bit);
	pci_mmio_writel(tmp, nicintel_eebar + reg);

	return -1;
}

/* Shifts one byte out while receiving another one by bitbanging (denoted "direct access" in the datasheet). */
static int nicintel_ee_bitbang(uint8_t mosi, uint8_t *miso)
{
	uint8_t out = 0x0;

	int i;
	for (i = 7; i >= 0; i--) {
		nicintel_ee_bitset(EEC, EE_SI, mosi & BIT(i));
		nicintel_ee_bitset(EEC, EE_SCK, 1);
		if (miso != NULL) {
			uint32_t tmp = pci_mmio_readl(nicintel_eebar + EEC);
			if (tmp & BIT(EE_SO))
				out |= BIT(i);
		}
		nicintel_ee_bitset(EEC, EE_SCK, 0);
	}

	if (miso != NULL)
		*miso = out;

	return 0;
}

/* Polls the WIP bit of the status register of the attached EEPROM via bitbanging. */
static int nicintel_ee_ready(void)
{
	unsigned int i;
	for (i = 0; i < 1000; i++) {
		nicintel_ee_bitset(EEC, EE_CS, 0);

		nicintel_ee_bitbang(JEDEC_RDSR, NULL);
		uint8_t rdsr;
		nicintel_ee_bitbang(0x00, &rdsr);

		nicintel_ee_bitset(EEC, EE_CS, 1);
		programmer_delay(1);
		if (!(rdsr & SPI_SR_WIP)) {
			return 0;
		}
	}
	return -1;
}

/* Requests direct access to the SPI pins. */
static int nicintel_ee_req(void)
{
	uint32_t tmp;
	nicintel_ee_bitset(EEC, EE_REQ, 1);

	tmp = pci_mmio_readl(nicintel_eebar + EEC);
	if (!(tmp & BIT(EE_GNT))) {
		msg_perr("Enabling eeprom access failed.\n");
		return 1;
	}

	nicintel_ee_bitset(EEC, EE_SCK, 0);
	return 0;
}

static int nicintel_ee_write_82580(struct flashctx *flash, const uint8_t *buf, unsigned int addr, unsigned int len)
{
	if (nicintel_ee_req())
		return -1;

	int ret = -1;
	if (nicintel_ee_ready())
		goto out;

	while (len > 0) {
		/* WREN */
		nicintel_ee_bitset(EEC, EE_CS, 0);
		nicintel_ee_bitbang(JEDEC_WREN, NULL);
		nicintel_ee_bitset(EEC, EE_CS, 1);
		programmer_delay(1);

		/* data */
		nicintel_ee_bitset(EEC, EE_CS, 0);
		nicintel_ee_bitbang(JEDEC_BYTE_PROGRAM, NULL);
		nicintel_ee_bitbang((addr >> 8) & 0xff, NULL);
		nicintel_ee_bitbang(addr & 0xff, NULL);
		while (len > 0) {
			nicintel_ee_bitbang((buf) ? *buf++ : 0xff, NULL);
			len--;
			addr++;
			if (!(addr & EE_PAGE_MASK))
				break;
		}
		nicintel_ee_bitset(EEC, EE_CS, 1);
		programmer_delay(1);
		if (nicintel_ee_ready())
			goto out;
	}
	ret = 0;
out:
	nicintel_ee_bitset(EEC, EE_REQ, 0); /* Give up direct access. */
	return ret;
}

static int nicintel_ee_erase_82580(struct flashctx *flash, unsigned int addr, unsigned int len)
{
	return nicintel_ee_write_82580(flash, NULL, addr, len);
}

static const struct opaque_master opaque_master_nicintel_ee_82580 = {
	.probe		= nicintel_ee_probe_82580,
	.read		= nicintel_ee_read,
	.write		= nicintel_ee_write_82580,
	.erase		= nicintel_ee_erase_82580,
};

static const struct opaque_master opaque_master_nicintel_ee_i210 = {
	.probe		= nicintel_ee_probe_i210,
	.read		= nicintel_ee_read,
	.write		= nicintel_ee_write_i210,
	.erase		= nicintel_ee_erase_i210,
};

static int nicintel_ee_shutdown_i210(void *arg)
{
	int ret = 0;

	if (!done_i20_write)
		goto out;

	uint32_t flup = pci_mmio_readl(nicintel_eebar + EEC);

	flup |= BIT(EE_FLUPD);
	pci_mmio_writel(flup, nicintel_eebar + EEC);

	int i;
	for (i = 0; i < MAX_ATTEMPTS; i++)
		if (pci_mmio_readl(nicintel_eebar + EEC) & BIT(EE_FLUDONE))
			goto out;

	ret = -1;
	msg_perr("Flash update failed\n");

out:
	return ret;
}

static int nicintel_ee_shutdown_82580(void *eecp)
{
	uint32_t old_eec = *(uint32_t *)eecp;
	/* Request bitbanging and unselect the chip first to be safe. */
	if (nicintel_ee_req() || nicintel_ee_bitset(EEC, EE_CS, 1))
		return -1;

	/* Try to restore individual bits we care about. */
	int ret = nicintel_ee_bitset(EEC, EE_SCK, old_eec & BIT(EE_SCK));
	ret |= nicintel_ee_bitset(EEC, EE_SI, old_eec & BIT(EE_SI));
	ret |= nicintel_ee_bitset(EEC, EE_CS, old_eec & BIT(EE_CS));
	/* REQ will be cleared by hardware anyway after 2 seconds of inactivity on the SPI pins (3.3.2.1). */
	ret |= nicintel_ee_bitset(EEC, EE_REQ, old_eec & BIT(EE_REQ));

	free(eecp);
	return ret;
}

static int nicintel_ee_init(void)
{
	if (rget_io_perms())
		return 1;

	struct pci_dev *dev = pcidev_init(nics_intel_ee, PCI_BASE_ADDRESS_0);
	if (!dev)
		return 1;

	uint32_t io_base_addr = pcidev_readbar(dev, PCI_BASE_ADDRESS_0);
	if (!io_base_addr)
		return 1;

	if (!is_i210(dev->device_id)) {
		nicintel_eebar = rphysmap("Intel Gigabit NIC w/ SPI EEPROM", io_base_addr, MEMMAP_SIZE);
		if (!nicintel_eebar)
			return 1;

		nicintel_pci = dev;
		if (dev->device_id != UNPROG_DEVICE) {
			uint32_t eec = pci_mmio_readl(nicintel_eebar + EEC);

			/* C.f. 3.3.1.5 for the detection mechanism (maybe? contradicting
			                the EE_PRES definition),
			    and 3.3.1.7 for possible recovery. */
			if (!(eec & BIT(EE_PRES))) {
				msg_perr("Controller reports no EEPROM is present.\n");
				return 1;
			}

			uint32_t *eecp = malloc(sizeof(uint32_t));
			if (eecp == NULL)
				return 1;
			*eecp = eec;

			if (register_shutdown(nicintel_ee_shutdown_82580, eecp))
				return 1;
		}

		return register_opaque_master(&opaque_master_nicintel_ee_82580);
	} else {
		nicintel_eebar = rphysmap("Intel i210 NIC w/ emulated EEPROM",
					  io_base_addr + 0x12000, MEMMAP_SIZE);
		if (!nicintel_eebar)
			return 1;

		if (register_shutdown(nicintel_ee_shutdown_i210, NULL))
			return 1;

		return register_opaque_master(&opaque_master_nicintel_ee_i210);
	}

	return 1;
}

const struct programmer_entry programmer_nicintel_eeprom = {
	.name			= "nicintel_eeprom",
	.type			= PCI,
	.devs.dev		= nics_intel_ee,
	.init			= nicintel_ee_init,
	.map_flash_region	= fallback_map,
	.unmap_flash_region	= fallback_unmap,
	.delay			= internal_delay,
};
