#include "e1000.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)
{
	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, 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 */
