net: Make GRETH driver depend on SPARC.
[safe/jmp/linux-2.6] / drivers / net / fec.c
index c9fd82d..d9d14c8 100644 (file)
@@ -367,7 +367,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        spin_unlock_irqrestore(&fep->hw_lock, flags);
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 static void
@@ -427,7 +427,7 @@ fec_enet_tx(struct net_device *dev)
        struct  sk_buff *skb;
 
        fep = netdev_priv(dev);
-       spin_lock_irq(&fep->hw_lock);
+       spin_lock(&fep->hw_lock);
        bdp = fep->dirty_tx;
 
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
@@ -486,7 +486,7 @@ fec_enet_tx(struct net_device *dev)
                }
        }
        fep->dirty_tx = bdp;
-       spin_unlock_irq(&fep->hw_lock);
+       spin_unlock(&fep->hw_lock);
 }
 
 
@@ -509,7 +509,7 @@ fec_enet_rx(struct net_device *dev)
        flush_cache_all();
 #endif
 
-       spin_lock_irq(&fep->hw_lock);
+       spin_lock(&fep->hw_lock);
 
        /* First, grab all of the stats for the incoming packet.
         * These get messed up if we get called due to a busy condition.
@@ -604,7 +604,7 @@ rx_processing_done:
        }
        fep->cur_rx = bdp;
 
-       spin_unlock_irq(&fep->hw_lock);
+       spin_unlock(&fep->hw_lock);
 }
 
 /* called from interrupt context */
@@ -615,7 +615,7 @@ fec_enet_mii(struct net_device *dev)
        mii_list_t      *mip;
 
        fep = netdev_priv(dev);
-       spin_lock_irq(&fep->mii_lock);
+       spin_lock(&fep->mii_lock);
 
        if ((mip = mii_head) == NULL) {
                printk("MII and no head!\n");
@@ -633,20 +633,19 @@ fec_enet_mii(struct net_device *dev)
                writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
 
 unlock:
-       spin_unlock_irq(&fep->mii_lock);
+       spin_unlock(&fep->mii_lock);
 }
 
 static int
-mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *))
+mii_queue_unlocked(struct net_device *dev, int regval,
+               void (*func)(uint, struct net_device *))
 {
        struct fec_enet_private *fep;
-       unsigned long   flags;
        mii_list_t      *mip;
        int             retval;
 
        /* Add PHY address to register command */
        fep = netdev_priv(dev);
-       spin_lock_irqsave(&fep->mii_lock, flags);
 
        regval |= fep->phy_addr << 23;
        retval = 0;
@@ -667,6 +666,19 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
                retval = 1;
        }
 
+       return retval;
+}
+
+static int
+mii_queue(struct net_device *dev, int regval,
+               void (*func)(uint, struct net_device *))
+{
+       struct fec_enet_private *fep;
+       unsigned long   flags;
+       int             retval;
+       fep = netdev_priv(dev);
+       spin_lock_irqsave(&fep->mii_lock, flags);
+       retval = mii_queue_unlocked(dev, regval, func);
        spin_unlock_irqrestore(&fep->mii_lock, flags);
        return retval;
 }
@@ -1116,6 +1128,26 @@ static phy_info_t phy_info_dp83848= {
        },
 };
 
+static phy_info_t phy_info_lan8700 = {
+       0x0007C0C,
+       "LAN8700",
+       (const phy_cmd_t []) { /* config */
+               { mk_mii_read(MII_REG_CR), mii_parse_cr },
+               { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+               { mk_mii_end, }
+       },
+       (const phy_cmd_t []) { /* startup */
+               { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+               { mk_mii_read(MII_REG_SR), mii_parse_sr },
+               { mk_mii_end, }
+       },
+       (const phy_cmd_t []) { /* act_int */
+               { mk_mii_end, }
+       },
+       (const phy_cmd_t []) { /* shutdown */
+               { mk_mii_end, }
+       },
+};
 /* ------------------------------------------------------------------------- */
 
 static phy_info_t const * const phy_info[] = {
@@ -1125,6 +1157,7 @@ static phy_info_t const * const phy_info[] = {
        &phy_info_am79c874,
        &phy_info_ks8721bl,
        &phy_info_dp83848,
+       &phy_info_lan8700,
        NULL
 };
 
@@ -1142,19 +1175,9 @@ static void __inline__ fec_request_mii_intr(struct net_device *dev)
                printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
 }
 
-static void __inline__ fec_disable_phy_intr(void)
-{
-       volatile unsigned long *icrp;
-       icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-       *icrp = 0x08000000;
-}
-
-static void __inline__ fec_phy_ack_intr(void)
+static void __inline__ fec_disable_phy_intr(struct net_device *dev)
 {
-       volatile unsigned long *icrp;
-       /* Acknowledge the interrupt */
-       icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-       *icrp = 0x0d000000;
+       free_irq(66, dev);
 }
 #endif
 
@@ -1373,11 +1396,11 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
 
                        /* Got first part of ID, now get remainder */
                        fep->phy_id = phytype << 16;
-                       mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
+                       mii_queue_unlocked(dev, mk_mii_read(MII_REG_PHYIR2),
                                                        mii_discover_phy3);
                } else {
                        fep->phy_addr++;
-                       mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
+                       mii_queue_unlocked(dev, mk_mii_read(MII_REG_PHYIR1),
                                                        mii_discover_phy);
                }
        } else {
@@ -1386,7 +1409,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
                writel(0, fep->hwp + FEC_MII_SPEED);
                fep->phy_speed = 0;
 #ifdef HAVE_mii_link_interrupt
-               fec_disable_phy_intr();
+               fec_disable_phy_intr(dev);
 #endif
        }
 }
@@ -1399,8 +1422,6 @@ mii_link_interrupt(int irq, void * dev_id)
        struct  net_device *dev = dev_id;
        struct fec_enet_private *fep = netdev_priv(dev);
 
-       fec_phy_ack_intr();
-
        mii_do_cmd(dev, fep->phy->ack_int);
        mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
 
@@ -1585,7 +1606,7 @@ static void set_multicast_list(struct net_device *dev)
 
        dmi = dev->mc_list;
 
-       for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
+       for (j = 0; j < netdev_mc_count(dev); j++, dmi = dmi->next) {
                /* Only support group multicast for now */
                if (!(dmi->dmi_addr[0] & 1))
                        continue;
@@ -1654,10 +1675,11 @@ static const struct net_device_ops fec_netdev_ops = {
   *
   * index is only used in legacy code
   */
-int __init fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev, int index)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
        struct bufdesc *cbd_base;
+       struct bufdesc *bdp;
        int i;
 
        /* Allocate memory for buffer descriptors. */
@@ -1710,6 +1732,34 @@ int __init fec_enet_init(struct net_device *dev, int index)
        /* Set MII speed to 2.5 MHz */
        fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
                                        / 2500000) / 2) & 0x3F) << 1;
+
+       /* Initialize the receive buffer descriptors. */
+       bdp = fep->rx_bd_base;
+       for (i = 0; i < RX_RING_SIZE; i++) {
+
+               /* Initialize the BD for every fragment in the page. */
+               bdp->cbd_sc = 0;
+               bdp++;
+       }
+
+       /* Set the last buffer to wrap */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       /* ...and the same for transmit */
+       bdp = fep->tx_bd_base;
+       for (i = 0; i < TX_RING_SIZE; i++) {
+
+               /* Initialize the BD for every fragment in the page. */
+               bdp->cbd_sc = 0;
+               bdp->cbd_bufaddr = 0;
+               bdp++;
+       }
+
+       /* Set the last buffer to wrap */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
        fec_restart(dev, 0);
 
        /* Queue up command to detect the PHY and initialize the
@@ -1730,7 +1780,6 @@ static void
 fec_restart(struct net_device *dev, int duplex)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
-       struct bufdesc *bdp;
        int i;
 
        /* Whack a reset.  We should wait for this. */
@@ -1768,33 +1817,6 @@ fec_restart(struct net_device *dev, int duplex)
                }
        }
 
-       /* Initialize the receive buffer descriptors. */
-       bdp = fep->rx_bd_base;
-       for (i = 0; i < RX_RING_SIZE; i++) {
-
-               /* Initialize the BD for every fragment in the page. */
-               bdp->cbd_sc = BD_ENET_RX_EMPTY;
-               bdp++;
-       }
-
-       /* Set the last buffer to wrap */
-       bdp--;
-       bdp->cbd_sc |= BD_SC_WRAP;
-
-       /* ...and the same for transmit */
-       bdp = fep->tx_bd_base;
-       for (i = 0; i < TX_RING_SIZE; i++) {
-
-               /* Initialize the BD for every fragment in the page. */
-               bdp->cbd_sc = 0;
-               bdp->cbd_bufaddr = 0;
-               bdp++;
-       }
-
-       /* Set the last buffer to wrap */
-       bdp--;
-       bdp->cbd_sc |= BD_SC_WRAP;
-
        /* Enable MII mode */
        if (duplex) {
                /* MII enable / FD enable */