]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/ax88796.c
Merge git://git.infradead.org/battery-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / ax88796.c
index 1d882360b34da8ea6cd97488739656d6f9f13e09..7495a9ee8f4bff6dde5b7c7666398d35882059fd 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>
 
@@ -580,9 +581,39 @@ static const struct ethtool_ops ax_ethtool_ops = {
        .set_settings           = ax_set_settings,
        .nway_reset             = ax_nway_reset,
        .get_link               = ax_get_link,
-       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
+#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)
@@ -641,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);
@@ -819,11 +867,12 @@ static int ax_probe(struct platform_device *pdev)
        }
 
        ei_status.mem = ioremap(res->start, size);
-       dev->base_addr = (long)ei_status.mem;
+       dev->base_addr = (unsigned long)ei_status.mem;
 
        if (ei_status.mem == NULL) {
-               dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
-                       res->start, res->end);
+               dev_err(&pdev->dev, "Cannot ioremap area (%08llx,%08llx)\n",
+                       (unsigned long long)res->start,
+                       (unsigned long long)res->end);
 
                ret = -ENXIO;
                goto exit_req;
@@ -851,7 +900,7 @@ static int ax_probe(struct platform_device *pdev)
 
                ax->map2 = ioremap(res->start, size);
                if (ax->map2 == NULL) {
-                       dev_err(&pdev->dev, "cannot map reset register");
+                       dev_err(&pdev->dev, "cannot map reset register\n");
                        ret = -ENXIO;
                        goto exit_mem2;
                }