Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / net / sunhme.c
index 13fdcca..9f046ca 100644 (file)
@@ -13,9 +13,6 @@
  *     argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50
  */
 
-static char version[] =
-        "sunhme.c:v2.02 24/Aug/2003 David S. Miller (davem@redhat.com)\n";
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -36,9 +33,9 @@ static char version[] =
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/byteorder.h>
@@ -67,15 +64,24 @@ static char version[] =
 
 #include "sunhme.h"
 
+#define DRV_NAME       "sunhme"
+#define DRV_VERSION    "2.02"
+#define DRV_RELDATE    "8/24/03"
+#define DRV_AUTHOR     "David S. Miller (davem@redhat.com)"
+
+static char version[] =
+       DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
 
-#define DRV_NAME "sunhme"
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION("Sun HappyMealEthernet(HME) 10/100baseT ethernet driver");
+MODULE_LICENSE("GPL");
 
 static int macaddr[6];
 
 /* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
-MODULE_PARM(macaddr, "6i");
+module_param_array(macaddr, int, NULL, 0);
 MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
-MODULE_LICENSE("GPL");
 
 static struct happy_meal *root_happy_dev;
 
@@ -175,13 +181,13 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp)
 #define DEFAULT_IPG2       4 /* For all modes */
 #define DEFAULT_JAMSIZE    4 /* Toe jam */
 
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && defined(MODULE)
 /* This happy_pci_ids is declared __initdata because it is only used
    as an advisory to depmod.  If this is ported to the new PCI interface
    where it could be referenced at any time due to hot plugging,
    the __initdata reference should be removed. */
 
-struct pci_device_id happymeal_pci_ids[] = {
+static struct pci_device_id happymeal_pci_ids[] = {
        {
          .vendor       = PCI_VENDOR_ID_SUN,
          .device       = PCI_DEVICE_ID_SUN_HAPPYMEAL,
@@ -203,12 +209,12 @@ MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
  */
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
-static void sbus_hme_write32(unsigned long reg, u32 val)
+static void sbus_hme_write32(void __iomem *reg, u32 val)
 {
        sbus_writel(val, reg);
 }
 
-static u32 sbus_hme_read32(unsigned long reg)
+static u32 sbus_hme_read32(void __iomem *reg)
 {
        return sbus_readl(reg);
 }
@@ -232,12 +238,12 @@ static u32 sbus_hme_read_desc32(u32 *p)
        return *p;
 }
 
-static void pci_hme_write32(unsigned long reg, u32 val)
+static void pci_hme_write32(void __iomem *reg, u32 val)
 {
        writel(val, reg);
 }
 
-static u32 pci_hme_read32(unsigned long reg)
+static u32 pci_hme_read32(void __iomem *reg)
 {
        return readl(reg);
 }
@@ -354,7 +360,7 @@ do {        (__txd)->tx_addr = cpu_to_le32(__addr); \
 
 
 /* Oh yes, the MIF BitBang is mighty fun to program.  BitBucket is more like it. */
-static void BB_PUT_BIT(struct happy_meal *hp, unsigned long tregs, int bit)
+static void BB_PUT_BIT(struct happy_meal *hp, void __iomem *tregs, int bit)
 {
        hme_write32(hp, tregs + TCVR_BBDATA, bit);
        hme_write32(hp, tregs + TCVR_BBCLOCK, 0);
@@ -362,7 +368,7 @@ static void BB_PUT_BIT(struct happy_meal *hp, unsigned long tregs, int bit)
 }
 
 #if 0
-static u32 BB_GET_BIT(struct happy_meal *hp, unsigned long tregs, int internal)
+static u32 BB_GET_BIT(struct happy_meal *hp, void __iomem *tregs, int internal)
 {
        u32 ret;
 
@@ -378,7 +384,7 @@ static u32 BB_GET_BIT(struct happy_meal *hp, unsigned long tregs, int internal)
 }
 #endif
 
-static u32 BB_GET_BIT2(struct happy_meal *hp, unsigned long tregs, int internal)
+static u32 BB_GET_BIT2(struct happy_meal *hp, void __iomem *tregs, int internal)
 {
        u32 retval;
 
@@ -397,7 +403,7 @@ static u32 BB_GET_BIT2(struct happy_meal *hp, unsigned long tregs, int internal)
 #define TCVR_FAILURE      0x80000000     /* Impossible MIF read value */
 
 static int happy_meal_bb_read(struct happy_meal *hp,
-                             unsigned long tregs, int reg)
+                             void __iomem *tregs, int reg)
 {
        u32 tmp;
        int retval = 0;
@@ -443,7 +449,7 @@ static int happy_meal_bb_read(struct happy_meal *hp,
 }
 
 static void happy_meal_bb_write(struct happy_meal *hp,
-                               unsigned long tregs, int reg,
+                               void __iomem *tregs, int reg,
                                unsigned short value)
 {
        u32 tmp;
@@ -488,7 +494,7 @@ static void happy_meal_bb_write(struct happy_meal *hp,
 #define TCVR_READ_TRIES   16
 
 static int happy_meal_tcvr_read(struct happy_meal *hp,
-                               unsigned long tregs, int reg)
+                               void __iomem *tregs, int reg)
 {
        int tries = TCVR_READ_TRIES;
        int retval;
@@ -520,7 +526,7 @@ static int happy_meal_tcvr_read(struct happy_meal *hp,
 #define TCVR_WRITE_TRIES  16
 
 static void happy_meal_tcvr_write(struct happy_meal *hp,
-                                 unsigned long tregs, int reg,
+                                 void __iomem *tregs, int reg,
                                  unsigned short value)
 {
        int tries = TCVR_WRITE_TRIES;
@@ -579,7 +585,7 @@ static void happy_meal_tcvr_write(struct happy_meal *hp,
  * service routine, and the chip is reset, or the link is ifconfig'd down
  * and then back up, this entire process repeats itself all over again.
  */
-static int try_next_permutation(struct happy_meal *hp, unsigned long tregs)
+static int try_next_permutation(struct happy_meal *hp, void __iomem *tregs)
 {
        hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
 
@@ -603,7 +609,7 @@ static int try_next_permutation(struct happy_meal *hp, unsigned long tregs)
        return -1;
 }
 
-static void display_link_mode(struct happy_meal *hp, unsigned long tregs)
+static void display_link_mode(struct happy_meal *hp, void __iomem *tregs)
 {
        printk(KERN_INFO "%s: Link is up using ", hp->dev->name);
        if (hp->tcvr_type == external)
@@ -625,7 +631,7 @@ static void display_link_mode(struct happy_meal *hp, unsigned long tregs)
        }
 }
 
-static void display_forced_link_mode(struct happy_meal *hp, unsigned long tregs)
+static void display_forced_link_mode(struct happy_meal *hp, void __iomem *tregs)
 {
        printk(KERN_INFO "%s: Link has been forced up using ", hp->dev->name);
        if (hp->tcvr_type == external)
@@ -644,7 +650,7 @@ static void display_forced_link_mode(struct happy_meal *hp, unsigned long tregs)
                printk("Half Duplex.\n");
 }
 
-static int set_happy_link_modes(struct happy_meal *hp, unsigned long tregs)
+static int set_happy_link_modes(struct happy_meal *hp, void __iomem *tregs)
 {
        int full;
 
@@ -708,7 +714,7 @@ static int happy_meal_init(struct happy_meal *hp);
 
 static int is_lucent_phy(struct happy_meal *hp)
 {
-       unsigned long tregs = hp->tcvregs;
+       void __iomem *tregs = hp->tcvregs;
        unsigned short mr2, mr3;
        int ret = 0;
 
@@ -724,7 +730,7 @@ static int is_lucent_phy(struct happy_meal *hp)
 static void happy_meal_timer(unsigned long data)
 {
        struct happy_meal *hp = (struct happy_meal *) data;
-       unsigned long tregs = hp->tcvregs;
+       void __iomem *tregs = hp->tcvregs;
        int restart_timer = 0;
 
        spin_lock_irq(&hp->happy_lock);
@@ -905,7 +911,7 @@ out:
 #define RX_RESET_TRIES     32
 
 /* hp->happy_lock must be held */
-static void happy_meal_tx_reset(struct happy_meal *hp, unsigned long bregs)
+static void happy_meal_tx_reset(struct happy_meal *hp, void __iomem *bregs)
 {
        int tries = TX_RESET_TRIES;
 
@@ -925,7 +931,7 @@ static void happy_meal_tx_reset(struct happy_meal *hp, unsigned long bregs)
 }
 
 /* hp->happy_lock must be held */
-static void happy_meal_rx_reset(struct happy_meal *hp, unsigned long bregs)
+static void happy_meal_rx_reset(struct happy_meal *hp, void __iomem *bregs)
 {
        int tries = RX_RESET_TRIES;
 
@@ -947,7 +953,7 @@ static void happy_meal_rx_reset(struct happy_meal *hp, unsigned long bregs)
 #define STOP_TRIES         16
 
 /* hp->happy_lock must be held */
-static void happy_meal_stop(struct happy_meal *hp, unsigned long gregs)
+static void happy_meal_stop(struct happy_meal *hp, void __iomem *gregs)
 {
        int tries = STOP_TRIES;
 
@@ -967,7 +973,7 @@ static void happy_meal_stop(struct happy_meal *hp, unsigned long gregs)
 }
 
 /* hp->happy_lock must be held */
-static void happy_meal_get_counters(struct happy_meal *hp, unsigned long bregs)
+static void happy_meal_get_counters(struct happy_meal *hp, void __iomem *bregs)
 {
        struct net_device_stats *stats = &hp->net_stats;
 
@@ -990,7 +996,7 @@ static void happy_meal_get_counters(struct happy_meal *hp, unsigned long bregs)
 }
 
 /* hp->happy_lock must be held */
-static void happy_meal_poll_stop(struct happy_meal *hp, unsigned long tregs)
+static void happy_meal_poll_stop(struct happy_meal *hp, void __iomem *tregs)
 {
        ASD(("happy_meal_poll_stop: "));
 
@@ -1025,7 +1031,7 @@ static void happy_meal_poll_stop(struct happy_meal *hp, unsigned long tregs)
 #define TCVR_UNISOLATE_TRIES   32 /* Dis-isolation can take longer. */
 
 /* hp->happy_lock must be held */
-static int happy_meal_tcvr_reset(struct happy_meal *hp, unsigned long tregs)
+static int happy_meal_tcvr_reset(struct happy_meal *hp, void __iomem *tregs)
 {
        u32 tconfig;
        int result, tries = TCVR_RESET_TRIES;
@@ -1123,7 +1129,7 @@ static int happy_meal_tcvr_reset(struct happy_meal *hp, unsigned long tregs)
  *
  * hp->happy_lock must be held
  */
-static void happy_meal_transceiver_check(struct happy_meal *hp, unsigned long tregs)
+static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tregs)
 {
        unsigned long tconfig = hme_read32(hp, tregs + TCVR_CFG);
 
@@ -1318,7 +1324,7 @@ static void happy_meal_init_rings(struct happy_meal *hp)
 
 /* hp->happy_lock must be held */
 static void happy_meal_begin_auto_negotiation(struct happy_meal *hp,
-                                             unsigned long tregs,
+                                             void __iomem *tregs,
                                              struct ethtool_cmd *ep)
 {
        int timeout;
@@ -1443,11 +1449,11 @@ force_link:
 /* hp->happy_lock must be held */
 static int happy_meal_init(struct happy_meal *hp)
 {
-       unsigned long gregs        = hp->gregs;
-       unsigned long etxregs      = hp->etxregs;
-       unsigned long erxregs      = hp->erxregs;
-       unsigned long bregs        = hp->bigmacregs;
-       unsigned long tregs        = hp->tcvregs;
+       void __iomem *gregs        = hp->gregs;
+       void __iomem *etxregs      = hp->etxregs;
+       void __iomem *erxregs      = hp->erxregs;
+       void __iomem *bregs        = hp->bigmacregs;
+       void __iomem *tregs        = hp->tcvregs;
        u32 regtmp, rxcfg;
        unsigned char *e = &hp->dev->dev_addr[0];
 
@@ -1736,9 +1742,9 @@ static int happy_meal_init(struct happy_meal *hp)
 /* hp->happy_lock must be held */
 static void happy_meal_set_initial_advertisement(struct happy_meal *hp)
 {
-       unsigned long tregs     = hp->tcvregs;
-       unsigned long bregs     = hp->bigmacregs;
-       unsigned long gregs     = hp->gregs;
+       void __iomem *tregs     = hp->tcvregs;
+       void __iomem *bregs     = hp->bigmacregs;
+       void __iomem *gregs     = hp->gregs;
 
        happy_meal_stop(hp, gregs);
        hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
@@ -1910,7 +1916,7 @@ static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status)
 /* hp->happy_lock must be held */
 static void happy_meal_mif_interrupt(struct happy_meal *hp)
 {
-       unsigned long tregs = hp->tcvregs;
+       void __iomem *tregs = hp->tcvregs;
 
        printk(KERN_INFO "%s: Link status change.\n", hp->dev->name);
        hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
@@ -2390,7 +2396,7 @@ static struct net_device_stats *happy_meal_get_stats(struct net_device *dev)
 static void happy_meal_set_multicast(struct net_device *dev)
 {
        struct happy_meal *hp = dev->priv;
-       unsigned long bregs = hp->bigmacregs;
+       void __iomem *bregs = hp->bigmacregs;
        struct dev_mc_list *dmi = dev->mc_list;
        char *addrs;
        int i;
@@ -2948,12 +2954,12 @@ static int is_quattro_p(struct pci_dev *pdev)
 }
 
 /* Fetch MAC address from vital product data of PCI ROM. */
-static void find_eth_addr_in_vpd(void *rom_base, int len, int index, unsigned char *dev_addr)
+static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
 {
        int this_offset;
 
        for (this_offset = 0x20; this_offset < len; this_offset++) {
-               void *p = rom_base + this_offset;
+               void __iomem *p = rom_base + this_offset;
 
                if (readb(p + 0) != 0x90 ||
                    readb(p + 1) != 0x00 ||
@@ -2971,42 +2977,33 @@ static void find_eth_addr_in_vpd(void *rom_base, int len, int index, unsigned ch
 
                        for (i = 0; i < 6; i++)
                                dev_addr[i] = readb(p + i);
-                       break;
+                       return 1;
                }
                index--;
        }
+       return 0;
 }
 
 static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
 {
-       u32 rom_reg_orig;
-       void *p;
-       int index;
-
-       index = 0;
-       if (is_quattro_p(pdev))
-               index = PCI_SLOT(pdev->devfn);
-
-       if (pdev->resource[PCI_ROM_RESOURCE].parent == NULL) {
-               if (pci_assign_resource(pdev, PCI_ROM_RESOURCE) < 0)
-                       goto use_random;
-       }
-
-       pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_reg_orig);
-       pci_write_config_dword(pdev, pdev->rom_base_reg,
-                              rom_reg_orig | PCI_ROM_ADDRESS_ENABLE);
+       size_t size;
+       void __iomem *p = pci_map_rom(pdev, &size);
 
-       p = ioremap(pci_resource_start(pdev, PCI_ROM_RESOURCE), (64 * 1024));
-       if (p != NULL && readb(p) == 0x55 && readb(p + 1) == 0xaa)
-               find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
+       if (p) {
+               int index = 0;
+               int found;
 
-       if (p != NULL)
-               iounmap(p);
+               if (is_quattro_p(pdev))
+                       index = PCI_SLOT(pdev->devfn);
 
-       pci_write_config_dword(pdev, pdev->rom_base_reg, rom_reg_orig);
-       return;
+               found = readb(p) == 0x55 &&
+                       readb(p + 1) == 0xaa &&
+                       find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
+               pci_unmap_rom(pdev, p);
+               if (found)
+                       return;
+       }
 
-use_random:
        /* Sun MAC prefix then 3 random bytes. */
        dev_addr[0] = 0x08;
        dev_addr[1] = 0x00;
@@ -3025,7 +3022,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
 #endif
        struct happy_meal *hp;
        struct net_device *dev;
-       unsigned long hpreg_base;
+       void __iomem *hpreg_base;
+       unsigned long hpreg_res;
        int i, qfe_slot = -1;
        char prom_name[64];
        int err;
@@ -3084,7 +3082,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
                qp->happy_meals[qfe_slot] = dev;
        }               
 
-       hpreg_base = pci_resource_start(pdev, 0);
+       hpreg_res = pci_resource_start(pdev, 0);
        err = -ENODEV;
        if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
                printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n");
@@ -3096,7 +3094,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
                goto err_out_clear_quattro;
        }
 
-       if ((hpreg_base = (unsigned long) ioremap(hpreg_base, 0x8000)) == 0) {
+       if ((hpreg_base = ioremap(hpreg_res, 0x8000)) == 0) {
                printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n");
                goto err_out_free_res;
        }
@@ -3256,7 +3254,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
        return 0;
 
 err_out_iounmap:
-       iounmap((void *)hp->gregs);
+       iounmap(hp->gregs);
 
 err_out_free_res:
        pci_release_regions(pdev);
@@ -3389,7 +3387,7 @@ static void __exit happy_meal_cleanup_module(void)
                                            PAGE_SIZE,
                                            hp->happy_block,
                                            hp->hblock_dvma);
-                       iounmap((void *)hp->gregs);
+                       iounmap(hp->gregs);
                        pci_release_regions(hp->happy_dev);
                }
 #endif