#include "e1000.h"
#include <linux/compiler.h>

/*-----------------------------------------------------------------------
 * SPI transfer
 *
 * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
 * "bitlen" bits in the SPI MISO port.  That's just the way SPI works.
 *
 * The source of the outgoing bits is the "dout" parameter and the
 * destination of the input bits is the "din" parameter.  Note that "dout"
 * and "din" can point to the same memory location, in which case the
 * input data overwrites the output data (since both are buffered by
 * temporary variables, this is OK).
 *
 * This may be interrupted with Ctrl-C if "intr" is true, otherwise it will
 * never return an error.
 */
static int e1000_spi_xfer(struct e1000_hw *hw, unsigned int bitlen,
		const void *dout_mem, void *din_mem, boolean_t intr)
{
	const uint8_t *dout = dout_mem;
	uint8_t *din = din_mem;

	uint8_t mask = 0;
	uint32_t eecd;
	unsigned long i;

	/* Pre-read the control register */
	eecd = E1000_READ_REG(hw, EECD);

	/* Iterate over each bit */
	for (i = 0, mask = 0x80; i < bitlen; i++, mask = (mask >> 1)?:0x80) {
		/* Check for interrupt */
		if (intr && ctrlc())
			return -1;

		/* Determine the output bit */
		if (dout && dout[i >> 3] & mask)
			eecd |=  E1000_EECD_DI;
		else
			eecd &= ~E1000_EECD_DI;

		/* Write the output bit and wait 50us */
		E1000_WRITE_REG(hw, EECD, eecd);
		E1000_WRITE_FLUSH(hw);
		udelay(50);

		/* Poke the clock (waits 50us) */
		e1000_raise_ee_clk(hw, &eecd);

		/* Now read the input bit */
		eecd = E1000_READ_REG(hw, EECD);
		if (din) {
			if (eecd & E1000_EECD_DO)
				din[i >> 3] |=  mask;
			else
				din[i >> 3] &= ~mask;
		}

		/* Poke the clock again (waits 50us) */
		e1000_lower_ee_clk(hw, &eecd);
	}

	/* Now clear any remaining bits of the input */
	if (din && (i & 7))
		din[i >> 3] &= ~((mask << 1) - 1);

	return 0;
}

#ifdef CONFIG_E1000_SPI_GENERIC
static inline struct e1000_hw *e1000_hw_from_spi(struct spi_slave *spi)
{
	return container_of(spi, struct e1000_hw, spi);
}

/* Not sure why all of these are necessary */
void spi_init_r(void) { /* Nothing to do */ }
void spi_init_f(void) { /* Nothing to do */ }
void spi_init(void)   { /* Nothing to do */ }

struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
		unsigned int max_hz, unsigned int mode)
{
	/* Find the right PCI device */
	struct e1000_hw *hw = e1000_find_card(bus);
	if (!hw) {
		printf("ERROR: No such e1000 device: e1000#%u\n", bus);
		return NULL;
	}

	/* Make sure it has an SPI chip */
	if (hw->eeprom.type != e1000_eeprom_spi) {
		E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n");
		return NULL;
	}

	/* Argument sanity checks */
	if (cs != 0) {
		E1000_ERR(hw->nic, "No such SPI chip: %u\n", cs);
		return NULL;
	}
	if (mode != SPI_MODE_0) {
		E1000_ERR(hw->nic, "Only SPI MODE-0 is supported!\n");
		return NULL;
	}

	/* TODO: Use max_hz somehow */
	E1000_DBG(hw->nic, "EEPROM SPI access requested\n");
	return &hw->spi;
}

void spi_free_slave(struct spi_slave *spi)
{
	__maybe_unused struct e1000_hw *hw = e1000_hw_from_spi(spi);
	E1000_DBG(hw->nic, "EEPROM SPI access released\n");
}

int spi_claim_bus(struct spi_slave *spi)
{
	struct e1000_hw *hw = e1000_hw_from_spi(spi);

	if (e1000_acquire_eeprom(hw)) {
		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
		return -1;
	}

	return 0;
}

void spi_release_bus(struct spi_slave *spi)
{
	struct e1000_hw *hw = e1000_hw_from_spi(spi);
	e1000_release_eeprom(hw);
}

/* Skinny wrapper around e1000_spi_xfer */
int spi_xfer(struct spi_slave *spi, unsigned int bitlen,
		const void *dout_mem, void *din_mem, unsigned long flags)
{
	struct e1000_hw *hw = e1000_hw_from_spi(spi);
	int ret;

	if (flags & SPI_XFER_BEGIN)
		e1000_standby_eeprom(hw);

	ret = e1000_spi_xfer(hw, bitlen, dout_mem, din_mem, TRUE);

	if (flags & SPI_XFER_END)
		e1000_standby_eeprom(hw);

	return ret;
}

#endif /* not CONFIG_E1000_SPI_GENERIC */

#ifdef CONFIG_CMD_E1000

/* The EEPROM opcodes */
#define SPI_EEPROM_ENABLE_WR	0x06
#define SPI_EEPROM_DISABLE_WR	0x04
#define SPI_EEPROM_WRITE_STATUS	0x01
#define SPI_EEPROM_READ_STATUS	0x05
#define SPI_EEPROM_WRITE_PAGE	0x02
#define SPI_EEPROM_READ_PAGE	0x03

/* The EEPROM status bits */
#define SPI_EEPROM_STATUS_BUSY	0x01
#define SPI_EEPROM_STATUS_WREN	0x02

static int e1000_spi_eeprom_enable_wr(struct e1000_hw *hw, boolean_t intr)
{
	u8 op[] = { SPI_EEPROM_ENABLE_WR };
	e1000_standby_eeprom(hw);
	return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
}

/*
 * These have been tested to perform correctly, but they are not used by any
 * of the EEPROM commands at this time.
 */
#if 0
static int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw, boolean_t intr)
{
	u8 op[] = { SPI_EEPROM_DISABLE_WR };
	e1000_standby_eeprom(hw);
	return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
}

static int e1000_spi_eeprom_write_status(struct e1000_hw *hw,
		u8 status, boolean_t intr)
{
	u8 op[] = { SPI_EEPROM_WRITE_STATUS, status };
	e1000_standby_eeprom(hw);
	return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
}
#endif

static int e1000_spi_eeprom_read_status(struct e1000_hw *hw, boolean_t intr)
{
	u8 op[] = { SPI_EEPROM_READ_STATUS, 0 };
	e1000_standby_eeprom(hw);
	if (e1000_spi_xfer(hw, 8*sizeof(op), op, op, intr))
		return -1;
	return op[1];
}

static int e1000_spi_eeprom_write_page(struct e1000_hw *hw,
		const void *data, u16 off, u16 len, boolean_t intr)
{
	u8 op[] = {
		SPI_EEPROM_WRITE_PAGE,
		(off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
	};

	e1000_standby_eeprom(hw);

	if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
		return -1;
	if (e1000_spi_xfer(hw, len << 3, data, NULL, intr))
		return -1;

	return 0;
}

static int e1000_spi_eeprom_read_page(struct e1000_hw *hw,
		void *data, u16 off, u16 len, boolean_t intr)
{
	u8 op[] = {
		SPI_EEPROM_READ_PAGE,
		(off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
	};

	e1000_standby_eeprom(hw);

	if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
		return -1;
	if (e1000_spi_xfer(hw, len << 3, NULL, data, intr))
		return -1;

	return 0;
}

static int e1000_spi_eeprom_poll_ready(struct e1000_hw *hw, boolean_t intr)
{
	int status;
	while ((status = e1000_spi_eeprom_read_status(hw, intr)) >= 0) {
		if (!(status & SPI_EEPROM_STATUS_BUSY))
			return 0;
	}
	return -1;
}

static int e1000_spi_eeprom_dump(struct e1000_hw *hw,
		void *data, u16 off, unsigned int len, boolean_t intr)
{
	/* Interruptibly wait for the EEPROM to be ready */
	if (e1000_spi_eeprom_poll_ready(hw, intr))
		return -1;

	/* Dump each page in sequence */
	while (len) {
		/* Calculate the data bytes on this page */
		u16 pg_off = off & (hw->eeprom.page_size - 1);
		u16 pg_len = hw->eeprom.page_size - pg_off;
		if (pg_len > len)
			pg_len = len;

		/* Now dump the page */
		if (e1000_spi_eeprom_read_page(hw, data, off, pg_len, intr))
			return -1;

		/* Otherwise go on to the next page */
		len  -= pg_len;
		off  += pg_len;
		data += pg_len;
	}

	/* We're done! */
	return 0;
}

static int e1000_spi_eeprom_program(struct e1000_hw *hw,
		const void *data, u16 off, u16 len, boolean_t intr)
{
	/* Program each page in sequence */
	while (len) {
		/* Calculate the data bytes on this page */
		u16 pg_off = off & (hw->eeprom.page_size - 1);
		u16 pg_len = hw->eeprom.page_size - pg_off;
		if (pg_len > len)
			pg_len = len;

		/* Interruptibly wait for the EEPROM to be ready */
		if (e1000_spi_eeprom_poll_ready(hw, intr))
			return -1;

		/* Enable write access */
		if (e1000_spi_eeprom_enable_wr(hw, intr))
			return -1;

		/* Now program the page */
		if (e1000_spi_eeprom_write_page(hw, data, off, pg_len, intr))
			return -1;

		/* Otherwise go on to the next page */
		len  -= pg_len;
		off  += pg_len;
		data += pg_len;
	}

	/* Wait for the last write to complete */
	if (e1000_spi_eeprom_poll_ready(hw, intr))
		return -1;

	/* We're done! */
	return 0;
}

static int do_e1000_spi_show(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
		int argc, char * const argv[])
{
	unsigned int length = 0;
	u16 i, offset = 0;
	u8 *buffer;
	int err;

	if (argc > 2) {
		cmd_usage(cmdtp);
		return 1;
	}

	/* Parse the offset and length */
	if (argc >= 1)
		offset = simple_strtoul(argv[0], NULL, 0);
	if (argc == 2)
		length = simple_strtoul(argv[1], NULL, 0);
	else if (offset < (hw->eeprom.word_size << 1))
		length = (hw->eeprom.word_size << 1) - offset;

	/* Extra sanity checks */
	if (!length) {
		E1000_ERR(hw->nic, "Requested zero-sized dump!\n");
		return 1;
	}
	if ((0x10000 < length) || (0x10000 - length < offset)) {
		E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n");
		return 1;
	}

	/* Allocate a buffer to hold stuff */
	buffer = malloc(length);
	if (!buffer) {
		E1000_ERR(hw->nic, "Out of Memory!\n");
		return 1;
	}

	/* Acquire the EEPROM and perform the dump */
	if (e1000_acquire_eeprom(hw)) {
		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
		free(buffer);
		return 1;
	}
	err = e1000_spi_eeprom_dump(hw, buffer, offset, length, TRUE);
	e1000_release_eeprom(hw);
	if (err) {
		E1000_ERR(hw->nic, "Interrupted!\n");
		free(buffer);
		return 1;
	}

	/* Now hexdump the result */
	printf("%s: ===== Intel e1000 EEPROM (0x%04hX - 0x%04hX) =====",
			hw->nic->name, offset, offset + length - 1);
	for (i = 0; i < length; i++) {
		if ((i & 0xF) == 0)
			printf("\n%s: %04hX: ", hw->nic->name, offset + i);
		else if ((i & 0xF) == 0x8)
			printf(" ");
		printf(" %02hx", buffer[i]);
	}
	printf("\n");

	/* Success! */
	free(buffer);
	return 0;
}

static int do_e1000_spi_dump(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
		int argc, char * const argv[])
{
	unsigned int length;
	u16 offset;
	void *dest;

	if (argc != 3) {
		cmd_usage(cmdtp);
		return 1;
	}

	/* Parse the arguments */
	dest = (void *)simple_strtoul(argv[0], NULL, 16);
	offset = simple_strtoul(argv[1], NULL, 0);
	length = simple_strtoul(argv[2], NULL, 0);

	/* Extra sanity checks */
	if (!length) {
		E1000_ERR(hw->nic, "Requested zero-sized dump!\n");
		return 1;
	}
	if ((0x10000 < length) || (0x10000 - length < offset)) {
		E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n");
		return 1;
	}

	/* Acquire the EEPROM */
	if (e1000_acquire_eeprom(hw)) {
		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
		return 1;
	}

	/* Perform the programming operation */
	if (e1000_spi_eeprom_dump(hw, dest, offset, length, TRUE) < 0) {
		E1000_ERR(hw->nic, "Interrupted!\n");
		e1000_release_eeprom(hw);
		return 1;
	}

	e1000_release_eeprom(hw);
	printf("%s: ===== EEPROM DUMP COMPLETE =====\n", hw->nic->name);
	return 0;
}

static int do_e1000_spi_program(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
		int argc, char * const argv[])
{
	unsigned int length;
	const void *source;
	u16 offset;

	if (argc != 3) {
		cmd_usage(cmdtp);
		return 1;
	}

	/* Parse the arguments */
	source = (const void *)simple_strtoul(argv[0], NULL, 16);
	offset = simple_strtoul(argv[1], NULL, 0);
	length = simple_strtoul(argv[2], NULL, 0);

	/* Acquire the EEPROM */
	if (e1000_acquire_eeprom(hw)) {
		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
		return 1;
	}

	/* Perform the programming operation */
	if (e1000_spi_eeprom_program(hw, source, offset, length, TRUE) < 0) {
		E1000_ERR(hw->nic, "Interrupted!\n");
		e1000_release_eeprom(hw);
		return 1;
	}

	e1000_release_eeprom(hw);
	printf("%s: ===== EEPROM PROGRAMMED =====\n", hw->nic->name);
	return 0;
}

static int do_e1000_spi_checksum(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
		int argc, char * const argv[])
{
	uint16_t i, length, checksum = 0, checksum_reg;
	uint16_t *buffer;
	boolean_t upd;

	if (argc == 0)
		upd = 0;
	else if ((argc == 1) && !strcmp(argv[0], "update"))
		upd = 1;
	else {
		cmd_usage(cmdtp);
		return 1;
	}

	/* Allocate a temporary buffer */
	length = sizeof(uint16_t) * (EEPROM_CHECKSUM_REG + 1);
	buffer = malloc(length);
	if (!buffer) {
		E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n");
		return 1;
	}

	/* Acquire the EEPROM */
	if (e1000_acquire_eeprom(hw)) {
		E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
		return 1;
	}

	/* Read the EEPROM */
	if (e1000_spi_eeprom_dump(hw, buffer, 0, length, TRUE) < 0) {
		E1000_ERR(hw->nic, "Interrupted!\n");
		e1000_release_eeprom(hw);
		return 1;
	}

	/* Compute the checksum and read the expected value */
	for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
		checksum += le16_to_cpu(buffer[i]);
	checksum = ((uint16_t)EEPROM_SUM) - checksum;
	checksum_reg = le16_to_cpu(buffer[i]);

	/* Verify it! */
	if (checksum_reg == checksum) {
		printf("%s: INFO: EEPROM checksum is correct! (0x%04hx)\n",
				hw->nic->name, checksum);
		e1000_release_eeprom(hw);
		return 0;
	}

	/* Hrm, verification failed, print an error */
	E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n");
	E1000_ERR(hw->nic, "  ...register was 0x%04hx, calculated 0x%04hx\n",
			checksum_reg, checksum);

	/* If they didn't ask us to update it, just return an error */
	if (!upd) {
		e1000_release_eeprom(hw);
		return 1;
	}

	/* Ok, correct it! */
	printf("%s: Reprogramming the EEPROM checksum...\n", hw->nic->name);
	buffer[i] = cpu_to_le16(checksum);
	if (e1000_spi_eeprom_program(hw, &buffer[i], i * sizeof(uint16_t),
			sizeof(uint16_t), TRUE)) {
		E1000_ERR(hw->nic, "Interrupted!\n");
		e1000_release_eeprom(hw);
		return 1;
	}

	e1000_release_eeprom(hw);
	return 0;
}

int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
		int argc, char * const argv[])
{
	if (argc < 1) {
		cmd_usage(cmdtp);
		return 1;
	}

	/* Make sure it has an SPI chip */
	if (hw->eeprom.type != e1000_eeprom_spi) {
		E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n");
		return 1;
	}

	/* Check the eeprom sub-sub-command arguments */
	if (!strcmp(argv[0], "show"))
		return do_e1000_spi_show(cmdtp, hw, argc - 1, argv + 1);

	if (!strcmp(argv[0], "dump"))
		return do_e1000_spi_dump(cmdtp, hw, argc - 1, argv + 1);

	if (!strcmp(argv[0], "program"))
		return do_e1000_spi_program(cmdtp, hw, argc - 1, argv + 1);

	if (!strcmp(argv[0], "checksum"))
		return do_e1000_spi_checksum(cmdtp, hw, argc - 1, argv + 1);

	cmd_usage(cmdtp);
	return 1;
}

#endif /* not CONFIG_CMD_E1000 */
