fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / ppc / 8xx_io / fec.c
index 5c7c914..e6c28fb 100644 (file)
@@ -28,7 +28,6 @@
  * Thomas Lange, thomas@corelatus.com
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -44,6 +43,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
+#include <linux/bitops.h>
 #ifdef CONFIG_FEC_PACKETHOOK
 #include <linux/pkthook.h>
 #endif
@@ -52,7 +52,6 @@
 #include <asm/pgtable.h>
 #include <asm/mpc8xx.h>
 #include <asm/irq.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/commproc.h>
 
@@ -173,7 +172,8 @@ struct fec_enet_private {
        uint    phy_status;
        uint    phy_speed;
        phy_info_t      *phy;
-       struct tq_struct phy_task;
+       struct work_struct phy_task;
+       struct net_device *dev;
 
        uint    sequence_done;
 
@@ -199,7 +199,7 @@ static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 #ifdef CONFIG_USE_MDIO
 static void fec_enet_mii(struct net_device *dev);
 #endif /* CONFIG_USE_MDIO */
-static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
 #ifdef CONFIG_FEC_PACKETHOOK
 static void  fec_enet_tx(struct net_device *dev, __u32 regval);
 static void  fec_enet_rx(struct net_device *dev, __u32 regval);
@@ -389,6 +389,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        flush_dcache_range((unsigned long)skb->data,
                           (unsigned long)skb->data + skb->len);
 
+       /* disable interrupts while triggering transmit */
        spin_lock_irq(&fep->lock);
 
        /* Send it on its way.  Tell FEC its ready, interrupt when done,
@@ -470,8 +471,8 @@ fec_timeout(struct net_device *dev)
 /* The interrupt handler.
  * This is called from the MPC core interrupt.
  */
-static void
-fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t
+fec_enet_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile fec_t  *fecp;
@@ -524,6 +525,7 @@ printk("%s[%d] %s: unexpected FEC_ENET_MII event\n", __FILE__,__LINE__,__FUNCTIO
                }
 
        }
+       return IRQ_RETVAL(IRQ_HANDLED);
 }
 
 
@@ -539,6 +541,7 @@ fec_enet_tx(struct net_device *dev)
        struct  sk_buff *skb;
 
        fep = dev->priv;
+       /* lock while transmitting */
        spin_lock(&fep->lock);
        bdp = fep->dirty_tx;
 
@@ -799,6 +802,7 @@ fec_enet_mii(struct net_device *dev)
 
        if ((mip = mii_head) != NULL) {
                ep->fec_mii_data = mip->mii_regval;
+
        }
 }
 
@@ -817,8 +821,8 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
 
        retval = 0;
 
-       save_flags(flags);
-       cli();
+       /* lock while modifying mii_list */
+       spin_lock_irqsave(&fep->lock, flags);
 
        if ((mip = mii_free) != NULL) {
                mii_free = mip->mii_next;
@@ -836,7 +840,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
                retval = 1;
        }
 
-       restore_flags(flags);
+       spin_unlock_irqrestore(&fep->lock, flags);
 
        return(retval);
 }
@@ -1260,9 +1264,11 @@ static void mii_display_status(struct net_device *dev)
        printk(".\n");
 }
 
-static void mii_display_config(struct net_device *dev)
+static void mii_display_config(struct work_struct *work)
 {
-       struct fec_enet_private *fep = dev->priv;
+       struct fec_enet_private *fep =
+               container_of(work, struct fec_enet_private, phy_task);
+       struct net_device *dev = fep->dev;
        volatile uint *s = &(fep->phy_status);
 
        printk("%s: config: auto-negotiation ", dev->name);
@@ -1291,9 +1297,11 @@ static void mii_display_config(struct net_device *dev)
        fep->sequence_done = 1;
 }
 
-static void mii_relink(struct net_device *dev)
+static void mii_relink(struct work_struct *work)
 {
-       struct fec_enet_private *fep = dev->priv;
+       struct fec_enet_private *fep =
+               container_of(work, struct fec_enet_private, phy_task);
+       struct net_device *dev = fep->dev;
        int duplex;
 
        fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0;
@@ -1320,18 +1328,18 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
 {
        struct fec_enet_private *fep = dev->priv;
 
-       fep->phy_task.routine = (void *)mii_relink;
-       fep->phy_task.data = dev;
-       schedule_task(&fep->phy_task);
+       fep->dev = dev;
+       INIT_WORK(&fep->phy_task, mii_relink);
+       schedule_work(&fep->phy_task);
 }
 
 static void mii_queue_config(uint mii_reg, struct net_device *dev)
 {
        struct fec_enet_private *fep = dev->priv;
 
-       fep->phy_task.routine = (void *)mii_display_config;
-       fep->phy_task.data = dev;
-       schedule_task(&fep->phy_task);
+       fep->dev = dev;
+       INIT_WORK(&fep->phy_task, mii_display_config);
+       schedule_work(&fep->phy_task);
 }
 
 
@@ -1400,11 +1408,11 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
 
 /* This interrupt occurs when the PHY detects a link change.
 */
-static void
+static
 #ifdef CONFIG_RPXCLASSIC
-mii_link_interrupt(void *dev_id)
+void mii_link_interrupt(void *dev_id)
 #else
-mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+irqreturn_t mii_link_interrupt(int irq, void * dev_id)
 #endif
 {
 #ifdef CONFIG_USE_MDIO
@@ -1437,6 +1445,9 @@ mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 printk("%s[%d] %s: unexpected Link interrupt\n", __FILE__,__LINE__,__FUNCTION__);
 #endif /* CONFIG_USE_MDIO */
 
+#ifndef CONFIG_RPXCLASSIC
+       return IRQ_RETVAL(IRQ_HANDLED);
+#endif /* CONFIG_RPXCLASSIC */
 }
 
 static int
@@ -1572,7 +1583,7 @@ static int __init fec_enet_init(void)
        struct fec_enet_private *fep;
        int i, j, k, err;
        unsigned char   *eap, *iap, *ba;
-       unsigned long   mem_addr;
+       dma_addr_t      mem_addr;
        volatile        cbd_t   *bdp;
        cbd_t           *cbd_base;
        volatile        immap_t *immap;
@@ -1637,7 +1648,8 @@ static int __init fec_enet_init(void)
                printk("FEC initialization failed.\n");
                return 1;
        }
-       cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+       cbd_base = (cbd_t *)dma_alloc_coherent(dev->class_dev.dev, PAGE_SIZE,
+                                              &mem_addr, GFP_KERNEL);
 
        /* Set receive and transmit descriptor base.
        */
@@ -1654,7 +1666,10 @@ static int __init fec_enet_init(void)
 
                /* Allocate a page.
                */
-               ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+               ba = (unsigned char *)dma_alloc_coherent(dev->class_dev.dev,
+                                                        PAGE_SIZE,
+                                                        &mem_addr,
+                                                        GFP_KERNEL);
                /* BUG: no check for failure */
 
                /* Initialize the BD for every fragment in the page.
@@ -1684,7 +1699,7 @@ static int __init fec_enet_init(void)
 
        /* Install our interrupt handler.
        */
-       if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
+       if (request_irq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
                panic("Could not allocate FEC IRQ!");
 
 #ifdef CONFIG_RPXCLASSIC
@@ -1705,7 +1720,7 @@ static int __init fec_enet_init(void)
        ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |=
                (0x80000000 >> PHY_INTERRUPT);
 
-       if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0)
+       if (request_irq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0)
                panic("Could not allocate MII IRQ!");
 #endif
 
@@ -1732,7 +1747,7 @@ static int __init fec_enet_init(void)
 
        /* Bits moved from Rev. D onward.
        */
-       if ((mfspr(IMMR) & 0xffff) < 0x0501)
+       if ((mfspr(SPRN_IMMR) & 0xffff) < 0x0501)
                immap->im_ioport.iop_pddir = 0x1c58;    /* Pre rev. D */
        else
                immap->im_ioport.iop_pddir = 0x1fff;    /* Rev. D and later */