net: systemport: fix TX NAPI work done return value
[deliverable/linux.git] / drivers / net / ethernet / broadcom / bcmsysport.c
index dc708a888f802ccc8e910bfdd46944fa4a8f78c5..5776e503e4c57eb374e304fecc8e0fa44e2e5f85 100644 (file)
@@ -457,7 +457,7 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
        struct sk_buff *skb;
        unsigned int p_index;
        u16 len, status;
-       struct rsb *rsb;
+       struct bcm_rsb *rsb;
 
        /* Determine how much we should process since last call */
        p_index = rdma_readl(priv, RDMA_PROD_INDEX);
@@ -482,7 +482,7 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
                                RX_BUF_LENGTH, DMA_FROM_DEVICE);
 
                /* Extract the Receive Status Block prepended */
-               rsb = (struct rsb *)skb->data;
+               rsb = (struct bcm_rsb *)skb->data;
                len = (rsb->rx_status_len >> DESC_LEN_SHIFT) & DESC_LEN_MASK;
                status = (rsb->rx_status_len >> DESC_STATUS_SHIFT) &
                        DESC_STATUS_MASK;
@@ -514,7 +514,7 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
 
                if (unlikely(status & (RX_STATUS_ERR | RX_STATUS_OVFLOW))) {
                        netif_err(priv, rx_err, ndev, "error packet\n");
-                       if (RX_STATUS_OVFLOW)
+                       if (status & RX_STATUS_OVFLOW)
                                ndev->stats.rx_over_errors++;
                        ndev->stats.rx_dropped++;
                        ndev->stats.rx_errors++;
@@ -528,9 +528,9 @@ static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
                if (likely(status & DESC_L4_CSUM))
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-               /* Hardware pre-pends packets with 2bytes between Ethernet
-                * and IP header plus we have the Receive Status Block, strip
-                * off all of this from the SKB.
+               /* Hardware pre-pends packets with 2bytes before Ethernet
+                * header plus we have the Receive Status Block, strip off all
+                * of this from the SKB.
                 */
                skb_pull(skb, sizeof(*rsb) + 2);
                len -= (sizeof(*rsb) + 2);
@@ -637,10 +637,11 @@ static unsigned int bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
                                           struct bcm_sysport_tx_ring *ring)
 {
        unsigned int released;
+       unsigned long flags;
 
-       spin_lock(&ring->lock);
+       spin_lock_irqsave(&ring->lock, flags);
        released = __bcm_sysport_tx_reclaim(priv, ring);
-       spin_unlock(&ring->lock);
+       spin_unlock_irqrestore(&ring->lock, flags);
 
        return released;
 }
@@ -653,13 +654,13 @@ static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
 
        work_done = bcm_sysport_tx_reclaim(ring->priv, ring);
 
-       if (work_done < budget) {
+       if (work_done == 0) {
                napi_complete(napi);
                /* re-enable TX interrupt */
                intrl2_1_mask_clear(ring->priv, BIT(ring->index));
        }
 
-       return work_done;
+       return 0;
 }
 
 static void bcm_sysport_tx_reclaim_all(struct bcm_sysport_priv *priv)
@@ -759,7 +760,7 @@ static irqreturn_t bcm_sysport_tx_isr(int irq, void *dev_id)
 static int bcm_sysport_insert_tsb(struct sk_buff *skb, struct net_device *dev)
 {
        struct sk_buff *nskb;
-       struct tsb *tsb;
+       struct bcm_tsb *tsb;
        u32 csum_info;
        u8 ip_proto;
        u16 csum_start;
@@ -777,7 +778,7 @@ static int bcm_sysport_insert_tsb(struct sk_buff *skb, struct net_device *dev)
                skb = nskb;
        }
 
-       tsb = (struct tsb *)skb_push(skb, sizeof(*tsb));
+       tsb = (struct bcm_tsb *)skb_push(skb, sizeof(*tsb));
        /* Zero-out TSB by default */
        memset(tsb, 0, sizeof(*tsb));
 
@@ -822,6 +823,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
        struct netdev_queue *txq;
        struct dma_desc *desc;
        unsigned int skb_len;
+       unsigned long flags;
        dma_addr_t mapping;
        u32 len_status;
        u16 queue;
@@ -831,8 +833,8 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
        txq = netdev_get_tx_queue(dev, queue);
        ring = &priv->tx_rings[queue];
 
-       /* lock against tx reclaim in BH context */
-       spin_lock(&ring->lock);
+       /* lock against tx reclaim in BH context and TX ring full interrupt */
+       spin_lock_irqsave(&ring->lock, flags);
        if (unlikely(ring->desc_count == 0)) {
                netif_tx_stop_queue(txq);
                netdev_err(dev, "queue %d awake and ring full!\n", queue);
@@ -914,7 +916,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
 
        ret = NETDEV_TX_OK;
 out:
-       spin_unlock(&ring->lock);
+       spin_unlock_irqrestore(&ring->lock, flags);
        return ret;
 }
 
@@ -1252,28 +1254,17 @@ static inline void umac_enable_set(struct bcm_sysport_priv *priv,
                usleep_range(1000, 2000);
 }
 
-static inline int umac_reset(struct bcm_sysport_priv *priv)
+static inline void umac_reset(struct bcm_sysport_priv *priv)
 {
-       unsigned int timeout = 0;
        u32 reg;
-       int ret = 0;
-
-       umac_writel(priv, 0, UMAC_CMD);
-       while (timeout++ < 1000) {
-               reg = umac_readl(priv, UMAC_CMD);
-               if (!(reg & CMD_SW_RESET))
-                       break;
-
-               udelay(1);
-       }
-
-       if (timeout == 1000) {
-               dev_err(&priv->pdev->dev,
-                       "timeout waiting for MAC to come out of reset\n");
-               ret = -ETIMEDOUT;
-       }
 
-       return ret;
+       reg = umac_readl(priv, UMAC_CMD);
+       reg |= CMD_SW_RESET;
+       umac_writel(priv, reg, UMAC_CMD);
+       udelay(10);
+       reg = umac_readl(priv, UMAC_CMD);
+       reg &= ~CMD_SW_RESET;
+       umac_writel(priv, reg, UMAC_CMD);
 }
 
 static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
@@ -1301,11 +1292,7 @@ static int bcm_sysport_open(struct net_device *dev)
        int ret;
 
        /* Reset UniMAC */
-       ret = umac_reset(priv);
-       if (ret) {
-               netdev_err(dev, "UniMAC reset failed\n");
-               return ret;
-       }
+       umac_reset(priv);
 
        /* Flush TX and RX FIFOs at TOPCTRL level */
        topctrl_flush(priv);
@@ -1584,14 +1571,11 @@ static int bcm_sysport_probe(struct platform_device *pdev)
                                NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 
        /* Set the needed headroom once and for all */
-       BUILD_BUG_ON(sizeof(struct tsb) != 8);
-       dev->needed_headroom += sizeof(struct tsb);
+       BUILD_BUG_ON(sizeof(struct bcm_tsb) != 8);
+       dev->needed_headroom += sizeof(struct bcm_tsb);
 
-       /* We are interfaced to a switch which handles the multicast
-        * filtering for us, so we do not support programming any
-        * multicast hash table in this Ethernet MAC.
-        */
-       dev->flags &= ~IFF_MULTICAST;
+       /* libphy will adjust the link state accordingly */
+       netif_carrier_off(dev);
 
        ret = register_netdev(dev);
        if (ret) {
This page took 0.145987 seconds and 5 git commands to generate.