fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / ppc / 8xx_io / enet.c
index 8ddef1c..b23c45b 100644 (file)
@@ -22,7 +22,6 @@
  * small packets.
  *
  */
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/bitops.h>
 
 #include <asm/8xx_immap.h>
 #include <asm/pgtable.h>
 #include <asm/mpc8xx.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/commproc.h>
 
@@ -149,7 +149,7 @@ struct scc_enet_private {
 static int scc_enet_open(struct net_device *dev);
 static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int scc_enet_rx(struct net_device *dev);
-static void scc_enet_interrupt(void *dev_id, struct pt_regs *regs);
+static void scc_enet_interrupt(void *dev_id);
 static int scc_enet_close(struct net_device *dev);
 static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
@@ -305,7 +305,7 @@ scc_enet_timeout(struct net_device *dev)
  * This is called from the CPM handler, not the MPC core interrupt.
  */
 static void
-scc_enet_interrupt(void *dev_id, struct pt_regs *regs)
+scc_enet_interrupt(void *dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile struct scc_enet_private *cep;
@@ -581,10 +581,10 @@ static void set_multicast_list(struct net_device *dev)
        
                /* Log any net taps. */
                printk("%s: Promiscuous mode enabled.\n", dev->name);
-               cep->sccp->scc_pmsr |= SCC_PMSR_PRO;
+               cep->sccp->scc_psmr |= SCC_PSMR_PRO;
        } else {
 
-               cep->sccp->scc_pmsr &= ~SCC_PMSR_PRO;
+               cep->sccp->scc_psmr &= ~SCC_PSMR_PRO;
 
                if (dev->flags & IFF_ALLMULTI) {
                        /* Catch all multicast addresses, so set the
@@ -656,7 +656,7 @@ static int __init scc_enet_init(void)
 
        cp = cpmp;      /* Get pointer to Communication Processor */
 
-       immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000);  /* and to internal registers */
+       immap = (immap_t *)(mfspr(SPRN_IMMR) & 0xFFFF0000);     /* and to internal registers */
 
        bd = (bd_t *)__res;
 
@@ -713,16 +713,24 @@ static int __init scc_enet_init(void)
        immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK;     /* Disable Loopback */
 #endif /* PC_ENET_LBK */
 
-       /* Configure port C pins to enable CLSN and RENA.
+#ifdef PE_ENET_TCLK
+       /* Configure port E for TCLK and RCLK.
        */
-       immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
-       immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
-       immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);
-
+       cp->cp_pepar |=  (PE_ENET_TCLK | PE_ENET_RCLK);
+       cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
+       cp->cp_peso  &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
+#else
        /* Configure port A for TCLK and RCLK.
        */
        immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
        immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+#endif
+
+       /* Configure port C pins to enable CLSN and RENA.
+       */
+       immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+       immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+       immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);
 
        /* Configure Serial Interface clock routing.
         * First, clear all SCC bits to zero, then set the ones we want.
@@ -835,7 +843,8 @@ static int __init scc_enet_init(void)
 
                /* Allocate a page.
                */
-               ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+               ba = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE,
+                               &mem_addr, GFP_KERNEL);
                /* BUG: no check for failure */
 
                /* Initialize the BD for every fragment in the page.
@@ -889,19 +898,23 @@ static int __init scc_enet_init(void)
        /* Set processing mode.  Use Ethernet CRC, catch broadcast, and
         * start frame search 22 bit times after RENA.
         */
-       sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);
+       sccp->scc_psmr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22);
 
        /* It is now OK to enable the Ethernet transmitter.
         * Unfortunately, there are board implementation differences here.
         */
-#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA))
+#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
        immap->im_ioport.iop_pcpar |=  PC_ENET_TENA;
        immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
-#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
+#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
        cp->cp_pbpar |= PB_ENET_TENA;
        cp->cp_pbdir |= PB_ENET_TENA;
+#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA))
+       cp->cp_pepar |=  PE_ENET_TENA;
+       cp->cp_pedir &= ~PE_ENET_TENA;
+       cp->cp_peso  |=  PE_ENET_TENA;
 #else
-#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
+#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA
 #endif
 
 #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
@@ -934,6 +947,29 @@ static int __init scc_enet_init(void)
        *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
 #endif
 
+#ifdef CONFIG_MPC885ADS
+
+       /* Deassert PHY reset and enable the PHY.
+        */
+       {
+               volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE);
+               uint tmp;
+
+               tmp = in_be32(bcsr + 1 /* BCSR1 */);
+               tmp |= BCSR1_ETHEN;
+               out_be32(bcsr + 1, tmp);
+               tmp = in_be32(bcsr + 4 /* BCSR4 */);
+               tmp |= BCSR4_ETH10_RST;
+               out_be32(bcsr + 4, tmp);
+               iounmap(bcsr);
+       }
+
+       /* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode
+        * upon reset. SCC is set to half duplex by default. So this
+        * inconsistency should be better fixed by the software.
+        */
+#endif
+
        dev->base_addr = (unsigned long)ep;
 #if 0
        dev->name = "CPM_ENET";
@@ -967,3 +1003,4 @@ static int __init scc_enet_init(void)
 }
 
 module_init(scc_enet_init);
+