netdev: bfin_mac: use promiscuous flag for promiscuous mode
[safe/jmp/linux-2.6] / drivers / net / macsonic.c
index 8f492c7..adb54fe 100644 (file)
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
+#include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/nubus.h>
@@ -50,6 +50,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/bitrev.h>
+#include <linux/slab.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -62,7 +63,6 @@
 #include <asm/mac_via.h>
 
 static char mac_sonic_string[] = "macsonic";
-static struct platform_device *mac_sonic_device;
 
 #include "sonic.h"
 
@@ -140,7 +140,7 @@ static irqreturn_t macsonic_interrupt(int irq, void *dev_id)
 
 static int macsonic_open(struct net_device* dev)
 {
-       if (request_irq(dev->irq, &sonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
+       if (request_irq(dev->irq, sonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
                printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
                return -EAGAIN;
        }
@@ -149,7 +149,7 @@ static int macsonic_open(struct net_device* dev)
         * rupt as well, which must prevent re-entrance of the sonic handler.
         */
        if (dev->irq == IRQ_AUTO_3)
-               if (request_irq(IRQ_NUBUS_9, &macsonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
+               if (request_irq(IRQ_NUBUS_9, macsonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) {
                        printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, IRQ_NUBUS_9);
                        free_irq(dev->irq, dev);
                        return -EAGAIN;
@@ -223,69 +223,73 @@ static int __devinit macsonic_init(struct net_device *dev)
        return 0;
 }
 
-static int __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev)
+#define INVALID_MAC(mac) (memcmp(mac, "\x08\x00\x07", 3) && \
+                          memcmp(mac, "\x00\xA0\x40", 3) && \
+                          memcmp(mac, "\x00\x80\x19", 3) && \
+                          memcmp(mac, "\x00\x05\x02", 3))
+
+static void __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev)
 {
        struct sonic_local *lp = netdev_priv(dev);
        const int prom_addr = ONBOARD_SONIC_PROM_BASE;
-       int i;
+       unsigned short val;
 
-       /* On NuBus boards we can sometimes look in the ROM resources.
-          No such luck for comm-slot/onboard. */
-       for(i = 0; i < 6; i++)
-               dev->dev_addr[i] = SONIC_READ_PROM(i);
+       /*
+        * On NuBus boards we can sometimes look in the ROM resources.
+        * No such luck for comm-slot/onboard.
+        * On the PowerBook 520, the PROM base address is a mystery.
+        */
+       if (hwreg_present((void *)prom_addr)) {
+               int i;
+
+               for (i = 0; i < 6; i++)
+                       dev->dev_addr[i] = SONIC_READ_PROM(i);
+               if (!INVALID_MAC(dev->dev_addr))
+                       return;
 
-       /* Most of the time, the address is bit-reversed.  The NetBSD
-          source has a rather long and detailed historical account of
-          why this is so. */
-       if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
-           memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
-           memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
-           memcmp(dev->dev_addr, "\x00\x05\x02", 3))
+               /*
+                * Most of the time, the address is bit-reversed. The NetBSD
+                * source has a rather long and detailed historical account of
+                * why this is so.
+                */
                bit_reverse_addr(dev->dev_addr);
-       else
-               return 0;
-
-       /* If we still have what seems to be a bogus address, we'll
-           look in the CAM.  The top entry should be ours. */
-       /* Danger! This only works if MacOS has already initialized
-           the card... */
-       if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
-           memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
-           memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
-           memcmp(dev->dev_addr, "\x00\x05\x02", 3))
-       {
-               unsigned short val;
-
-               printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n");
-
-               SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
-               SONIC_WRITE(SONIC_CEP, 15);
-
-               val = SONIC_READ(SONIC_CAP2);
-               dev->dev_addr[5] = val >> 8;
-               dev->dev_addr[4] = val & 0xff;
-               val = SONIC_READ(SONIC_CAP1);
-               dev->dev_addr[3] = val >> 8;
-               dev->dev_addr[2] = val & 0xff;
-               val = SONIC_READ(SONIC_CAP0);
-               dev->dev_addr[1] = val >> 8;
-               dev->dev_addr[0] = val & 0xff;
-
-               printk(KERN_INFO "HW Address from CAM 15: %pM\n",
-                      dev->dev_addr);
-       } else return 0;
-
-       if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
-           memcmp(dev->dev_addr, "\x00\xA0\x40", 3) &&
-           memcmp(dev->dev_addr, "\x00\x80\x19", 3) &&
-           memcmp(dev->dev_addr, "\x00\x05\x02", 3))
-       {
+               if (!INVALID_MAC(dev->dev_addr))
+                       return;
+
                /*
-                * Still nonsense ... messed up someplace!
+                * If we still have what seems to be a bogus address, we'll
+                * look in the CAM. The top entry should be ours.
                 */
-               printk(KERN_ERR "macsonic: ERROR (INVALID MAC)\n");
-               return -EIO;
-       } else return 0;
+               printk(KERN_WARNING "macsonic: MAC address in PROM seems "
+                                   "to be invalid, trying CAM\n");
+       } else {
+               printk(KERN_WARNING "macsonic: cannot read MAC address from "
+                                   "PROM, trying CAM\n");
+       }
+
+       /* This only works if MacOS has already initialized the card. */
+
+       SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
+       SONIC_WRITE(SONIC_CEP, 15);
+
+       val = SONIC_READ(SONIC_CAP2);
+       dev->dev_addr[5] = val >> 8;
+       dev->dev_addr[4] = val & 0xff;
+       val = SONIC_READ(SONIC_CAP1);
+       dev->dev_addr[3] = val >> 8;
+       dev->dev_addr[2] = val & 0xff;
+       val = SONIC_READ(SONIC_CAP0);
+       dev->dev_addr[1] = val >> 8;
+       dev->dev_addr[0] = val & 0xff;
+
+       if (!INVALID_MAC(dev->dev_addr))
+               return;
+
+       /* Still nonsense ... messed up someplace! */
+
+       printk(KERN_WARNING "macsonic: MAC address in CAM entry 15 "
+                           "seems invalid, will use a random MAC\n");
+       random_ether_addr(dev->dev_addr);
 }
 
 static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
@@ -402,8 +406,7 @@ static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
        SONIC_WRITE(SONIC_ISR, 0x7fff);
 
        /* Now look for the MAC address. */
-       if (mac_onboard_sonic_ethernet_addr(dev) != 0)
-               return -ENODEV;
+       mac_onboard_sonic_ethernet_addr(dev);
 
        /* Shared init code */
        return macsonic_init(dev);
@@ -575,6 +578,7 @@ static int __devinit mac_sonic_probe(struct platform_device *pdev)
        lp = netdev_priv(dev);
        lp->device = &pdev->dev;
        SET_NETDEV_DEV(dev, &pdev->dev);
+       platform_set_drvdata(pdev, dev);
 
        /* This will catch fatal stuff like -ENOMEM as well as success */
        err = mac_onboard_sonic_probe(dev);
@@ -603,6 +607,7 @@ out:
 MODULE_DESCRIPTION("Macintosh SONIC ethernet driver");
 module_param(sonic_debug, int, 0);
 MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
+MODULE_ALIAS("platform:macsonic");
 
 #include "sonic.c"
 
@@ -623,44 +628,19 @@ static struct platform_driver mac_sonic_driver = {
        .probe  = mac_sonic_probe,
        .remove = __devexit_p(mac_sonic_device_remove),
        .driver = {
-               .name = mac_sonic_string,
+               .name   = mac_sonic_string,
+               .owner  = THIS_MODULE,
        },
 };
 
 static int __init mac_sonic_init_module(void)
 {
-       int err;
-
-       if ((err = platform_driver_register(&mac_sonic_driver))) {
-               printk(KERN_ERR "Driver registration failed\n");
-               return err;
-       }
-
-       mac_sonic_device = platform_device_alloc(mac_sonic_string, 0);
-       if (!mac_sonic_device)
-               goto out_unregister;
-
-       if (platform_device_add(mac_sonic_device)) {
-               platform_device_put(mac_sonic_device);
-               mac_sonic_device = NULL;
-       }
-
-       return 0;
-
-out_unregister:
-       platform_driver_unregister(&mac_sonic_driver);
-
-       return -ENOMEM;
+       return platform_driver_register(&mac_sonic_driver);
 }
 
 static void __exit mac_sonic_cleanup_module(void)
 {
        platform_driver_unregister(&mac_sonic_driver);
-
-       if (mac_sonic_device) {
-               platform_device_unregister(mac_sonic_device);
-               mac_sonic_device = NULL;
-       }
 }
 
 module_init(mac_sonic_init_module);