| #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 */ |