/*
 * 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_physmap.h"
#include "platform/pci.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 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_prepare_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_prepare_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;
		flashprog_progress_add(flash, 1);
		*buf++ = data & 0xff;
		addr++;
		len--;
		if (len > 0) {
			flashprog_progress_add(flash, 1);
			*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 ++;
			flashprog_progress_add(flash, 1);
		}
		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;
			flashprog_progress_add(flash, min(len, 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 (buf)
				flashprog_progress_add(flash, 1);
			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 int nicintel_ee_shutdown_82580(void *eecp);

static const struct opaque_master opaque_master_nicintel_ee_82580 = {
	.prepare	= nicintel_ee_prepare_82580,
	.read		= nicintel_ee_read,
	.write		= nicintel_ee_write_82580,
	.erase		= nicintel_ee_erase_82580,
	.shutdown	= nicintel_ee_shutdown_82580,
};

static int nicintel_ee_shutdown_i210(void *arg);

static const struct opaque_master opaque_master_nicintel_ee_i210 = {
	.prepare	= nicintel_ee_prepare_i210,
	.read		= nicintel_ee_read,
	.write		= nicintel_ee_write_i210,
	.erase		= nicintel_ee_erase_i210,
	.shutdown	= nicintel_ee_shutdown_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)
{
	int ret = 0;

	if (nicintel_pci->device_id != UNPROG_DEVICE) {
		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)) {
			ret = -1;
			goto out;
		}

		/* Try to restore individual bits we care about. */
		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));
	}

out:
	free(eecp);
	return ret;
}

static int nicintel_ee_init(struct flashprog_programmer *const prog)
{
	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;

		uint32_t *eecp = NULL;

		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;
			}

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

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

		return register_opaque_master(&opaque_master_nicintel_ee_i210, NULL);
	}

	return 1;
}

const struct programmer_entry programmer_nicintel_eeprom = {
	.name			= "nicintel_eeprom",
	.type			= PCI,
	.devs.dev		= nics_intel_ee,
	.init			= nicintel_ee_init,
};
