summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@avencall.com>2012-09-17 12:08:50 +0200
committerNoe Rubinstein <nrubinstein@avencall.com>2012-09-17 12:08:50 +0200
commit21dda137d7ad803b37b5b601bc2338527c7167ff (patch)
treef3f1ee76e96543e71b6f0660586de6d8284f2921
parent94eebcd5c08df282a5a5fde697698bed934e59ef (diff)
XIOH MAC addresses support in CBFS working
-rw-r--r--src/drivers/net/e1000/e1000_ep80579.c96
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];