diff options
author | Noe Rubinstein <nrubinstein@avencall.com> | 2012-09-17 12:08:50 +0200 |
---|---|---|
committer | Noe Rubinstein <nrubinstein@avencall.com> | 2012-09-17 12:08:50 +0200 |
commit | 21dda137d7ad803b37b5b601bc2338527c7167ff (patch) | |
tree | f3f1ee76e96543e71b6f0660586de6d8284f2921 | |
parent | 94eebcd5c08df282a5a5fde697698bed934e59ef (diff) |
XIOH MAC addresses support in CBFS working
-rw-r--r-- | src/drivers/net/e1000/e1000_ep80579.c | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/src/drivers/net/e1000/e1000_ep80579.c b/src/drivers/net/e1000/e1000_ep80579.c index 01b6d677..bc4d877e 100644 --- a/src/drivers/net/e1000/e1000_ep80579.c +++ b/src/drivers/net/e1000/e1000_ep80579.c @@ -517,27 +517,101 @@ static void e1000_clear_hw_cntrs_ep80579(struct e1000_hw *hw) } #define XIOH_MAC_OFFSET 0xfff00000 +static const u8 xioh_magic[] = {'X','I','O','H'}; + +typedef uint8_t mac_t[6]; + +struct serial { + uint16_t date; + unsigned version:4; + unsigned number:12; +} __attribute__((__packed__)); + +struct xioh_data { + u8 magic[4]; + uint16_t version; + uint8_t cksum; + uint8_t reserved; + struct serial serial; + mac_t addr[3]; +} __attribute__((__packed__)); + +static void print_mac_be(mac_t mac) +{ + DBG("%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); +} + +static void dump_xioh_data(struct xioh_data *xioh_data) +{ + int i; + + DBG("Magic: %c%c%c%c\n" + "Version: %x\n" + "Checksum: %x\n" + "Serial:\n" + "\tDate: %04x\n" + "\tHardware version: %x\n" + "\tNumber: %x\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); + + DBG("MAC addresses:\n"); + for (i = 0; i < 3; i++) { + DBG("\t"); + print_mac_be(xioh_data->addr[i]); + DBG("\n"); + } +} + +static u8 xor_cksum(const u8 *addr, size_t sz) +{ + u8 r = 0; + for (; sz; sz--) { + r ^= *addr++; + DBG("sz=%x, r=%x\n", sz, r); + } + return r; +} s32 e1000_xioh_read_mac_addr(struct e1000_hw *hw) { - static const u8 xioh_mac_magic[] = {'X','I','O','H', 0x00, 0x00}; unsigned i; - u8 *mac; + struct xioh_data *xioh_data; DBGF; - mac = ioremap(XIOH_MAC_OFFSET, 24); - - for (i = 0; i < ARRAY_SIZE(xioh_mac_magic); i++) - if (xioh_mac_magic[i] != mac[i]) + xioh_data = ioremap(XIOH_MAC_OFFSET, sizeof(struct xioh_data)); + for (i = 0; i < ARRAY_SIZE(xioh_magic); i++) + if (xioh_magic[i] != xioh_data->magic[i]) { + DBG("No XIOH magic in memory\n"); return -E1000_ERR_NVM; + } - for (i = 0; i < ETH_ALEN; i++) - hw->mac.perm_addr[i] = - mac[ARRAY_SIZE(xioh_mac_magic) + - ETH_ALEN * hw->dev_spec.ep80579.device_number + i]; + switch (xioh_data->version) { + case 0: + for (i = 0; i < 6; i++) + hw->mac.perm_addr[i] = ((u8*)xioh_data) + [6+6*hw->dev_spec.ep80579.device_number+i]; + break; + case 2: + dump_xioh_data(xioh_data); + if (xor_cksum((u8*)xioh_data, sizeof(*xioh_data))) { + DBG("Bad checksum!\n"); + return -E1000_ERR_NVM; + } + /* fallthrough */ + case 1: + for (i = 0; i < 6; i++) + hw->mac.perm_addr[i] = xioh_data->addr + [hw->dev_spec.ep80579.device_number][i]; + break; + } - iounmap(mac); + iounmap(xioh_data); for (i = 0; i < ETH_ALEN; i++) hw->mac.addr[i] = hw->mac.perm_addr[i]; |