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:
10 +static void bcmgenet_free_rx_buffers(struct BcmEnet_devctrl *pDevCtrl)
14 + unsigned int freed = 0;
16 + for (i = 0; i < pDevCtrl->nrRxBds; i++) {
17 + cb = &pDevCtrl->rxCbs[i];
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);
28 + dev_kfree_skb(pDevCtrl->rxCbs[i].skb);
32 + /* Reset the address to 0, such that next calls to assign_rx_buffers
33 + * re-allocate buffers
35 + pDevCtrl->rxBds[i].address = 0;
38 + pDevCtrl->rxBdAssignPtr = pDevCtrl->rxBds;
40 + TRACE(("%s: freed: %d SKBs\n", __func__, freed));
43 /* --------------------------------------------------------------------------
45 Purpose: Stop communicating with the outside world
46 @@ -690,6 +724,8 @@ static int bcmgenet_close(struct net_device *dev)
48 if (brcm_pm_deep_sleep())
51 + bcmgenet_free_rx_buffers(pDevCtrl);
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;
59 + unsigned long flags;
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) {
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);
76 @@ -2215,7 +2255,6 @@ static int assign_rx_buffers(struct BcmEnet_devctrl *pDevCtrl)
77 handleAlignment(pDevCtrl, skb);
79 /* keep count of any BD's we refill */
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)
86 pDevCtrl->rxBdAssignPtr++;
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;
96 - /* fill receive buffers */
97 - if (assign_rx_buffers(pDevCtrl) == 0) {
98 - printk(KERN_ERR "Failed to assign rx buffers\n");
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;
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;
117 + bcmgenet_free_rx_buffers(pDevCtrl);
119 /* free the transmit buffer descriptor */