]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/ibm_emac/ibm_emac_core.c
Manual merge with Linus.
[linux-2.6-omap-h63xx.git] / drivers / net / ibm_emac / ibm_emac_core.c
index eb7d6947871555812408a40aa7e0c6fba697275e..7e49522b8b3c6a10cc5c75070edb378d1c935658 100644 (file)
@@ -65,7 +65,7 @@
  */
 
 #define DRV_NAME        "emac"
-#define DRV_VERSION     "3.53"
+#define DRV_VERSION     "3.54"
 #define DRV_DESC        "PPC 4xx OCP EMAC driver"
 
 MODULE_DESCRIPTION(DRV_DESC);
@@ -158,6 +158,14 @@ static inline void emac_report_timeout_error(struct ocp_enet_private *dev,
 #define PHY_POLL_LINK_ON       HZ
 #define PHY_POLL_LINK_OFF      (HZ / 5)
 
+/* Graceful stop timeouts in us. 
+ * We should allow up to 1 frame time (full-duplex, ignoring collisions) 
+ */
+#define STOP_TIMEOUT_10                1230    
+#define STOP_TIMEOUT_100       124
+#define STOP_TIMEOUT_1000      13
+#define STOP_TIMEOUT_1000_JUMBO        73
+
 /* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
 static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
        "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
@@ -196,7 +204,7 @@ static inline int emac_phy_gpcs(int phy_mode)
 
 static inline void emac_tx_enable(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        unsigned long flags;
        u32 r;
 
@@ -212,7 +220,7 @@ static inline void emac_tx_enable(struct ocp_enet_private *dev)
 
 static void emac_tx_disable(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        unsigned long flags;
        u32 r;
 
@@ -222,10 +230,12 @@ static void emac_tx_disable(struct ocp_enet_private *dev)
 
        r = in_be32(&p->mr0);
        if (r & EMAC_MR0_TXE) {
-               int n = 300;
+               int n = dev->stop_timeout;
                out_be32(&p->mr0, r & ~EMAC_MR0_TXE);
-               while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n)
+               while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) {
+                       udelay(1);
                        --n;
+               }       
                if (unlikely(!n))
                        emac_report_timeout_error(dev, "TX disable timeout");
        }
@@ -234,7 +244,7 @@ static void emac_tx_disable(struct ocp_enet_private *dev)
 
 static void emac_rx_enable(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        unsigned long flags;
        u32 r;
 
@@ -248,9 +258,11 @@ static void emac_rx_enable(struct ocp_enet_private *dev)
        if (!(r & EMAC_MR0_RXE)) {
                if (unlikely(!(r & EMAC_MR0_RXI))) {
                        /* Wait if previous async disable is still in progress */
-                       int n = 100;
-                       while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+                       int n = dev->stop_timeout;
+                       while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
+                               udelay(1);
                                --n;
+                       }       
                        if (unlikely(!n))
                                emac_report_timeout_error(dev,
                                                          "RX disable timeout");
@@ -263,7 +275,7 @@ static void emac_rx_enable(struct ocp_enet_private *dev)
 
 static void emac_rx_disable(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        unsigned long flags;
        u32 r;
 
@@ -273,10 +285,12 @@ static void emac_rx_disable(struct ocp_enet_private *dev)
 
        r = in_be32(&p->mr0);
        if (r & EMAC_MR0_RXE) {
-               int n = 300;
+               int n = dev->stop_timeout;
                out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
-               while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+               while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
+                       udelay(1);
                        --n;
+               }       
                if (unlikely(!n))
                        emac_report_timeout_error(dev, "RX disable timeout");
        }
@@ -285,7 +299,7 @@ static void emac_rx_disable(struct ocp_enet_private *dev)
 
 static inline void emac_rx_disable_async(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        unsigned long flags;
        u32 r;
 
@@ -301,7 +315,7 @@ static inline void emac_rx_disable_async(struct ocp_enet_private *dev)
 
 static int emac_reset(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        unsigned long flags;
        int n = 20;
 
@@ -334,7 +348,7 @@ static int emac_reset(struct ocp_enet_private *dev)
 
 static void emac_hash_mc(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        u16 gaht[4] = { 0 };
        struct dev_mc_list *dmi;
 
@@ -379,7 +393,7 @@ static inline int emac_opb_mhz(void)
 /* BHs disabled */
 static int emac_configure(struct ocp_enet_private *dev)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        struct net_device *ndev = dev->ndev;
        int gige;
        u32 r;
@@ -394,7 +408,8 @@ static int emac_configure(struct ocp_enet_private *dev)
        /* Mode register */
        r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
        if (dev->phy.duplex == DUPLEX_FULL)
-               r |= EMAC_MR1_FDE;
+               r |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
+       dev->stop_timeout = STOP_TIMEOUT_10;
        switch (dev->phy.speed) {
        case SPEED_1000:
                if (emac_phy_gpcs(dev->phy.mode)) {
@@ -409,12 +424,16 @@ static int emac_configure(struct ocp_enet_private *dev)
                        r |= EMAC_MR1_MF_1000;
                r |= EMAC_MR1_RFS_16K;
                gige = 1;
-               
-               if (dev->ndev->mtu > ETH_DATA_LEN)
+
+               if (dev->ndev->mtu > ETH_DATA_LEN) {
                        r |= EMAC_MR1_JPSM;
+                       dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO;
+               } else
+                       dev->stop_timeout = STOP_TIMEOUT_1000;
                break;
        case SPEED_100:
                r |= EMAC_MR1_MF_100;
+               dev->stop_timeout = STOP_TIMEOUT_100;
                /* Fall through */
        default:
                r |= EMAC_MR1_RFS_4K;
@@ -536,7 +555,7 @@ static void emac_full_tx_reset(struct net_device *ndev)
 
 static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        u32 r;
        int n;
 
@@ -585,7 +604,7 @@ static int __emac_mdio_read(struct ocp_enet_private *dev, u8 id, u8 reg)
 static void __emac_mdio_write(struct ocp_enet_private *dev, u8 id, u8 reg,
                              u16 val)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        int n;
 
        DBG2("%d: mdio_write(%02x,%02x,%04x)" NL, dev->def->index, id, reg,
@@ -647,7 +666,7 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
 static void emac_set_multicast_list(struct net_device *ndev)
 {
        struct ocp_enet_private *dev = ndev->priv;
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        u32 rmr = emac_iff2rmr(ndev);
 
        DBG("%d: multicast %08x" NL, dev->def->index, rmr);
@@ -806,7 +825,7 @@ static void emac_clean_rx_ring(struct ocp_enet_private *dev)
 }
 
 static inline int emac_alloc_rx_skb(struct ocp_enet_private *dev, int slot,
-                                   int flags)
+                                   gfp_t flags)
 {
        struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
        if (unlikely(!skb))
@@ -1028,7 +1047,7 @@ static inline u16 emac_tx_csum(struct ocp_enet_private *dev,
 
 static inline int emac_xmit_finish(struct ocp_enet_private *dev, int len)
 {
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        struct net_device *ndev = dev->ndev;
 
        /* Send the packet out */
@@ -1500,7 +1519,7 @@ static void emac_rxde(void *param)
 static irqreturn_t emac_irq(int irq, void *dev_instance, struct pt_regs *regs)
 {
        struct ocp_enet_private *dev = dev_instance;
-       struct emac_regs *p = dev->emacp;
+       struct emac_regs __iomem *p = dev->emacp;
        struct ibm_emac_error_stats *st = &dev->estats;
 
        u32 isr = in_be32(&p->isr);
@@ -1600,17 +1619,17 @@ static void emac_remove(struct ocp_device *ocpdev)
 
        DBG("%d: remove" NL, dev->def->index);
 
-       ocp_set_drvdata(ocpdev, 0);
+       ocp_set_drvdata(ocpdev, NULL);
        unregister_netdev(dev->ndev);
 
        tah_fini(dev->tah_dev);
        rgmii_fini(dev->rgmii_dev, dev->rgmii_input);
        zmii_fini(dev->zmii_dev, dev->zmii_input);
 
-       emac_dbg_register(dev->def->index, 0);
+       emac_dbg_register(dev->def->index, NULL);
 
        mal_unregister_commac(dev->mal, &dev->commac);
-       iounmap((void *)dev->emacp);
+       iounmap(dev->emacp);
        kfree(dev->ndev);
 }
 
@@ -2029,9 +2048,7 @@ static int __init emac_probe(struct ocp_device *ocpdev)
                goto out4;
 
        /* Map EMAC regs */
-       dev->emacp =
-           (struct emac_regs *)ioremap(dev->def->paddr,
-                                       sizeof(struct emac_regs));
+       dev->emacp = ioremap(dev->def->paddr, sizeof(struct emac_regs));
        if (!dev->emacp) {
                printk(KERN_ERR "emac%d: could not ioremap device registers!\n",
                       dev->def->index);
@@ -2048,6 +2065,7 @@ static int __init emac_probe(struct ocp_device *ocpdev)
        dev->phy.duplex = DUPLEX_FULL;
        dev->phy.autoneg = AUTONEG_DISABLE;
        dev->phy.pause = dev->phy.asym_pause = 0;
+       dev->stop_timeout = STOP_TIMEOUT_100;
        init_timer(&dev->link_timer);
        dev->link_timer.function = emac_link_timer;
        dev->link_timer.data = (unsigned long)dev;
@@ -2190,7 +2208,7 @@ static int __init emac_probe(struct ocp_device *ocpdev)
 
        return 0;
       out6:
-       iounmap((void *)dev->emacp);
+       iounmap(dev->emacp);
       out5:
        tah_fini(dev->tah_dev);
       out4: