]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/ixp2000/ixpdev.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
[linux-2.6-omap-h63xx.git] / drivers / net / ixp2000 / ixpdev.c
index 216aad1911e6139eb31fe62e7e7b235d9644c067..fbc2d21020f4ee9ac2cca49a5b3b3d7764a9a9fe 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
-#include <asm/arch/uengine.h>
+#include <asm/hardware/uengine.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
 #include "ixp2400_rx.ucode"
@@ -24,6 +24,8 @@
 #include "ixpdev_priv.h"
 #include "ixpdev.h"
 
+#define DRV_MODULE_VERSION     "0.2"
+
 static int nds_count;
 static struct net_device **nds;
 static int nds_open;
@@ -147,12 +149,6 @@ static int ixpdev_poll(struct net_device *dev, int *budget)
        return 0;
 }
 
-/* @@@ Ugly hack.  */
-static inline int netif_rx_schedule_prep_notup(struct net_device *dev)
-{
-       return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
-}
-
 static void ixpdev_tx_complete(void)
 {
        int channel;
@@ -206,7 +202,7 @@ static irqreturn_t ixpdev_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         */
        if (status & 0x00ff) {
                ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
-               if (likely(netif_rx_schedule_prep_notup(nds[0]))) {
+               if (likely(__netif_rx_schedule_prep(nds[0]))) {
                        __netif_rx_schedule(nds[0]);
                } else {
                        printk(KERN_CRIT "ixp2000: irq while polling!!\n");
@@ -224,6 +220,15 @@ static irqreturn_t ixpdev_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ixpdev_poll_controller(struct net_device *dev)
+{
+       disable_irq(IRQ_IXP2000_THDA0);
+       ixpdev_interrupt(IRQ_IXP2000_THDA0, dev, NULL);
+       enable_irq(IRQ_IXP2000_THDA0);
+}
+#endif
+
 static int ixpdev_open(struct net_device *dev)
 {
        struct ixpdev_priv *ip = netdev_priv(dev);
@@ -274,6 +279,9 @@ struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
        dev->poll = ixpdev_poll;
        dev->open = ixpdev_open;
        dev->stop = ixpdev_close;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = ixpdev_poll_controller;
+#endif
 
        dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
        dev->weight = 64;
@@ -291,24 +299,14 @@ int ixpdev_init(int __nds_count, struct net_device **__nds,
        int i;
        int err;
 
-       if (RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192) {
-               static void __too_many_rx_or_tx_buffers(void);
-               __too_many_rx_or_tx_buffers();
-       }
+       BUILD_BUG_ON(RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192);
+
+       printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION);
 
        nds_count = __nds_count;
        nds = __nds;
        set_port_admin_status = __set_port_admin_status;
 
-       for (i = 0; i < nds_count; i++) {
-               err = register_netdev(nds[i]);
-               if (err) {
-                       while (--i >= 0)
-                               unregister_netdev(nds[i]);
-                       goto err_out;
-               }
-       }
-
        for (i = 0; i < RX_BUF_COUNT; i++) {
                void *buf;
 
@@ -317,7 +315,7 @@ int ixpdev_init(int __nds_count, struct net_device **__nds,
                        err = -ENOMEM;
                        while (--i >= 0)
                                free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
-                       goto err_unregister;
+                       goto err_out;
                }
                rx_desc[i].buf_addr = virt_to_phys(buf);
                rx_desc[i].buf_length = PAGE_SIZE;
@@ -355,7 +353,6 @@ int ixpdev_init(int __nds_count, struct net_device **__nds,
        ixp2000_uengine_load(0, &ixp2400_rx);
        ixp2000_uengine_start_contexts(0, 0xff);
 
-
        /* 256 entries, ring status set means 'empty', base address 0x0800.  */
        ixp2000_reg_write(RING_TX_PENDING_BASE, 0x44000800);
        ixp2000_reg_write(RING_TX_PENDING_HEAD, 0x00000000);
@@ -369,16 +366,33 @@ int ixpdev_init(int __nds_count, struct net_device **__nds,
        ixp2000_uengine_load(1, &ixp2400_tx);
        ixp2000_uengine_start_contexts(1, 0xff);
 
+       for (i = 0; i < nds_count; i++) {
+               err = register_netdev(nds[i]);
+               if (err) {
+                       while (--i >= 0)
+                               unregister_netdev(nds[i]);
+                       goto err_free_tx;
+               }
+       }
+
+       for (i = 0; i < nds_count; i++) {
+               printk(KERN_INFO "%s: IXP2000 MSF ethernet (port %d), "
+                       "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", nds[i]->name, i,
+                       nds[i]->dev_addr[0], nds[i]->dev_addr[1],
+                       nds[i]->dev_addr[2], nds[i]->dev_addr[3],
+                       nds[i]->dev_addr[4], nds[i]->dev_addr[5]);
+       }
+
        return 0;
 
+err_free_tx:
+       for (i = 0; i < TX_BUF_COUNT; i++)
+               free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+
 err_free_rx:
        for (i = 0; i < RX_BUF_COUNT; i++)
                free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
 
-err_unregister:
-       for (i = 0; i < nds_count; i++)
-               unregister_netdev(nds[i]);
-
 err_out:
        return err;
 } 
@@ -389,6 +403,9 @@ void ixpdev_deinit(void)
 
        /* @@@ Flush out pending packets.  */
 
+       for (i = 0; i < nds_count; i++)
+               unregister_netdev(nds[i]);
+
        ixp2000_uengine_stop_contexts(1, 0xff);
        ixp2000_uengine_stop_contexts(0, 0xff);
        ixp2000_uengine_reset(0x3);
@@ -398,7 +415,4 @@ void ixpdev_deinit(void)
 
        for (i = 0; i < RX_BUF_COUNT; i++)
                free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
-
-       for (i = 0; i < nds_count; i++)
-               unregister_netdev(nds[i]);
 }