drivers/usb/net/kaweth.c: add device "Allied Telesyn AT-USB10 USB Ethernet Adapter"
[safe/jmp/linux-2.6] / drivers / net / ax88796.c
index a886a4b..b718dc6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/eeprom_93cx6.h>
+#include <linux/slab.h>
 
 #include <net/ax88796.h>
 
@@ -37,7 +38,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 +94,7 @@ struct ax_device {
 
        unsigned char            running;
        unsigned char            resume_open;
+       unsigned int             irqflags;
 
        u32                      reg_offsets[0x20];
 };
@@ -153,7 +158,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 +178,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 +220,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 +265,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 +401,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 +427,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 +441,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 +476,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;
 
@@ -623,6 +629,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 +734,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 +768,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 +781,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 +839,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 +860,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");
@@ -898,7 +922,7 @@ static int ax_probe(struct platform_device *pdev)
                size = (res->end - res->start) + 1;
 
                ax->mem2 = request_mem_region(res->start, size, pdev->name);
-               if (ax->mem == NULL) {
+               if (ax->mem2 == NULL) {
                        dev_err(&pdev->dev, "cannot reserve registers\n");
                        ret = -ENXIO;
                        goto exit_mem1;