ax88796: add 93cx6 eeprom support
[linux-3.10.git] / drivers / net / ax88796.c
index 90e0734e60375abe0325cc5cfd0c7a49e0b9c43f..9fe0517cf89319e70340d952fd189e8365400d4b 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/eeprom_93cx6.h>
 
 #include <net/ax88796.h>
 
@@ -582,6 +583,37 @@ static const struct ethtool_ops ax_ethtool_ops = {
        .get_link               = ax_get_link,
 };
 
+#ifdef CONFIG_AX88796_93CX6
+static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom)
+{
+       struct ei_device *ei_local = eeprom->data;
+       u8 reg = ei_inb(ei_local->mem + AX_MEMR);
+
+       eeprom->reg_data_in = reg & AX_MEMR_EEI;
+       eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */
+       eeprom->reg_data_clock = reg & AX_MEMR_EECLK;
+       eeprom->reg_chip_select = reg & AX_MEMR_EECS;
+}
+
+static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom)
+{
+       struct ei_device *ei_local = eeprom->data;
+       u8 reg = ei_inb(ei_local->mem + AX_MEMR);
+
+       reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS);
+
+       if (eeprom->reg_data_in)
+               reg |= AX_MEMR_EEI;
+       if (eeprom->reg_data_clock)
+               reg |= AX_MEMR_EECLK;
+       if (eeprom->reg_chip_select)
+               reg |= AX_MEMR_EECS;
+
+       ei_outb(reg, ei_local->mem + AX_MEMR);
+       udelay(10);
+}
+#endif
+
 /* setup code */
 
 static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
@@ -640,6 +672,23 @@ static int ax_init_dev(struct net_device *dev, int first_init)
                memcpy(dev->dev_addr,  SA_prom, 6);
        }
 
+#ifdef CONFIG_AX88796_93CX6
+       if (first_init && ax->plat->flags & AXFLG_HAS_93CX6) {
+               unsigned char mac_addr[6];
+               struct eeprom_93cx6 eeprom;
+
+               eeprom.data = ei_local;
+               eeprom.register_read = ax_eeprom_register_read;
+               eeprom.register_write = ax_eeprom_register_write;
+               eeprom.width = PCI_EEPROM_WIDTH_93C56;
+
+               eeprom_93cx6_multiread(&eeprom, 0,
+                                      (__le16 __force *)mac_addr,
+                                      sizeof(mac_addr) >> 1);
+
+               memcpy(dev->dev_addr,  mac_addr, 6);
+       }
+#endif
        if (ax->plat->wordlength == 2) {
                /* We must set the 8390 for word mode. */
                ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);