[PATCH] drivers/net/Kconfig: indentation fix
[safe/jmp/linux-2.6] / drivers / net / skge.c
index a1cfead..b538e30 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -43,7 +44,7 @@
 #include "skge.h"
 
 #define DRV_NAME               "skge"
-#define DRV_VERSION            "1.1"
+#define DRV_VERSION            "1.3"
 #define PFX                    DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE   128
@@ -88,15 +89,14 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
 
 static int skge_up(struct net_device *dev);
 static int skge_down(struct net_device *dev);
+static void skge_phy_reset(struct skge_port *skge);
 static void skge_tx_clean(struct skge_port *skge);
 static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static void genesis_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_init(struct skge_hw *hw, int port);
-static void yukon_reset(struct skge_hw *hw, int port);
 static void genesis_mac_init(struct skge_hw *hw, int port);
-static void genesis_reset(struct skge_hw *hw, int port);
 static void genesis_link_up(struct skge_port *skge);
 
 /* Avoid conditionals by using array */
@@ -130,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
                      regs->len - B3_RI_WTO_R1);
 }
 
-/* Wake on Lan only supported on Yukon chps with rev 1 or above */
+/* Wake on Lan only supported on Yukon chips with rev 1 or above */
 static int wol_supported(const struct skge_hw *hw)
 {
        return !((hw->chip_id == CHIP_ID_GENESIS ||
@@ -170,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        return 0;
 }
 
-/* Determine supported/adverised modes based on hardware.
- * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
+/* Determine supported/advertised modes based on hardware.
+ * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
  */
 static u32 skge_supported_modes(const struct skge_hw *hw)
 {
@@ -276,10 +276,9 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        skge->autoneg = ecmd->autoneg;
        skge->advertising = ecmd->advertising;
 
-       if (netif_running(dev)) {
-               skge_down(dev);
-               skge_up(dev);
-       }
+       if (netif_running(dev))
+               skge_phy_reset(skge);
+
        return (0);
 }
 
@@ -399,6 +398,7 @@ static int skge_set_ring_param(struct net_device *dev,
                               struct ethtool_ringparam *p)
 {
        struct skge_port *skge = netdev_priv(dev);
+       int err;
 
        if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
            p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
@@ -409,7 +409,9 @@ static int skge_set_ring_param(struct net_device *dev,
 
        if (netif_running(dev)) {
                skge_down(dev);
-               skge_up(dev);
+               err = skge_up(dev);
+               if (err)
+                       dev_close(dev);
        }
 
        return 0;
@@ -430,21 +432,11 @@ static void skge_set_msglevel(struct net_device *netdev, u32 value)
 static int skge_nway_reset(struct net_device *dev)
 {
        struct skge_port *skge = netdev_priv(dev);
-       struct skge_hw *hw = skge->hw;
-       int port = skge->port;
 
        if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev))
                return -EINVAL;
 
-       spin_lock_bh(&hw->phy_lock);
-       if (hw->chip_id == CHIP_ID_GENESIS) {
-               genesis_reset(hw, port);
-               genesis_mac_init(hw, port);
-       } else {
-               yukon_reset(hw, port);
-               yukon_init(hw, port);
-       }
-       spin_unlock_bh(&hw->phy_lock);
+       skge_phy_reset(skge);
        return 0;
 }
 
@@ -516,10 +508,8 @@ static int skge_set_pauseparam(struct net_device *dev,
        else
                skge->flow_control = FLOW_MODE_NONE;
 
-       if (netif_running(dev)) {
-               skge_down(dev);
-               skge_up(dev);
-       }
+       if (netif_running(dev))
+               skge_phy_reset(skge);
        return 0;
 }
 
@@ -532,13 +522,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
                return 78215; /* or:  78.125 MHz */
 }
 
-/* Chip hz to microseconds */
+/* Chip HZ to microseconds */
 static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
 {
        return (ticks * 1000) / hwkhz(hw);
 }
 
-/* Microseconds to chip hz */
+/* Microseconds to chip HZ */
 static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
 {
        return hwkhz(hw) * usec / 1000;
@@ -1163,7 +1153,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
        xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
        xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
 
-       /* Use link status change interrrupt */
+       /* Use link status change interrupt */
        xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
 
        bcom_check_link(hw, port);
@@ -1203,7 +1193,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
        skge_write32(hw, B2_GP_IO, r);
        skge_read32(hw, B2_GP_IO);
 
-       /* Enable GMII interfac */
+       /* Enable GMII interface */
        xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
 
        bcom_phy_init(skge, jumbo);
@@ -1254,7 +1244,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
         * that jumbo frames larger than 8192 bytes will be
         * truncated. Disabling all bad frame filtering causes
         * the RX FIFO to operate in streaming mode, in which
-        * case the XMAC will start transfering frames out of the
+        * case the XMAC will start transferring frames out of the
         * RX FIFO as soon as the FIFO threshold is reached.
         */
        xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
@@ -1321,7 +1311,7 @@ static void genesis_stop(struct skge_port *skge)
                     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
 
        /*
-        * If the transfer stucks at the MAC the STOP command will not
+        * If the transfer sticks at the MAC the STOP command will not
         * terminate if we don't flush the XMAC's transmit FIFO !
         */
        xm_write32(hw, port, XM_MODE,
@@ -1559,7 +1549,7 @@ static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
        return v;
 }
 
-/* Marvell Phy Initailization */
+/* Marvell Phy Initialization */
 static void yukon_init(struct skge_hw *hw, int port)
 {
        struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1804,6 +1794,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
        skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
 }
 
+/* Go into power down mode */
+static void yukon_suspend(struct skge_hw *hw, int port)
+{
+       u16 ctrl;
+
+       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+       ctrl |= PHY_M_PC_POL_R_DIS;
+       gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+       ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+       ctrl |= PHY_CT_RESET;
+       gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+       /* switch IEEE compatible power down mode on */
+       ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+       ctrl |= PHY_CT_PDOWN;
+       gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+}
+
 static void yukon_stop(struct skge_port *skge)
 {
        struct skge_hw *hw = skge->hw;
@@ -1817,14 +1826,7 @@ static void yukon_stop(struct skge_port *skge)
                         & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
        gma_read16(hw, port, GM_GP_CTRL);
 
-       if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-           hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
-               u32 io = skge_read32(hw, B2_GP_IO);
-
-               io |= GP_DIR_9 | GP_IO_9;
-               skge_write32(hw, B2_GP_IO, io);
-               skge_read32(hw, B2_GP_IO);
-       }
+       yukon_suspend(hw, port);
 
        /* set GPHY Control reset */
        skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -2007,6 +2009,25 @@ static void yukon_phy_intr(struct skge_port *skge)
        /* XXX restart autonegotiation? */
 }
 
+static void skge_phy_reset(struct skge_port *skge)
+{
+       struct skge_hw *hw = skge->hw;
+       int port = skge->port;
+
+       netif_stop_queue(skge->netdev);
+       netif_carrier_off(skge->netdev);
+
+       spin_lock_bh(&hw->phy_lock);
+       if (hw->chip_id == CHIP_ID_GENESIS) {
+               genesis_reset(hw, port);
+               genesis_mac_init(hw, port);
+       } else {
+               yukon_reset(hw, port);
+               yukon_init(hw, port);
+       }
+       spin_unlock_bh(&hw->phy_lock);
+}
+
 /* Basic MII support */
 static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -2144,7 +2165,7 @@ static int skge_up(struct net_device *dev)
        hw->intr_mask |= portirqmask[port];
        skge_write32(hw, B0_IMSK, hw->intr_mask);
 
-       /* Initialze MAC */
+       /* Initialize MAC */
        spin_lock_bh(&hw->phy_lock);
        if (hw->chip_id == CHIP_ID_GENESIS)
                genesis_mac_init(hw, port);
@@ -2175,6 +2196,7 @@ static int skge_up(struct net_device *dev)
        kfree(skge->rx_ring.start);
  free_pci_mem:
        pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+       skge->mem = NULL;
 
        return err;
 }
@@ -2185,6 +2207,9 @@ static int skge_down(struct net_device *dev)
        struct skge_hw *hw = skge->hw;
        int port = skge->port;
 
+       if (skge->mem == NULL)
+               return 0;
+
        if (netif_msg_ifdown(skge))
                printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
@@ -2241,6 +2266,7 @@ static int skge_down(struct net_device *dev)
        kfree(skge->rx_ring.start);
        kfree(skge->tx_ring.start);
        pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+       skge->mem = NULL;
        return 0;
 }
 
@@ -2268,11 +2294,13 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
        }
 
        if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) {
-               netif_stop_queue(dev);
-               spin_unlock_irqrestore(&skge->tx_lock, flags);
+               if (!netif_queue_stopped(dev)) {
+                       netif_stop_queue(dev);
 
-               printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
-                      dev->name);
+                       printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+                              dev->name);
+               }
+               spin_unlock_irqrestore(&skge->tx_lock, flags);
                return NETDEV_TX_BUSY;
        }
 
@@ -2288,14 +2316,12 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
        td->dma_hi = map >> 32;
 
        if (skb->ip_summed == CHECKSUM_HW) {
-               const struct iphdr *ip
-                       = (const struct iphdr *) (skb->data + ETH_HLEN);
                int offset = skb->h.raw - skb->data;
 
                /* This seems backwards, but it is what the sk98lin
                 * does.  Looks like hardware is wrong?
                 */
-               if (ip->protocol == IPPROTO_UDP
+               if (skb->h.ipiph->protocol == IPPROTO_UDP
                    && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
                        control = BMU_TCP_CHECK;
                else
@@ -2401,18 +2427,23 @@ static void skge_tx_timeout(struct net_device *dev)
 
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
 {
-       int err = 0;
-       int running = netif_running(dev);
+       int err;
 
        if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
                return -EINVAL;
 
+       if (!netif_running(dev)) {
+               dev->mtu = new_mtu;
+               return 0;
+       }
+
+       skge_down(dev);
 
-       if (running)
-               skge_down(dev);
        dev->mtu = new_mtu;
-       if (running)
-               skge_up(dev);
+
+       err = skge_up(dev);
+       if (err)
+               dev_close(dev);
 
        return err;
 }
@@ -2464,7 +2495,7 @@ static void yukon_set_multicast(struct net_device *dev)
        reg = gma_read16(hw, port, GM_RX_CTRL);
        reg |= GM_RXCR_UCF_ENA;
 
-       if (dev->flags & IFF_PROMISC)           /* promiscious */
+       if (dev->flags & IFF_PROMISC)           /* promiscuous */
                reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
        else if (dev->flags & IFF_ALLMULTI)     /* all multicast */
                memset(filter, 0xff, sizeof(filter));
@@ -2615,7 +2646,7 @@ static int skge_poll(struct net_device *dev, int *budget)
        unsigned int to_do = min(dev->quota, *budget);
        unsigned int work_done = 0;
 
-       for (e = ring->to_clean; work_done < to_do; e = e->next) {
+       for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
                struct skge_rx_desc *rd = e->desc;
                struct sk_buff *skb;
                u32 control;
@@ -2648,11 +2679,11 @@ static int skge_poll(struct net_device *dev, int *budget)
        if (work_done >=  to_do)
                return 1; /* not done */
 
-       local_irq_disable();
-       __netif_rx_complete(dev);
+       netif_rx_complete(dev);
        hw->intr_mask |= portirqmask[skge->port];
        skge_write32(hw, B0_IMSK, hw->intr_mask);
-       local_irq_enable();
+       skge_read32(hw, B0_IMSK);
+
        return 0;
 }
 
@@ -2664,7 +2695,7 @@ static inline void skge_tx_intr(struct net_device *dev)
        struct skge_element *e;
 
        spin_lock(&skge->tx_lock);
-       for (e = ring->to_clean; e != ring->to_use; e = e->next) {
+       for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
                struct skge_tx_desc *td = e->desc;
                u32 control;
 
@@ -2787,7 +2818,7 @@ static void skge_error_irq(struct skge_hw *hw)
 }
 
 /*
- * Interrrupt from PHY are handled in tasklet (soft irq)
+ * Interrupt from PHY are handled in tasklet (soft irq)
  * because accessing phy registers requires spin wait which might
  * cause excess interrupt latency.
  */
@@ -2817,6 +2848,14 @@ static void skge_extirq(unsigned long data)
        local_irq_enable();
 }
 
+static inline void skge_wakeup(struct net_device *dev)
+{
+       struct skge_port *skge = netdev_priv(dev);
+
+       prefetch(skge->rx_ring.to_clean);
+       netif_rx_schedule(dev);
+}
+
 static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct skge_hw *hw = dev_id;
@@ -2828,12 +2867,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
        status &= hw->intr_mask;
        if (status & IS_R1_F) {
                hw->intr_mask &= ~IS_R1_F;
-               netif_rx_schedule(hw->dev[0]);
+               skge_wakeup(hw->dev[0]);
        }
 
        if (status & IS_R2_F) {
                hw->intr_mask &= ~IS_R2_F;
-               netif_rx_schedule(hw->dev[1]);
+               skge_wakeup(hw->dev[1]);
        }
 
        if (status & IS_XA1_F)
@@ -3213,7 +3252,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
        }
 
 #ifdef __BIG_ENDIAN
-       /* byte swap decriptors in hardware */
+       /* byte swap descriptors in hardware */
        {
                u32 reg;
 
@@ -3253,7 +3292,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
        if (err)
                goto err_out_free_irq;
 
-       printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n",
+       printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
               pci_resource_start(pdev, 0), pdev->irq,
               skge_board_name(hw), hw->chip_rev);
 
@@ -3378,8 +3417,8 @@ static int skge_resume(struct pci_dev *pdev)
                struct net_device *dev = hw->dev[i];
                if (dev) {
                        netif_device_attach(dev);
-                       if (netif_running(dev))
-                               skge_up(dev);
+                       if (netif_running(dev) && skge_up(dev))
+                               dev_close(dev);
                }
        }
        return 0;