linux-dreambox-3.4: add bcmgenet fix from stblinux-3.3-3.6
[opendreambox.git] / meta-dreambox / recipes-kernel / linux / linux-dreambox-3.4 / backport_bcmgenet_fix_from_3.3-3.6.patch
1 diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
2 index 754c39a..97fad5a 100644
3 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
4 +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
5 @@ -619,6 +619,40 @@ err2:
6  
7         return -ENODEV;
8  }
9 +
10 +static void bcmgenet_free_rx_buffers(struct BcmEnet_devctrl *pDevCtrl)
11 +{
12 +       struct Enet_CB *cb;
13 +       unsigned int i;
14 +       unsigned int freed = 0;
15 +
16 +       for (i = 0; i < pDevCtrl->nrRxBds; i++) {
17 +               cb = &pDevCtrl->rxCbs[i];
18 +
19 +               if (dma_unmap_addr(cb, dma_addr)) {
20 +                       dma_unmap_single(&pDevCtrl->dev->dev,
21 +                                        dma_unmap_addr(cb, dma_addr),
22 +                                        pDevCtrl->rxBufLen, DMA_FROM_DEVICE);
23 +                       dma_unmap_addr_set(cb, dma_addr, 0);
24 +               }
25 +
26 +               if (cb->skb) {
27 +                       freed++;
28 +                       dev_kfree_skb(pDevCtrl->rxCbs[i].skb);
29 +                       cb->skb = NULL;
30 +               }
31 +
32 +               /* Reset the address to 0, such that next calls to assign_rx_buffers
33 +                * re-allocate buffers
34 +                */
35 +               pDevCtrl->rxBds[i].address = 0;
36 +       }
37 +
38 +       pDevCtrl->rxBdAssignPtr = pDevCtrl->rxBds;
39 +
40 +       TRACE(("%s: freed: %d SKBs\n", __func__, freed));
41 +}
42 +
43  /* --------------------------------------------------------------------------
44  Name: bcmgenet_close
45  Purpose: Stop communicating with the outside world
46 @@ -690,6 +724,8 @@ static int bcmgenet_close(struct net_device *dev)
47  
48         if (brcm_pm_deep_sleep())
49                 save_state(pDevCtrl);
50 +       else
51 +               bcmgenet_free_rx_buffers(pDevCtrl);
52  
53         if (device_may_wakeup(&dev->dev) && pDevCtrl->dev_asleep) {
54                 if (pDevCtrl->wolopts & (WAKE_MAGIC|WAKE_MAGICSECURE))
55 @@ -1936,6 +1972,7 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
56         struct BcmEnet_devctrl *pDevCtrl = dev_id;
57         volatile struct intrl2Regs *intrl2 = pDevCtrl->intrl2_1;
58         unsigned int index;
59 +       unsigned long flags;
60  
61         /* Save irq status for bottom-half processing. */
62         pDevCtrl->irq1_stat = intrl2->cpu_stat & ~intrl2->cpu_mask_status;
63 @@ -1950,8 +1987,11 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
64         if (pDevCtrl->irq1_stat & 0x0000ffff) {
65                 index = 0;
66                 for (index = 0; index < 16; index++) {
67 -                       if (pDevCtrl->irq1_stat & (1<<index))
68 +                       if (pDevCtrl->irq1_stat & (1<<index)) {
69 +                               spin_lock_irqsave(&pDevCtrl->lock, flags);
70                                 bcmgenet_tx_reclaim(pDevCtrl->dev, index);
71 +                               spin_unlock_irqrestore(&pDevCtrl->lock, flags);
72 +                       }
73                 }
74         }
75  
76 @@ -2215,7 +2255,6 @@ static int assign_rx_buffers(struct BcmEnet_devctrl *pDevCtrl)
77                 handleAlignment(pDevCtrl, skb);
78  
79                 /* keep count of any BD's we refill */
80 -               bdsfilled++;
81                 cb->skb = skb;
82                 mapping = dma_map_single(&pDevCtrl->dev->dev,
83                         skb->data, pDevCtrl->rxBufLen, DMA_FROM_DEVICE);
84 @@ -2236,6 +2275,7 @@ static int assign_rx_buffers(struct BcmEnet_devctrl *pDevCtrl)
85                 else
86                         pDevCtrl->rxBdAssignPtr++;
87  
88 +               bdsfilled++;
89         }
90  
91         /* Enable rx DMA incase it was disabled due to running out of rx BD */
92 @@ -2811,13 +2851,6 @@ static int bcmgenet_init_dev(struct BcmEnet_devctrl *pDevCtrl, bool reset)
93         lastBd = pDevCtrl->txBds + pDevCtrl->nrTxBds - 1;
94         pDevCtrl->txFreeBds = pDevCtrl->nrTxBds;
95  
96 -       /* fill receive buffers */
97 -       if (assign_rx_buffers(pDevCtrl) == 0) {
98 -               printk(KERN_ERR "Failed to assign rx buffers\n");
99 -               ret = -ENOMEM;
100 -               goto error1;
101 -       }
102 -
103         TRACE(("%s done!\n", __func__));
104         /* init umac registers */
105         if (init_umac(pDevCtrl, reset)) {
106 @@ -2861,12 +2894,8 @@ static void bcmgenet_uninit_dev(struct BcmEnet_devctrl *pDevCtrl)
107                                 pDevCtrl->txCbs[i].skb = NULL;
108                         }
109                 }
110 -               for (i = 0; i < pDevCtrl->nrRxBds; i++) {
111 -                       if (pDevCtrl->rxCbs[i].skb != NULL) {
112 -                               dev_kfree_skb(pDevCtrl->rxCbs[i].skb);
113 -                               pDevCtrl->rxCbs[i].skb = NULL;
114 -                       }
115 -               }
116 +
117 +               bcmgenet_free_rx_buffers(pDevCtrl);
118  
119                 /* free the transmit buffer descriptor */
120                 if (pDevCtrl->txBds)