ax88796: Add method to take MAC from platform data
[safe/jmp/linux-2.6] / drivers / net / ax88796.c
index 0b4adf4..62d9c9c 100644 (file)
@@ -37,7 +37,10 @@ static int phy_debug = 0;
 #define __ei_open       ax_ei_open
 #define __ei_close      ax_ei_close
 #define __ei_poll      ax_ei_poll
+#define __ei_start_xmit ax_ei_start_xmit
 #define __ei_tx_timeout ax_ei_tx_timeout
+#define __ei_get_stats  ax_ei_get_stats
+#define __ei_set_multicast_list ax_ei_set_multicast_list
 #define __ei_interrupt  ax_ei_interrupt
 #define ____alloc_ei_netdev ax__alloc_ei_netdev
 #define __NS8390_init   ax_NS8390_init
@@ -90,6 +93,7 @@ struct ax_device {
 
        unsigned char            running;
        unsigned char            resume_open;
+       unsigned int             irqflags;
 
        u32                      reg_offsets[0x20];
 };
@@ -153,7 +157,7 @@ static void ax_reset_8390(struct net_device *dev)
        while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
                if (jiffies - reset_start_time > 2*HZ/100) {
                        dev_warn(&ax->dev->dev, "%s: %s did not complete.\n",
-                              __FUNCTION__, dev->name);
+                              __func__, dev->name);
                        break;
                }
        }
@@ -173,7 +177,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
        if (ei_status.dmaing) {
                dev_err(&ax->dev->dev, "%s: DMAing conflict in %s "
                        "[DMAstat:%d][irqlock:%d].\n",
-                       dev->name, __FUNCTION__,
+                       dev->name, __func__,
                        ei_status.dmaing, ei_status.irqlock);
                return;
        }
@@ -215,7 +219,7 @@ static void ax_block_input(struct net_device *dev, int count,
                dev_err(&ax->dev->dev,
                        "%s: DMAing conflict in %s "
                        "[DMAstat:%d][irqlock:%d].\n",
-                       dev->name, __FUNCTION__,
+                       dev->name, __func__,
                        ei_status.dmaing, ei_status.irqlock);
                return;
        }
@@ -260,7 +264,7 @@ static void ax_block_output(struct net_device *dev, int count,
        if (ei_status.dmaing) {
                dev_err(&ax->dev->dev, "%s: DMAing conflict in %s."
                        "[DMAstat:%d][irqlock:%d]\n",
-                       dev->name, __FUNCTION__,
+                       dev->name, __func__,
                       ei_status.dmaing, ei_status.irqlock);
                return;
        }
@@ -396,7 +400,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
 {
        if (phy_debug)
                pr_debug("%s: dev %p, %04x, %04x, %d\n",
-                       __FUNCTION__, dev, phy_addr, reg, opc);
+                       __func__, dev, phy_addr, reg, opc);
 
        ax_mii_ei_outbits(dev, 0x3f, 6);        /* pre-amble */
        ax_mii_ei_outbits(dev, 1, 2);           /* frame-start */
@@ -422,7 +426,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg)
        spin_unlock_irqrestore(&ei_local->page_lock, flags);
 
        if (phy_debug)
-               pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
+               pr_debug("%s: %04x.%04x => read %04x\n", __func__,
                         phy_addr, reg, result);
 
        return result;
@@ -436,7 +440,7 @@ ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
        unsigned long flags;
 
        dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n",
-               __FUNCTION__, dev, phy_addr, reg, value);
+               __func__, dev, phy_addr, reg, value);
 
        spin_lock_irqsave(&ei->page_lock, flags);
 
@@ -471,7 +475,8 @@ static int ax_open(struct net_device *dev)
 
        dev_dbg(&ax->dev->dev, "%s: open\n", dev->name);
 
-       ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
+       ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+                         dev->name, dev);
        if (ret)
                return ret;
 
@@ -554,7 +559,7 @@ static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        spin_lock_irqsave(&ax->mii_lock, flags);
        mii_ethtool_gset(&ax->mii, cmd);
-       spin_lock_irqsave(&ax->mii_lock, flags);
+       spin_unlock_irqrestore(&ax->mii_lock, flags);
 
        return 0;
 }
@@ -567,7 +572,7 @@ static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        spin_lock_irqsave(&ax->mii_lock, flags);
        rc = mii_ethtool_sset(&ax->mii, cmd);
-       spin_lock_irqsave(&ax->mii_lock, flags);
+       spin_unlock_irqrestore(&ax->mii_lock, flags);
 
        return rc;
 }
@@ -623,6 +628,23 @@ static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom)
 }
 #endif
 
+static const struct net_device_ops ax_netdev_ops = {
+       .ndo_open               = ax_open,
+       .ndo_stop               = ax_close,
+       .ndo_do_ioctl           = ax_ioctl,
+
+       .ndo_start_xmit         = ax_ei_start_xmit,
+       .ndo_tx_timeout         = ax_ei_tx_timeout,
+       .ndo_get_stats          = ax_ei_get_stats,
+       .ndo_set_multicast_list = ax_ei_set_multicast_list,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_change_mtu         = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = ax_ei_poll,
+#endif
+};
+
 /* setup code */
 
 static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
@@ -711,12 +733,19 @@ static int ax_init_dev(struct net_device *dev, int first_init)
        /* load the mac-address from the device if this is the
         * first time we've initialised */
 
-       if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
-               ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
-                       ei_local->mem + E8390_CMD); /* 0x61 */
+       if (first_init) {
+               if (ax->plat->flags & AXFLG_MAC_FROMDEV) {
+                       ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+                               ei_local->mem + E8390_CMD); /* 0x61 */
+                       for (i = 0; i < ETHER_ADDR_LEN; i++)
+                               dev->dev_addr[i] =
+                                       ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+               }
 
-               for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
-                       dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+               if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) &&
+                    ax->plat->mac_addr)
+                       memcpy(dev->dev_addr, ax->plat->mac_addr,
+                               ETHER_ADDR_LEN);
        }
 
        ax_reset_8390(dev);
@@ -738,9 +767,7 @@ static int ax_init_dev(struct net_device *dev, int first_init)
        ei_status.get_8390_hdr  = &ax_get_8390_hdr;
        ei_status.priv = 0;
 
-       dev->open               = ax_open;
-       dev->stop               = ax_close;
-       dev->do_ioctl           = ax_ioctl;
+       dev->netdev_ops         = &ax_netdev_ops;
        dev->ethtool_ops        = &ax_ethtool_ops;
 
        ax->msg_enable          = NETIF_MSG_LINK;
@@ -753,18 +780,12 @@ static int ax_init_dev(struct net_device *dev, int first_init)
        ax->mii.mdio_write      = ax_phy_write;
        ax->mii.dev             = dev;
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = ax_ei_poll;
-#endif
        ax_NS8390_init(dev, 0);
 
-       if (first_init) {
-               DECLARE_MAC_BUF(mac);
-
-               dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %s\n",
+       if (first_init)
+               dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %pM\n",
                         ei_status.word16 ? 16:8, dev->irq, dev->base_addr,
-                        print_mac(mac, dev->dev_addr));
-       }
+                        dev->dev_addr);
 
        ret = register_netdev(dev);
        if (ret)
@@ -817,7 +838,7 @@ static int ax_probe(struct platform_device *pdev)
        struct ax_device  *ax;
        struct resource   *res;
        size_t size;
-       int ret;
+       int ret = 0;
 
        dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
        if (dev == NULL)
@@ -838,13 +859,15 @@ static int ax_probe(struct platform_device *pdev)
 
        /* find the platform resources */
 
-       dev->irq  = platform_get_irq(pdev, 0);
-       if (dev->irq < 0) {
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (res == NULL) {
                dev_err(&pdev->dev, "no IRQ specified\n");
-               ret = -ENXIO;
                goto exit_mem;
        }
 
+       dev->irq = res->start;
+       ax->irqflags = res->flags & IRQF_TRIGGER_MASK;
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res == NULL) {
                dev_err(&pdev->dev, "no MEM specified\n");