diff options
author | Noe Rubinstein <nrubinstein@avencall.com> | 2012-08-17 12:19:44 +0200 |
---|---|---|
committer | Noe Rubinstein <nrubinstein@avencall.com> | 2012-08-17 12:20:33 +0200 |
commit | 5cec356dd881d3c0ad65a834611323030a7bded1 (patch) | |
tree | 920cb3700b44c6995590bc2f928f0d0c56d232e2 | |
parent | 5e65f1e1423cf086a2734e4170c415c5a7c1f96d (diff) |
XIOH data version 2 w/ cksums
-rw-r--r-- | e1000_hw.c | 60 | ||||
-rw-r--r-- | e1000_hw.h | 3 | ||||
-rw-r--r-- | e1000_main.c | 5 |
3 files changed, 59 insertions, 9 deletions
@@ -4292,7 +4292,8 @@ struct serial { struct xioh_data { u8 magic[4]; uint16_t version; - uint16_t reserved; + uint8_t cksum; + uint8_t reserved; struct serial serial; union mac addr[3]; } __packed; @@ -4310,11 +4311,46 @@ static int devnum(struct e1000_hw *hw) return -1; } +void print_mac_be(union mac mac) +{ + printk("%02x:%02x:%02x:%02x:%02x:%02x", + mac.b[0], mac.b[1], mac.b[2], + mac.b[3], mac.b[4], mac.b[5]); +} + +void dump_xioh_data(struct xioh_data *xioh_data) +{ + int i; + + printk(KERN_DEBUG "Magic: %c%c%c%c\n" + "Version: %u\n" + "Checksum: %02x\n" + "Serial:\n" + "\tDate: %04x\n" + "\tHardware version: %u\n" + "\tNumber: %u\n", + xioh_data->magic[0], xioh_data->magic[1], + xioh_data->magic[2], xioh_data->magic[3], + xioh_data->version, + xioh_data->cksum, + xioh_data->serial.date, + xioh_data->serial.version, xioh_data->serial.number); + + printk(KERN_DEBUG "MAC addresses:\n"); + for (i = 0; i < 3; i++) { + printk(KERN_DEBUG "\t"); + print_mac_be(xioh_data->addr[i]); + printk("\n"); + } +} + + static u8 xor_cksum(const u8 *addr, size_t sz) { - u8 r; + u8 r = 0; for (; sz; sz--) r ^= *addr++; + return r; } @@ -4325,18 +4361,27 @@ s32 e1000_xioh_read_mac_addr(struct e1000_hw *hw) struct xioh_data *xioh_data; xioh_data = ioremap(XIOH_MAC_OFFSET, sizeof(struct xioh_data)); + + dump_xioh_data(xioh_data); + for (i = 0; i < ARRAY_SIZE(xioh_magic); i++) - if (xioh_magic[i] != xioh_data->magic[i]) + if (xioh_magic[i] != xioh_data->magic[i]) { + printk(KERN_DEBUG "Wrong magic number for XIOH\n"); return -E1000_ERR_EEPROM; + } switch (xioh_data->version) { + u8 cks; case 0: for (i = 0; i < 6; i++) hw->perm_mac_addr[i] = ((u8*)xioh_data)[6+6*num+i]; break; case 2: - if (xor_cksum((u8*)xioh_data, sizeof(xioh_data))) + if ((cks = xor_cksum((u8*)xioh_data, sizeof(*xioh_data)))) { + printk(KERN_ERR + "Wrong checksum %02x for XIOH data!\n", cks); return -E1000_ERR_EEPROM; + } /* fallthrough */ case 1: for (i = 0; i < 6; i++) @@ -4345,14 +4390,15 @@ s32 e1000_xioh_read_mac_addr(struct e1000_hw *hw) } if (xioh_data->version != 2) - printk(KERN_WARNING "e1000: Using an old storage scheme for " - "XIOH data. You should upgrade your boot " - "firmware!\n"); + printk(KERN_WARNING + "Using an old storage scheme for XIOH data. " + "You should upgrade your boot firmware.\n"); iounmap(xioh_data); for (i = 0; i < NODE_ADDRESS_SIZE; i++) hw->mac_addr[i] = hw->perm_mac_addr[i]; + return E1000_SUCCESS; } @@ -375,6 +375,9 @@ s32 e1000_validate_eeprom_checksum(struct e1000_hw *hw); s32 e1000_update_eeprom_checksum(struct e1000_hw *hw); s32 e1000_write_eeprom(struct e1000_hw *hw, u16 reg, u16 words, u16 * data); s32 e1000_read_mac_addr(struct e1000_hw *hw); +#ifdef XIOH +s32 e1000_xioh_read_mac_addr(struct e1000_hw *hw); +#endif /* Filters (multicast, vlan, receive) */ u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 * mc_addr); diff --git a/e1000_main.c b/e1000_main.c index 30163c3..ce8d305 100644 --- a/e1000_main.c +++ b/e1000_main.c @@ -970,7 +970,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, while (!(er32(EERD) & E1000_EERD_DONE)); if (er32(EERD) >> (E1000_EERD_DATA_SHIFT + 14) != 1) { DPRINTK(PROBE, DEBUG, "No EEPROM, trying to find XIOH signature in CBFS..."); - if (e1000_read_mac_addr(hw)) { + if (e1000_xioh_read_mac_addr(hw)) { DPRINTK(PROBE, ERR, "No valid data in CBFS!\n"); printk(KERN_ERR "The MAC Address will be " "reset to 00:00:00:00:00:00, " @@ -981,7 +981,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, "to enable this network device.\n"); memset(hw->mac_addr, 0, netdev->addr_len); } - } + } else printk(KERN_ERR "There IS an EEPROM!?\n"); + } #else /* make sure the EEPROM is good */ |