static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
-#define E1000_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + E1000_##reg)))
-#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_##reg))
-#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) (\
- writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))))
-#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
- readl((a)->hw_addr + E1000_##reg + ((offset) << 2)))
-#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
-
-#ifndef CONFIG_AP1000 /* remove for warnings */
+
static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
uint16_t words,
uint16_t *data);
* hw - Struct containing variables accessed by shared code
* eecd - EECD's current value
*****************************************************************************/
-static void
-e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
+void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
{
/* Raise the clock input to the EEPROM (by setting the SK bit), and then
* wait 50 microseconds.
* hw - Struct containing variables accessed by shared code
* eecd - EECD's current value
*****************************************************************************/
-static void
-e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
+void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t * eecd)
{
/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
* wait 50 microseconds.
*
* hw - Struct containing variables accessed by shared code
*****************************************************************************/
-static void
-e1000_standby_eeprom(struct e1000_hw *hw)
+void e1000_standby_eeprom(struct e1000_hw *hw)
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd;
* Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
* function should be called before issuing a command to the EEPROM.
*****************************************************************************/
-static int32_t
-e1000_acquire_eeprom(struct e1000_hw *hw)
+int32_t e1000_acquire_eeprom(struct e1000_hw *hw)
{
struct e1000_eeprom_info *eeprom = &hw->eeprom;
uint32_t eecd, i = 0;
return error;
}
-static void
-e1000_release_eeprom(struct e1000_hw *hw)
+void e1000_release_eeprom(struct e1000_hw *hw)
{
uint32_t eecd;
* If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
* valid.
*****************************************************************************/
-static int
-e1000_validate_eeprom_checksum(struct eth_device *nic)
+static int e1000_validate_eeprom_checksum(struct e1000_hw *hw)
{
- struct e1000_hw *hw = nic->priv;
- uint16_t checksum = 0;
- uint16_t i, eeprom_data;
+ uint16_t i, checksum, checksum_reg, *buf;
DEBUGFUNC();
- for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
- if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
+ /* Allocate a temporary buffer */
+ buf = malloc(sizeof(buf[0]) * (EEPROM_CHECKSUM_REG + 1));
+ if (!buf) {
+ E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n");
+ return -E1000_ERR_EEPROM;
}
- if (checksum == (uint16_t) EEPROM_SUM) {
- return 0;
- } else {
- DEBUGOUT("EEPROM Checksum Invalid\n");
+ /* Read the EEPROM */
+ if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) {
+ E1000_ERR(hw->nic, "Unable to read EEPROM!\n");
return -E1000_ERR_EEPROM;
}
+
+ /* Compute the checksum */
+ checksum = 0;
+ for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+ checksum += buf[i];
+ checksum = ((uint16_t)EEPROM_SUM) - checksum;
+ checksum_reg = buf[i];
+
+ /* Verify it! */
+ if (checksum == checksum_reg)
+ 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);
+
+ return -E1000_ERR_EEPROM;
}
/*****************************************************************************
return E1000_SUCCESS;
}
-#endif /* #ifndef CONFIG_AP1000 */
/***************************************************************************
*
static int
e1000_read_mac_addr(struct eth_device *nic)
{
-#ifndef CONFIG_AP1000
struct e1000_hw *hw = nic->priv;
uint16_t offset;
uint16_t eeprom_data;
nic->enetaddr[5] ^= 1;
#ifdef CONFIG_E1000_FALLBACK_MAC
- if ( *(u32*)(nic->enetaddr) == 0 || *(u32*)(nic->enetaddr) == ~0 ) {
+ if (!is_valid_ether_addr(nic->enetaddr)) {
unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC;
memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE);
}
-#endif
-#else
- /*
- * The AP1000's e1000 has no eeprom; the MAC address is stored in the
- * environment variables. Currently this does not support the addition
- * of a PMC e1000 card, which is certainly a possibility, so this should
- * be updated to properly use the env variable only for the onboard e1000
- */
-
- int ii;
- char *s, *e;
-
- DEBUGFUNC();
-
- s = getenv ("ethaddr");
- if (s == NULL) {
- return -E1000_ERR_EEPROM;
- } else {
- for(ii = 0; ii < 6; ii++) {
- nic->enetaddr[ii] = s ? simple_strtoul (s, &e, 16) : 0;
- if (s){
- s = (*e) ? e + 1 : e;
- }
- }
- }
#endif
return 0;
}
{
uint32_t ctrl;
uint32_t ctrl_ext;
- uint32_t icr;
uint32_t manc;
uint32_t pba = 0;
E1000_WRITE_REG(hw, IMC, 0xffffffff);
/* Clear any pending interrupt events. */
- icr = E1000_READ_REG(hw, ICR);
+ E1000_READ_REG(hw, ICR);
/* If MWI was previously enabled, reenable it. */
if (hw->mac_type == e1000_82542_rev2_0) {
if (e1000_check_phy_reset_block(hw))
return E1000_SUCCESS;
-#ifndef CONFIG_AP1000
/* Read and store word 0x0F of the EEPROM. This word contains bits
* that determine the hardware's default PAUSE (flow control) mode,
* a bit that determines whether the HW defaults to enabling or
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
-#else
- /* we have to hardcode the proper value for our hardware. */
- /* this value is for the 82540EM pci card used for prototyping, and it works. */
- eeprom_data = 0xb220;
-#endif
if (hw->fc == e1000_fc_default) {
switch (hw->mac_type) {
hw->fc = e1000_fc_full;
break;
default:
-#ifndef CONFIG_AP1000
ret_val = e1000_read_eeprom(hw,
EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
if (ret_val) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
-#else
- eeprom_data = 0xb220;
-#endif
if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
hw->fc = e1000_fc_none;
else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
}
DEBUGOUT("Phy ID = %x \n", hw->phy_id);
-#ifndef CONFIG_AP1000
/* Set PHY to class A mode (if necessary) */
ret_val = e1000_set_phy_mode(hw);
if (ret_val)
return ret_val;
-#endif
if ((hw->mac_type == e1000_82545_rev_3) ||
(hw->mac_type == e1000_82546_rev_3)) {
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
mdelay(20);
/* Now enable the transmitter */
- e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
+ if (!ret_val)
+ e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
if (hw->mac_type == e1000_82547) {
uint16_t fused, fine, coarse;
/**************************************************************************
TRANSMIT - Transmit a frame
***************************************************************************/
-static int
-e1000_transmit(struct eth_device *nic, volatile void *packet, int length)
+static int e1000_transmit(struct eth_device *nic, void *packet, int length)
{
- void * nv_packet = (void *)packet;
+ void *nv_packet = (void *)packet;
struct e1000_hw *hw = nic->priv;
struct e1000_tx_desc *txp;
int i = 0;
}
}
+/* 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
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))
+#if !defined(CONFIG_MVBC_1G)
if (e1000_init_eeprom_params(hw)) {
E1000_ERR(nic, "EEPROM is invalid!\n");
continue;
}
- if (e1000_validate_eeprom_checksum(nic) < 0) {
- E1000_ERR(nic, "EEPROM checksum is bad!\n");
+ if (e1000_validate_eeprom_checksum(hw))
continue;
- }
#endif
e1000_read_mac_addr(nic);
e1000_get_bus_type(hw);
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 */