V4L/DVB (3429): Missing break statement on tuner-core
[powerpc.git] / drivers / net / sky2.c
index 92ea915..f8b973a 100644 (file)
@@ -57,7 +57,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "0.12"
+#define DRV_VERSION            "0.13"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -92,7 +92,7 @@
 static const u32 default_msg =
     NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
     | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
-    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_INTR;
+    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
 
 static int debug = -1;         /* defaults above */
 module_param(debug, int, 0);
@@ -704,7 +704,7 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
  * This is a workaround code taken from SysKonnect sk98lin driver
  * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
  */
-static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q,
+static void sky2_put_idx(struct sky2_hw *hw, unsigned q,
                                u16 idx, u16 *last, u16 size)
 {
        wmb();
@@ -749,7 +749,7 @@ static inline u32 high32(dma_addr_t a)
 }
 
 /* Build description to hardware about buffer */
-static inline void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
 {
        struct sky2_rx_le *le;
        u32 hi = high32(map);
@@ -889,13 +889,13 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
        struct sky2_hw *hw = sky2->hw;
        u16 port = sky2->port;
 
-       spin_lock(&sky2->tx_lock);
+       spin_lock_bh(&sky2->tx_lock);
 
        sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
        sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
        sky2->vlgrp = grp;
 
-       spin_unlock(&sky2->tx_lock);
+       spin_unlock_bh(&sky2->tx_lock);
 }
 
 static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -904,14 +904,14 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
        struct sky2_hw *hw = sky2->hw;
        u16 port = sky2->port;
 
-       spin_lock(&sky2->tx_lock);
+       spin_lock_bh(&sky2->tx_lock);
 
        sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
        sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
        if (sky2->vlgrp)
                sky2->vlgrp->vlan_devices[vid] = NULL;
 
-       spin_unlock(&sky2->tx_lock);
+       spin_unlock_bh(&sky2->tx_lock);
 }
 #endif
 
@@ -1080,7 +1080,7 @@ static inline int tx_avail(const struct sky2_port *sky2)
 }
 
 /* Estimate of number of transmit list elements required */
-static inline unsigned tx_le_req(const struct sk_buff *skb)
+static unsigned tx_le_req(const struct sk_buff *skb)
 {
        unsigned count;
 
@@ -1116,6 +1116,10 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
        u16 mss;
        u8 ctrl;
 
+       /* No BH disabling for tx_lock here.  We are running in BH disabled
+        * context and TX reclaim runs via poll inside of a software
+        * interrupt, and no related locks in IRQ processing.
+        */
        if (!spin_trylock(&sky2->tx_lock))
                return NETDEV_TX_LOCKED;
 
@@ -1125,8 +1129,9 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                 */
                if (!netif_queue_stopped(dev)) {
                        netif_stop_queue(dev);
-                       printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
-                              dev->name);
+                       if (net_ratelimit())
+                               printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+                                      dev->name);
                }
                spin_unlock(&sky2->tx_lock);
 
@@ -1307,17 +1312,17 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
                dev_kfree_skb_any(skb);
        }
 
-       spin_lock(&sky2->tx_lock);
        sky2->tx_cons = put;
        if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE)
                netif_wake_queue(dev);
-       spin_unlock(&sky2->tx_lock);
 }
 
 /* Cleanup all untransmitted buffers, assume transmitter not running */
 static void sky2_tx_clean(struct sky2_port *sky2)
 {
+       spin_lock_bh(&sky2->tx_lock);
        sky2_tx_complete(sky2, sky2->tx_prod);
+       spin_unlock_bh(&sky2->tx_lock);
 }
 
 /* Network shutdown */
@@ -1607,28 +1612,40 @@ out:
        local_irq_enable();
 }
 
+
+/* Transmit timeout is only called if we are running, carries is up
+ * and tx queue is full (stopped).
+ */
 static void sky2_tx_timeout(struct net_device *dev)
 {
        struct sky2_port *sky2 = netdev_priv(dev);
        struct sky2_hw *hw = sky2->hw;
        unsigned txq = txqaddr[sky2->port];
+       u16 ridx;
+
+       /* Maybe we just missed an status interrupt */
+       spin_lock(&sky2->tx_lock);
+       ridx = sky2_read16(hw,
+                          sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX);
+       sky2_tx_complete(sky2, ridx);
+       spin_unlock(&sky2->tx_lock);
+
+       if (!netif_queue_stopped(dev)) {
+               if (net_ratelimit())
+                       pr_info(PFX "transmit interrupt missed? recovered\n");
+               return;
+       }
 
        if (netif_msg_timer(sky2))
                printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
 
-       netif_stop_queue(dev);
-
        sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
-       sky2_read32(hw, Q_ADDR(txq, Q_CSR));
-
        sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
 
        sky2_tx_clean(sky2);
 
        sky2_qset(hw, txq);
        sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
-
-       netif_wake_queue(dev);
 }
 
 
@@ -1770,7 +1787,7 @@ oversize:
 error:
        ++sky2->net_stats.rx_errors;
 
-       if (netif_msg_rx_err(sky2))
+       if (netif_msg_rx_err(sky2) && net_ratelimit())
                printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
                       sky2->netdev->name, status, length);
 
@@ -1791,13 +1808,16 @@ error:
  */
 #define TX_NO_STATUS   0xffff
 
-static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
+static void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
 {
        if (last != TX_NO_STATUS) {
                struct net_device *dev = hw->dev[port];
                if (dev && netif_running(dev)) {
                        struct sky2_port *sky2 = netdev_priv(dev);
+
+                       spin_lock(&sky2->tx_lock);
                        sky2_tx_complete(sky2, last);
+                       spin_unlock(&sky2->tx_lock);
                }
        }
 }
@@ -1920,35 +1940,42 @@ static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
 {
        struct net_device *dev = hw->dev[port];
 
-       printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
-              dev->name, status);
+       if (net_ratelimit())
+               printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
+                      dev->name, status);
 
        if (status & Y2_IS_PAR_RD1) {
-               printk(KERN_ERR PFX "%s: ram data read parity error\n",
-                      dev->name);
+               if (net_ratelimit())
+                       printk(KERN_ERR PFX "%s: ram data read parity error\n",
+                              dev->name);
                /* Clear IRQ */
                sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
        }
 
        if (status & Y2_IS_PAR_WR1) {
-               printk(KERN_ERR PFX "%s: ram data write parity error\n",
-                      dev->name);
+               if (net_ratelimit())
+                       printk(KERN_ERR PFX "%s: ram data write parity error\n",
+                              dev->name);
 
                sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
        }
 
        if (status & Y2_IS_PAR_MAC1) {
-               printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
+               if (net_ratelimit())
+                       printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
                sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
        }
 
        if (status & Y2_IS_PAR_RX1) {
-               printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
+               if (net_ratelimit())
+                       printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
                sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
        }
 
        if (status & Y2_IS_TCP_TXA1) {
-               printk(KERN_ERR PFX "%s: TCP segmentation error\n", dev->name);
+               if (net_ratelimit())
+                       printk(KERN_ERR PFX "%s: TCP segmentation error\n",
+                              dev->name);
                sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
        }
 }
@@ -1964,8 +1991,9 @@ static void sky2_hw_intr(struct sky2_hw *hw)
                u16 pci_err;
 
                pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err);
-               printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
-                      pci_name(hw->pdev), pci_err);
+               if (net_ratelimit())
+                       printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
+                              pci_name(hw->pdev), pci_err);
 
                sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
                pci_write_config_word(hw->pdev, PCI_STATUS,
@@ -1979,8 +2007,9 @@ static void sky2_hw_intr(struct sky2_hw *hw)
 
                pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err);
 
-               printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
-                      pci_name(hw->pdev), pex_err);
+               if (net_ratelimit())
+                       printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
+                              pci_name(hw->pdev), pex_err);
 
                /* clear the interrupt */
                sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
@@ -2270,7 +2299,7 @@ static int sky2_reset(struct sky2_hw *hw)
        return 0;
 }
 
-static inline u32 sky2_supported_modes(const struct sky2_hw *hw)
+static u32 sky2_supported_modes(const struct sky2_hw *hw)
 {
        u32 modes;
        if (hw->copper) {
@@ -3015,7 +3044,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        return dev;
 }
 
-static inline void sky2_show_addr(struct net_device *dev)
+static void __devinit sky2_show_addr(struct net_device *dev)
 {
        const struct sky2_port *sky2 = netdev_priv(dev);
 
@@ -3089,14 +3118,13 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 #endif
 
        err = -ENOMEM;
-       hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+       hw = kzalloc(sizeof(*hw), GFP_KERNEL);
        if (!hw) {
                printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
                       pci_name(pdev));
                goto err_out_free_regions;
        }
 
-       memset(hw, 0, sizeof(*hw));
        hw->pdev = pdev;
 
        hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);