Commit ce5207e191c59b3135303fd03b98dd2ac3701ba2

Authored by Kyle Moffett
Committed by Wolfgang Denk
1 parent 2326a94db1

e1000: Allow direct access to the E1000 SPI EEPROM device

As a part of the manufacturing process for some of our custom hardware,
we are programming the EEPROMs attached to our Intel 82571EB controllers
from software using U-Boot and Linux.

This code provides several conditionally-compiled features to assist in
our manufacturing process:

  CONFIG_CMD_E1000:
    This is a basic "e1000" command which allows querying the controller
    and (if other config options are set) performing EEPROM programming.
    In particular, with CONFIG_E1000_SPI this allows you to display a
    hex-dump of the EEPROM, copy to/from main memory, and verify/update
    the software checksum.

  CONFIG_E1000_SPI_GENERIC:
    Build a generic SPI driver providing the standard U-Boot SPI driver
    interface.  This allows commands such as "sspi" to access the bus
    attached to the E1000 controller.  Additionally, some E1000 chipsets
    can support user data in a reserved space in the E1000 EEPROM which
    could be used for U-Boot environment storage.

  CONFIG_E1000_SPI:
    The core SPI access code used by the above interfaces.

For example, the following commands allow you to program the EEPROM from
a USB device (assumes CONFIG_E1000_SPI and CONFIG_CMD_E1000 are enabled):
  usb start
  fatload usb 0 $loadaddr 82571EB_No_Mgmt_Discrete-LOM.bin
  e1000 0 spi program $loadaddr 0 1024
  e1000 0 spi checksum update

Please keep in mind that the Intel-provided .eep files are organized as
16-bit words.  When converting them to binary form for programming you
must byteswap each 16-bit word so that it is in little-endian form.

This means that when reading and writing words to the SPI EEPROM, the
bit ordering for each word looks like this on the wire:

  Time >>>
------------------------------------------------------------------
  ... [7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8], ...
------------------------------------------------------------------
  (MSB is 15, LSB is 0).

Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
Cc: Ben Warren <biggerbadderben@gmail.com>

Showing 5 changed files with 671 additions and 2 deletions Side-by-side Diff

... ... @@ -957,7 +957,20 @@
957 957  
958 958 - NETWORK Support (PCI):
959 959 CONFIG_E1000
960   - Support for Intel 8254x gigabit chips.
  960 + Support for Intel 8254x/8257x gigabit chips.
  961 +
  962 + CONFIG_E1000_SPI
  963 + Utility code for direct access to the SPI bus on Intel 8257x.
  964 + This does not do anything useful unless you set at least one
  965 + of CONFIG_CMD_E1000 or CONFIG_E1000_SPI_GENERIC.
  966 +
  967 + CONFIG_E1000_SPI_GENERIC
  968 + Allow generic access to the SPI bus on the Intel 8257x, for
  969 + example with the "sspi" command.
  970 +
  971 + CONFIG_CMD_E1000
  972 + Management command for E1000 devices. When used on devices
  973 + with SPI support you can reprogram the EEPROM from U-Boot.
961 974  
962 975 CONFIG_E1000_FALLBACK_MAC
963 976 default MAC for empty EEPROM after production.
drivers/net/Makefile
... ... @@ -37,6 +37,7 @@
37 37 COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o
38 38 COBJS-$(CONFIG_DNET) += dnet.o
39 39 COBJS-$(CONFIG_E1000) += e1000.o
  40 +COBJS-$(CONFIG_E1000_SPI) += e1000_spi.o
40 41 COBJS-$(CONFIG_EEPRO100) += eepro100.o
41 42 COBJS-$(CONFIG_ENC28J60) += enc28j60.o
42 43 COBJS-$(CONFIG_EP93XX) += ep93xx_eth.o
... ... @@ -5155,6 +5155,9 @@
5155 5155 }
5156 5156 }
5157 5157  
  5158 +/* A list of all registered e1000 devices */
  5159 +static LIST_HEAD(e1000_hw_list);
  5160 +
5158 5161 /**************************************************************************
5159 5162 PROBE - Look for an adapter, this routine's visible to the outside
5160 5163 You should omit the last argument struct pci_device * for a non-PCI NIC
5161 5164  
... ... @@ -5234,8 +5237,9 @@
5234 5237 if (e1000_check_phy_reset_block(hw))
5235 5238 E1000_ERR(nic, "PHY Reset is blocked!\n");
5236 5239  
5237   - /* Basic init was OK, reset the hardware */
  5240 + /* Basic init was OK, reset the hardware and allow SPI access */
5238 5241 e1000_reset_hw(hw);
  5242 + list_add_tail(&hw->list_node, &e1000_hw_list);
5239 5243  
5240 5244 /* Validate the EEPROM and get chipset information */
5241 5245 #if !(defined(CONFIG_AP1000) || defined(CONFIG_MVBC_1G))
... ... @@ -5263,4 +5267,64 @@
5263 5267  
5264 5268 return i;
5265 5269 }
  5270 +
  5271 +struct e1000_hw *e1000_find_card(unsigned int cardnum)
  5272 +{
  5273 + struct e1000_hw *hw;
  5274 +
  5275 + list_for_each_entry(hw, &e1000_hw_list, list_node)
  5276 + if (hw->cardnum == cardnum)
  5277 + return hw;
  5278 +
  5279 + return NULL;
  5280 +}
  5281 +
  5282 +#ifdef CONFIG_CMD_E1000
  5283 +static int do_e1000(cmd_tbl_t *cmdtp, int flag,
  5284 + int argc, char * const argv[])
  5285 +{
  5286 + struct e1000_hw *hw;
  5287 +
  5288 + if (argc < 3) {
  5289 + cmd_usage(cmdtp);
  5290 + return 1;
  5291 + }
  5292 +
  5293 + /* Make sure we can find the requested e1000 card */
  5294 + hw = e1000_find_card(simple_strtoul(argv[1], NULL, 10));
  5295 + if (!hw) {
  5296 + printf("e1000: ERROR: No such device: e1000#%s\n", argv[1]);
  5297 + return 1;
  5298 + }
  5299 +
  5300 + if (!strcmp(argv[2], "print-mac-address")) {
  5301 + unsigned char *mac = hw->nic->enetaddr;
  5302 + printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
  5303 + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  5304 + return 0;
  5305 + }
  5306 +
  5307 +#ifdef CONFIG_E1000_SPI
  5308 + /* Handle the "SPI" subcommand */
  5309 + if (!strcmp(argv[2], "spi"))
  5310 + return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3);
  5311 +#endif
  5312 +
  5313 + cmd_usage(cmdtp);
  5314 + return 1;
  5315 +}
  5316 +
  5317 +U_BOOT_CMD(
  5318 + e1000, 7, 0, do_e1000,
  5319 + "Intel e1000 controller management",
  5320 + /* */"<card#> print-mac-address\n"
  5321 +#ifdef CONFIG_E1000_SPI
  5322 + "e1000 <card#> spi show [<offset> [<length>]]\n"
  5323 + "e1000 <card#> spi dump <addr> <offset> <length>\n"
  5324 + "e1000 <card#> spi program <addr> <offset> <length>\n"
  5325 + "e1000 <card#> spi checksum [update]\n"
  5326 +#endif
  5327 + " - Manage the Intel E1000 PCI device"
  5328 +);
  5329 +#endif /* not CONFIG_CMD_E1000 */
... ... @@ -35,12 +35,17 @@
35 35 #define _E1000_HW_H_
36 36  
37 37 #include <common.h>
  38 +#include <linux/list.h>
38 39 #include <malloc.h>
39 40 #include <net.h>
40 41 #include <netdev.h>
41 42 #include <asm/io.h>
42 43 #include <pci.h>
43 44  
  45 +#ifdef CONFIG_E1000_SPI
  46 +#include <spi.h>
  47 +#endif
  48 +
44 49 #define E1000_ERR(NIC, fmt, args...) \
45 50 printf("e1000: %s: ERROR: " fmt, (NIC)->name ,##args)
46 51  
47 52  
... ... @@ -72,12 +77,18 @@
72 77 struct e1000_hw_stats;
73 78  
74 79 /* Internal E1000 helper functions */
  80 +struct e1000_hw *e1000_find_card(unsigned int cardnum);
75 81 int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
76 82 void e1000_standby_eeprom(struct e1000_hw *hw);
77 83 void e1000_release_eeprom(struct e1000_hw *hw);
78 84 void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
79 85 void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
80 86  
  87 +#ifdef CONFIG_E1000_SPI
  88 +int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
  89 + int argc, char * const argv[]);
  90 +#endif
  91 +
81 92 typedef enum {
82 93 FALSE = 0,
83 94 TRUE = 1
84 95  
... ... @@ -1068,7 +1079,11 @@
1068 1079  
1069 1080 /* Structure containing variables used by the shared code (e1000_hw.c) */
1070 1081 struct e1000_hw {
  1082 + struct list_head list_node;
1071 1083 struct eth_device *nic;
  1084 +#ifdef CONFIG_E1000_SPI
  1085 + struct spi_slave spi;
  1086 +#endif
1072 1087 unsigned int cardnum;
1073 1088  
1074 1089 pci_dev_t pdev;
drivers/net/e1000_spi.c
  1 +#include "e1000.h"
  2 +
  3 +/*-----------------------------------------------------------------------
  4 + * SPI transfer
  5 + *
  6 + * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks
  7 + * "bitlen" bits in the SPI MISO port. That's just the way SPI works.
  8 + *
  9 + * The source of the outgoing bits is the "dout" parameter and the
  10 + * destination of the input bits is the "din" parameter. Note that "dout"
  11 + * and "din" can point to the same memory location, in which case the
  12 + * input data overwrites the output data (since both are buffered by
  13 + * temporary variables, this is OK).
  14 + *
  15 + * This may be interrupted with Ctrl-C if "intr" is true, otherwise it will
  16 + * never return an error.
  17 + */
  18 +static int e1000_spi_xfer(struct e1000_hw *hw, unsigned int bitlen,
  19 + const void *dout_mem, void *din_mem, boolean_t intr)
  20 +{
  21 + const uint8_t *dout = dout_mem;
  22 + uint8_t *din = din_mem;
  23 +
  24 + uint8_t mask = 0;
  25 + uint32_t eecd;
  26 + unsigned long i;
  27 +
  28 + /* Pre-read the control register */
  29 + eecd = E1000_READ_REG(hw, EECD);
  30 +
  31 + /* Iterate over each bit */
  32 + for (i = 0, mask = 0x80; i < bitlen; i++, mask = (mask >> 1)?:0x80) {
  33 + /* Check for interrupt */
  34 + if (intr && ctrlc())
  35 + return -1;
  36 +
  37 + /* Determine the output bit */
  38 + if (dout && dout[i >> 3] & mask)
  39 + eecd |= E1000_EECD_DI;
  40 + else
  41 + eecd &= ~E1000_EECD_DI;
  42 +
  43 + /* Write the output bit and wait 50us */
  44 + E1000_WRITE_REG(hw, EECD, eecd);
  45 + E1000_WRITE_FLUSH(hw);
  46 + udelay(50);
  47 +
  48 + /* Poke the clock (waits 50us) */
  49 + e1000_raise_ee_clk(hw, &eecd);
  50 +
  51 + /* Now read the input bit */
  52 + eecd = E1000_READ_REG(hw, EECD);
  53 + if (din) {
  54 + if (eecd & E1000_EECD_DO)
  55 + din[i >> 3] |= mask;
  56 + else
  57 + din[i >> 3] &= ~mask;
  58 + }
  59 +
  60 + /* Poke the clock again (waits 50us) */
  61 + e1000_lower_ee_clk(hw, &eecd);
  62 + }
  63 +
  64 + /* Now clear any remaining bits of the input */
  65 + if (din && (i & 7))
  66 + din[i >> 3] &= ~((mask << 1) - 1);
  67 +
  68 + return 0;
  69 +}
  70 +
  71 +#ifdef CONFIG_E1000_SPI_GENERIC
  72 +static inline struct e1000_hw *e1000_hw_from_spi(struct spi_slave *spi)
  73 +{
  74 + return container_of(spi, struct e1000_hw, spi);
  75 +}
  76 +
  77 +/* Not sure why all of these are necessary */
  78 +void spi_init_r(void) { /* Nothing to do */ }
  79 +void spi_init_f(void) { /* Nothing to do */ }
  80 +void spi_init(void) { /* Nothing to do */ }
  81 +
  82 +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  83 + unsigned int max_hz, unsigned int mode)
  84 +{
  85 + /* Find the right PCI device */
  86 + struct e1000_hw *hw = e1000_find_card(bus);
  87 + if (!hw) {
  88 + printf("ERROR: No such e1000 device: e1000#%u\n", bus);
  89 + return NULL;
  90 + }
  91 +
  92 + /* Make sure it has an SPI chip */
  93 + if (hw->eeprom.type != e1000_eeprom_spi) {
  94 + E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n");
  95 + return NULL;
  96 + }
  97 +
  98 + /* Argument sanity checks */
  99 + if (cs != 0) {
  100 + E1000_ERR(hw->nic, "No such SPI chip: %u\n", cs);
  101 + return NULL;
  102 + }
  103 + if (mode != SPI_MODE_0) {
  104 + E1000_ERR(hw->nic, "Only SPI MODE-0 is supported!\n");
  105 + return NULL;
  106 + }
  107 +
  108 + /* TODO: Use max_hz somehow */
  109 + E1000_DBG(hw->nic, "EEPROM SPI access requested\n");
  110 + return &hw->spi;
  111 +}
  112 +
  113 +void spi_free_slave(struct spi_slave *spi)
  114 +{
  115 + struct e1000_hw *hw = e1000_hw_from_spi(spi);
  116 + E1000_DBG(hw->nic, "EEPROM SPI access released\n");
  117 +}
  118 +
  119 +int spi_claim_bus(struct spi_slave *spi)
  120 +{
  121 + struct e1000_hw *hw = e1000_hw_from_spi(spi);
  122 +
  123 + if (e1000_acquire_eeprom(hw)) {
  124 + E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
  125 + return -1;
  126 + }
  127 +
  128 + return 0;
  129 +}
  130 +
  131 +void spi_release_bus(struct spi_slave *spi)
  132 +{
  133 + struct e1000_hw *hw = e1000_hw_from_spi(spi);
  134 + e1000_release_eeprom(hw);
  135 +}
  136 +
  137 +/* Skinny wrapper around e1000_spi_xfer */
  138 +int spi_xfer(struct spi_slave *spi, unsigned int bitlen,
  139 + const void *dout_mem, void *din_mem, unsigned long flags)
  140 +{
  141 + struct e1000_hw *hw = e1000_hw_from_spi(spi);
  142 + int ret;
  143 +
  144 + if (flags & SPI_XFER_BEGIN)
  145 + e1000_standby_eeprom(hw);
  146 +
  147 + ret = e1000_spi_xfer(hw, bitlen, dout_mem, din_mem, TRUE);
  148 +
  149 + if (flags & SPI_XFER_END)
  150 + e1000_standby_eeprom(hw);
  151 +
  152 + return ret;
  153 +}
  154 +
  155 +#endif /* not CONFIG_E1000_SPI_GENERIC */
  156 +
  157 +#ifdef CONFIG_CMD_E1000
  158 +
  159 +/* The EEPROM opcodes */
  160 +#define SPI_EEPROM_ENABLE_WR 0x06
  161 +#define SPI_EEPROM_DISABLE_WR 0x04
  162 +#define SPI_EEPROM_WRITE_STATUS 0x01
  163 +#define SPI_EEPROM_READ_STATUS 0x05
  164 +#define SPI_EEPROM_WRITE_PAGE 0x02
  165 +#define SPI_EEPROM_READ_PAGE 0x03
  166 +
  167 +/* The EEPROM status bits */
  168 +#define SPI_EEPROM_STATUS_BUSY 0x01
  169 +#define SPI_EEPROM_STATUS_WREN 0x02
  170 +
  171 +static int e1000_spi_eeprom_enable_wr(struct e1000_hw *hw, boolean_t intr)
  172 +{
  173 + u8 op[] = { SPI_EEPROM_ENABLE_WR };
  174 + e1000_standby_eeprom(hw);
  175 + return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
  176 +}
  177 +
  178 +/*
  179 + * These have been tested to perform correctly, but they are not used by any
  180 + * of the EEPROM commands at this time.
  181 + */
  182 +#if 0
  183 +static int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw, boolean_t intr)
  184 +{
  185 + u8 op[] = { SPI_EEPROM_DISABLE_WR };
  186 + e1000_standby_eeprom(hw);
  187 + return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
  188 +}
  189 +
  190 +static int e1000_spi_eeprom_write_status(struct e1000_hw *hw,
  191 + u8 status, boolean_t intr)
  192 +{
  193 + u8 op[] = { SPI_EEPROM_WRITE_STATUS, status };
  194 + e1000_standby_eeprom(hw);
  195 + return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
  196 +}
  197 +#endif
  198 +
  199 +static int e1000_spi_eeprom_read_status(struct e1000_hw *hw, boolean_t intr)
  200 +{
  201 + u8 op[] = { SPI_EEPROM_READ_STATUS, 0 };
  202 + e1000_standby_eeprom(hw);
  203 + if (e1000_spi_xfer(hw, 8*sizeof(op), op, op, intr))
  204 + return -1;
  205 + return op[1];
  206 +}
  207 +
  208 +static int e1000_spi_eeprom_write_page(struct e1000_hw *hw,
  209 + const void *data, u16 off, u16 len, boolean_t intr)
  210 +{
  211 + u8 op[] = {
  212 + SPI_EEPROM_WRITE_PAGE,
  213 + (off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
  214 + };
  215 +
  216 + e1000_standby_eeprom(hw);
  217 +
  218 + if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
  219 + return -1;
  220 + if (e1000_spi_xfer(hw, len << 3, data, NULL, intr))
  221 + return -1;
  222 +
  223 + return 0;
  224 +}
  225 +
  226 +static int e1000_spi_eeprom_read_page(struct e1000_hw *hw,
  227 + void *data, u16 off, u16 len, boolean_t intr)
  228 +{
  229 + u8 op[] = {
  230 + SPI_EEPROM_READ_PAGE,
  231 + (off >> (hw->eeprom.address_bits - 8)) & 0xff, off & 0xff
  232 + };
  233 +
  234 + e1000_standby_eeprom(hw);
  235 +
  236 + if (e1000_spi_xfer(hw, 8 + hw->eeprom.address_bits, op, NULL, intr))
  237 + return -1;
  238 + if (e1000_spi_xfer(hw, len << 3, NULL, data, intr))
  239 + return -1;
  240 +
  241 + return 0;
  242 +}
  243 +
  244 +static int e1000_spi_eeprom_poll_ready(struct e1000_hw *hw, boolean_t intr)
  245 +{
  246 + int status;
  247 + while ((status = e1000_spi_eeprom_read_status(hw, intr)) >= 0) {
  248 + if (!(status & SPI_EEPROM_STATUS_BUSY))
  249 + return 0;
  250 + }
  251 + return -1;
  252 +}
  253 +
  254 +static int e1000_spi_eeprom_dump(struct e1000_hw *hw,
  255 + void *data, u16 off, unsigned int len, boolean_t intr)
  256 +{
  257 + /* Interruptibly wait for the EEPROM to be ready */
  258 + if (e1000_spi_eeprom_poll_ready(hw, intr))
  259 + return -1;
  260 +
  261 + /* Dump each page in sequence */
  262 + while (len) {
  263 + /* Calculate the data bytes on this page */
  264 + u16 pg_off = off & (hw->eeprom.page_size - 1);
  265 + u16 pg_len = hw->eeprom.page_size - pg_off;
  266 + if (pg_len > len)
  267 + pg_len = len;
  268 +
  269 + /* Now dump the page */
  270 + if (e1000_spi_eeprom_read_page(hw, data, off, pg_len, intr))
  271 + return -1;
  272 +
  273 + /* Otherwise go on to the next page */
  274 + len -= pg_len;
  275 + off += pg_len;
  276 + data += pg_len;
  277 + }
  278 +
  279 + /* We're done! */
  280 + return 0;
  281 +}
  282 +
  283 +static int e1000_spi_eeprom_program(struct e1000_hw *hw,
  284 + const void *data, u16 off, u16 len, boolean_t intr)
  285 +{
  286 + /* Program each page in sequence */
  287 + while (len) {
  288 + /* Calculate the data bytes on this page */
  289 + u16 pg_off = off & (hw->eeprom.page_size - 1);
  290 + u16 pg_len = hw->eeprom.page_size - pg_off;
  291 + if (pg_len > len)
  292 + pg_len = len;
  293 +
  294 + /* Interruptibly wait for the EEPROM to be ready */
  295 + if (e1000_spi_eeprom_poll_ready(hw, intr))
  296 + return -1;
  297 +
  298 + /* Enable write access */
  299 + if (e1000_spi_eeprom_enable_wr(hw, intr))
  300 + return -1;
  301 +
  302 + /* Now program the page */
  303 + if (e1000_spi_eeprom_write_page(hw, data, off, pg_len, intr))
  304 + return -1;
  305 +
  306 + /* Otherwise go on to the next page */
  307 + len -= pg_len;
  308 + off += pg_len;
  309 + data += pg_len;
  310 + }
  311 +
  312 + /* Wait for the last write to complete */
  313 + if (e1000_spi_eeprom_poll_ready(hw, intr))
  314 + return -1;
  315 +
  316 + /* We're done! */
  317 + return 0;
  318 +}
  319 +
  320 +static int do_e1000_spi_show(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
  321 + int argc, char * const argv[])
  322 +{
  323 + unsigned int length = 0;
  324 + u16 i, offset = 0;
  325 + u8 *buffer;
  326 + int err;
  327 +
  328 + if (argc > 2) {
  329 + cmd_usage(cmdtp);
  330 + return 1;
  331 + }
  332 +
  333 + /* Parse the offset and length */
  334 + if (argc >= 1)
  335 + offset = simple_strtoul(argv[0], NULL, 0);
  336 + if (argc == 2)
  337 + length = simple_strtoul(argv[1], NULL, 0);
  338 + else if (offset < (hw->eeprom.word_size << 1))
  339 + length = (hw->eeprom.word_size << 1) - offset;
  340 +
  341 + /* Extra sanity checks */
  342 + if (!length) {
  343 + E1000_ERR(hw->nic, "Requested zero-sized dump!\n");
  344 + return 1;
  345 + }
  346 + if ((0x10000 < length) || (0x10000 - length < offset)) {
  347 + E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n");
  348 + return 1;
  349 + }
  350 +
  351 + /* Allocate a buffer to hold stuff */
  352 + buffer = malloc(length);
  353 + if (!buffer) {
  354 + E1000_ERR(hw->nic, "Out of Memory!\n");
  355 + return 1;
  356 + }
  357 +
  358 + /* Acquire the EEPROM and perform the dump */
  359 + if (e1000_acquire_eeprom(hw)) {
  360 + E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
  361 + free(buffer);
  362 + return 1;
  363 + }
  364 + err = e1000_spi_eeprom_dump(hw, buffer, offset, length, TRUE);
  365 + e1000_release_eeprom(hw);
  366 + if (err) {
  367 + E1000_ERR(hw->nic, "Interrupted!\n");
  368 + free(buffer);
  369 + return 1;
  370 + }
  371 +
  372 + /* Now hexdump the result */
  373 + printf("%s: ===== Intel e1000 EEPROM (0x%04hX - 0x%04hX) =====",
  374 + hw->nic->name, offset, offset + length - 1);
  375 + for (i = 0; i < length; i++) {
  376 + if ((i & 0xF) == 0)
  377 + printf("\n%s: %04hX: ", hw->nic->name, offset + i);
  378 + else if ((i & 0xF) == 0x8)
  379 + printf(" ");
  380 + printf(" %02hx", buffer[i]);
  381 + }
  382 + printf("\n");
  383 +
  384 + /* Success! */
  385 + free(buffer);
  386 + return 0;
  387 +}
  388 +
  389 +static int do_e1000_spi_dump(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
  390 + int argc, char * const argv[])
  391 +{
  392 + unsigned int length;
  393 + u16 offset;
  394 + void *dest;
  395 +
  396 + if (argc != 3) {
  397 + cmd_usage(cmdtp);
  398 + return 1;
  399 + }
  400 +
  401 + /* Parse the arguments */
  402 + dest = (void *)simple_strtoul(argv[0], NULL, 16);
  403 + offset = simple_strtoul(argv[1], NULL, 0);
  404 + length = simple_strtoul(argv[2], NULL, 0);
  405 +
  406 + /* Extra sanity checks */
  407 + if (!length) {
  408 + E1000_ERR(hw->nic, "Requested zero-sized dump!\n");
  409 + return 1;
  410 + }
  411 + if ((0x10000 < length) || (0x10000 - length < offset)) {
  412 + E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n");
  413 + return 1;
  414 + }
  415 +
  416 + /* Acquire the EEPROM */
  417 + if (e1000_acquire_eeprom(hw)) {
  418 + E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
  419 + return 1;
  420 + }
  421 +
  422 + /* Perform the programming operation */
  423 + if (e1000_spi_eeprom_dump(hw, dest, offset, length, TRUE) < 0) {
  424 + E1000_ERR(hw->nic, "Interrupted!\n");
  425 + e1000_release_eeprom(hw);
  426 + return 1;
  427 + }
  428 +
  429 + e1000_release_eeprom(hw);
  430 + printf("%s: ===== EEPROM DUMP COMPLETE =====\n", hw->nic->name);
  431 + return 0;
  432 +}
  433 +
  434 +static int do_e1000_spi_program(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
  435 + int argc, char * const argv[])
  436 +{
  437 + unsigned int length;
  438 + const void *source;
  439 + u16 offset;
  440 +
  441 + if (argc != 3) {
  442 + cmd_usage(cmdtp);
  443 + return 1;
  444 + }
  445 +
  446 + /* Parse the arguments */
  447 + source = (const void *)simple_strtoul(argv[0], NULL, 16);
  448 + offset = simple_strtoul(argv[1], NULL, 0);
  449 + length = simple_strtoul(argv[2], NULL, 0);
  450 +
  451 + /* Acquire the EEPROM */
  452 + if (e1000_acquire_eeprom(hw)) {
  453 + E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
  454 + return 1;
  455 + }
  456 +
  457 + /* Perform the programming operation */
  458 + if (e1000_spi_eeprom_program(hw, source, offset, length, TRUE) < 0) {
  459 + E1000_ERR(hw->nic, "Interrupted!\n");
  460 + e1000_release_eeprom(hw);
  461 + return 1;
  462 + }
  463 +
  464 + e1000_release_eeprom(hw);
  465 + printf("%s: ===== EEPROM PROGRAMMED =====\n", hw->nic->name);
  466 + return 0;
  467 +}
  468 +
  469 +static int do_e1000_spi_checksum(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
  470 + int argc, char * const argv[])
  471 +{
  472 + uint16_t i, length, checksum, checksum_reg;
  473 + uint16_t *buffer;
  474 + boolean_t upd;
  475 +
  476 + if (argc == 0)
  477 + upd = 0;
  478 + else if ((argc == 1) && !strcmp(argv[0], "update"))
  479 + upd = 1;
  480 + else {
  481 + cmd_usage(cmdtp);
  482 + return 1;
  483 + }
  484 +
  485 + /* Allocate a temporary buffer */
  486 + length = sizeof(uint16_t) * (EEPROM_CHECKSUM_REG + 1);
  487 + buffer = malloc(length);
  488 + if (!buffer) {
  489 + E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n");
  490 + return 1;
  491 + }
  492 +
  493 + /* Acquire the EEPROM */
  494 + if (e1000_acquire_eeprom(hw)) {
  495 + E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n");
  496 + return 1;
  497 + }
  498 +
  499 + /* Read the EEPROM */
  500 + if (e1000_spi_eeprom_dump(hw, buffer, 0, length, TRUE) < 0) {
  501 + E1000_ERR(hw->nic, "Interrupted!\n");
  502 + e1000_release_eeprom(hw);
  503 + return 1;
  504 + }
  505 +
  506 + /* Compute the checksum and read the expected value */
  507 + for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
  508 + checksum += le16_to_cpu(buffer[i]);
  509 + checksum = ((uint16_t)EEPROM_SUM) - checksum;
  510 + checksum_reg = le16_to_cpu(buffer[i]);
  511 +
  512 + /* Verify it! */
  513 + if (checksum_reg == checksum) {
  514 + printf("%s: INFO: EEPROM checksum is correct! (0x%04hx)\n",
  515 + hw->nic->name, checksum);
  516 + e1000_release_eeprom(hw);
  517 + return 0;
  518 + }
  519 +
  520 + /* Hrm, verification failed, print an error */
  521 + E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n");
  522 + E1000_ERR(hw->nic, " ...register was 0x%04hx, calculated 0x%04hx\n",
  523 + checksum_reg, checksum);
  524 +
  525 + /* If they didn't ask us to update it, just return an error */
  526 + if (!upd) {
  527 + e1000_release_eeprom(hw);
  528 + return 1;
  529 + }
  530 +
  531 + /* Ok, correct it! */
  532 + printf("%s: Reprogramming the EEPROM checksum...\n", hw->nic->name);
  533 + buffer[i] = cpu_to_le16(checksum);
  534 + if (e1000_spi_eeprom_program(hw, &buffer[i], i * sizeof(uint16_t),
  535 + sizeof(uint16_t), TRUE)) {
  536 + E1000_ERR(hw->nic, "Interrupted!\n");
  537 + e1000_release_eeprom(hw);
  538 + return 1;
  539 + }
  540 +
  541 + e1000_release_eeprom(hw);
  542 + return 0;
  543 +}
  544 +
  545 +int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
  546 + int argc, char * const argv[])
  547 +{
  548 + if (argc < 1) {
  549 + cmd_usage(cmdtp);
  550 + return 1;
  551 + }
  552 +
  553 + /* Make sure it has an SPI chip */
  554 + if (hw->eeprom.type != e1000_eeprom_spi) {
  555 + E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n");
  556 + return 1;
  557 + }
  558 +
  559 + /* Check the eeprom sub-sub-command arguments */
  560 + if (!strcmp(argv[0], "show"))
  561 + return do_e1000_spi_show(cmdtp, hw, argc - 1, argv + 1);
  562 +
  563 + if (!strcmp(argv[0], "dump"))
  564 + return do_e1000_spi_dump(cmdtp, hw, argc - 1, argv + 1);
  565 +
  566 + if (!strcmp(argv[0], "program"))
  567 + return do_e1000_spi_program(cmdtp, hw, argc - 1, argv + 1);
  568 +
  569 + if (!strcmp(argv[0], "checksum"))
  570 + return do_e1000_spi_checksum(cmdtp, hw, argc - 1, argv + 1);
  571 +
  572 + cmd_usage(cmdtp);
  573 + return 1;
  574 +}
  575 +
  576 +#endif /* not CONFIG_CMD_E1000 */