]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/ax88796.c
net drivers: fix platform driver hotplug/coldplug
[linux-2.6-omap-h63xx.git] / drivers / net / ax88796.c
index 83da1770bafb6cde94eb3bda73b97e2118996fae..0b4adf4a0f7da9ab772ca84bc1d4738ca034c263 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>
 
@@ -136,11 +137,12 @@ static int ax_initial_check(struct net_device *dev)
 static void ax_reset_8390(struct net_device *dev)
 {
        struct ei_device *ei_local = netdev_priv(dev);
+       struct ax_device  *ax = to_ax_dev(dev);
        unsigned long reset_start_time = jiffies;
        void __iomem *addr = (void __iomem *)dev->base_addr;
 
        if (ei_debug > 1)
-               printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
+               dev_dbg(&ax->dev->dev, "resetting the 8390 t=%ld\n", jiffies);
 
        ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
 
@@ -150,7 +152,7 @@ static void ax_reset_8390(struct net_device *dev)
        /* This check _should_not_ be necessary, omit eventually. */
        while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
                if (jiffies - reset_start_time > 2*HZ/100) {
-                       printk(KERN_WARNING "%s: %s did not complete.\n",
+                       dev_warn(&ax->dev->dev, "%s: %s did not complete.\n",
                               __FUNCTION__, dev->name);
                        break;
                }
@@ -164,13 +166,15 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
                            int ring_page)
 {
        struct ei_device *ei_local = netdev_priv(dev);
+       struct ax_device  *ax = to_ax_dev(dev);
        void __iomem *nic_base = ei_local->mem;
 
        /* This *shouldn't* happen. If it does, it's the last thing you'll see */
        if (ei_status.dmaing) {
-               printk(KERN_EMERG "%s: DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n",
+               dev_err(&ax->dev->dev, "%s: DMAing conflict in %s "
+                       "[DMAstat:%d][irqlock:%d].\n",
                        dev->name, __FUNCTION__,
-                      ei_status.dmaing, ei_status.irqlock);
+                       ei_status.dmaing, ei_status.irqlock);
                return;
        }
 
@@ -203,13 +207,16 @@ static void ax_block_input(struct net_device *dev, int count,
                           struct sk_buff *skb, int ring_offset)
 {
        struct ei_device *ei_local = netdev_priv(dev);
+       struct ax_device  *ax = to_ax_dev(dev);
        void __iomem *nic_base = ei_local->mem;
        char *buf = skb->data;
 
        if (ei_status.dmaing) {
-               printk(KERN_EMERG "%s: DMAing conflict in ax_block_input "
+               dev_err(&ax->dev->dev,
+                       "%s: DMAing conflict in %s "
                        "[DMAstat:%d][irqlock:%d].\n",
-                       dev->name, ei_status.dmaing, ei_status.irqlock);
+                       dev->name, __FUNCTION__,
+                       ei_status.dmaing, ei_status.irqlock);
                return;
        }
 
@@ -238,6 +245,7 @@ static void ax_block_output(struct net_device *dev, int count,
                            const unsigned char *buf, const int start_page)
 {
        struct ei_device *ei_local = netdev_priv(dev);
+       struct ax_device  *ax = to_ax_dev(dev);
        void __iomem *nic_base = ei_local->mem;
        unsigned long dma_start;
 
@@ -250,7 +258,7 @@ static void ax_block_output(struct net_device *dev, int count,
 
        /* This *shouldn't* happen. If it does, it's the last thing you'll see */
        if (ei_status.dmaing) {
-               printk(KERN_EMERG "%s: DMAing conflict in %s."
+               dev_err(&ax->dev->dev, "%s: DMAing conflict in %s."
                        "[DMAstat:%d][irqlock:%d]\n",
                        dev->name, __FUNCTION__,
                       ei_status.dmaing, ei_status.irqlock);
@@ -280,7 +288,8 @@ static void ax_block_output(struct net_device *dev, int count,
 
        while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
                if (jiffies - dma_start > 2*HZ/100) {           /* 20ms */
-                       printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
+                       dev_warn(&ax->dev->dev,
+                                "%s: timeout waiting for Tx RDC.\n", dev->name);
                        ax_reset_8390(dev);
                        ax_NS8390_init(dev,1);
                        break;
@@ -423,10 +432,11 @@ static void
 ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
 {
        struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
+       struct ax_device  *ax = to_ax_dev(dev);
        unsigned long flags;
 
-       printk(KERN_DEBUG "%s: %p, %04x, %04x %04x\n",
-              __FUNCTION__, dev, phy_addr, reg, value);
+       dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n",
+               __FUNCTION__, dev, phy_addr, reg, value);
 
        spin_lock_irqsave(&ei->page_lock, flags);
 
@@ -582,6 +592,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 +681,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);
@@ -701,14 +759,11 @@ static int ax_init_dev(struct net_device *dev, int first_init)
        ax_NS8390_init(dev, 0);
 
        if (first_init) {
-               printk("AX88796: %dbit, irq %d, %lx, MAC: ",
-                      ei_status.word16 ? 16:8, dev->irq, dev->base_addr);
-
-               for (i = 0; i < ETHER_ADDR_LEN; i++)
-                       printk("%2.2x%c", dev->dev_addr[i],
-                              (i < (ETHER_ADDR_LEN-1) ? ':' : ' '));
+               DECLARE_MAC_BUF(mac);
 
-               printk("\n");
+               dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %s\n",
+                        ei_status.word16 ? 16:8, dev->irq, dev->base_addr,
+                        print_mac(mac, dev->dev_addr));
        }
 
        ret = register_netdev(dev);
@@ -821,8 +876,9 @@ static int ax_probe(struct platform_device *pdev)
        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;
@@ -850,7 +906,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;
                }
@@ -949,3 +1005,4 @@ module_exit(axdrv_exit);
 MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:ax88796");