mirror of
https://github.com/linux-sunxi/u-boot-sunxi.git
synced 2024-02-12 11:16:03 +08:00
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>
This commit is contained in:

committed by
Wolfgang Denk

parent
2326a94db1
commit
ce5207e191
@ -5155,6 +5155,9 @@ void e1000_get_bus_type(struct e1000_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
/* A list of all registered e1000 devices */
|
||||
static LIST_HEAD(e1000_hw_list);
|
||||
|
||||
/**************************************************************************
|
||||
PROBE - Look for an adapter, this routine's visible to the outside
|
||||
You should omit the last argument struct pci_device * for a non-PCI NIC
|
||||
@ -5234,8 +5237,9 @@ e1000_initialize(bd_t * bis)
|
||||
if (e1000_check_phy_reset_block(hw))
|
||||
E1000_ERR(nic, "PHY Reset is blocked!\n");
|
||||
|
||||
/* Basic init was OK, reset the hardware */
|
||||
/* Basic init was OK, reset the hardware and allow SPI access */
|
||||
e1000_reset_hw(hw);
|
||||
list_add_tail(&hw->list_node, &e1000_hw_list);
|
||||
|
||||
/* Validate the EEPROM and get chipset information */
|
||||
#if !(defined(CONFIG_AP1000) || defined(CONFIG_MVBC_1G))
|
||||
@ -5263,3 +5267,63 @@ e1000_initialize(bd_t * bis)
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
struct e1000_hw *e1000_find_card(unsigned int cardnum)
|
||||
{
|
||||
struct e1000_hw *hw;
|
||||
|
||||
list_for_each_entry(hw, &e1000_hw_list, list_node)
|
||||
if (hw->cardnum == cardnum)
|
||||
return hw;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMD_E1000
|
||||
static int do_e1000(cmd_tbl_t *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
struct e1000_hw *hw;
|
||||
|
||||
if (argc < 3) {
|
||||
cmd_usage(cmdtp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Make sure we can find the requested e1000 card */
|
||||
hw = e1000_find_card(simple_strtoul(argv[1], NULL, 10));
|
||||
if (!hw) {
|
||||
printf("e1000: ERROR: No such device: e1000#%s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[2], "print-mac-address")) {
|
||||
unsigned char *mac = hw->nic->enetaddr;
|
||||
printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_E1000_SPI
|
||||
/* Handle the "SPI" subcommand */
|
||||
if (!strcmp(argv[2], "spi"))
|
||||
return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3);
|
||||
#endif
|
||||
|
||||
cmd_usage(cmdtp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
e1000, 7, 0, do_e1000,
|
||||
"Intel e1000 controller management",
|
||||
/* */"<card#> print-mac-address\n"
|
||||
#ifdef CONFIG_E1000_SPI
|
||||
"e1000 <card#> spi show [<offset> [<length>]]\n"
|
||||
"e1000 <card#> spi dump <addr> <offset> <length>\n"
|
||||
"e1000 <card#> spi program <addr> <offset> <length>\n"
|
||||
"e1000 <card#> spi checksum [update]\n"
|
||||
#endif
|
||||
" - Manage the Intel E1000 PCI device"
|
||||
);
|
||||
#endif /* not CONFIG_CMD_E1000 */
|
||||
|
Reference in New Issue
Block a user