a49bd5f5e70d218b0d4ad1c3f58bd966694bb1d7
[openwrt.git] / target / linux / generic / patches-3.18 / 077-10-bgmac-simplify-dma-init-cleanup.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Sun, 12 Apr 2015 23:19:32 +0200
3 Subject: [PATCH] bgmac: simplify dma init/cleanup
4
5 Instead of allocating buffers at device init time and initializing
6 descriptors at device open, do both at the same time (during open).
7 Free all buffers when closing the device.
8
9 Signed-off-by: Felix Fietkau <nbd@nbd.name>
10 ---
11
12 --- a/drivers/net/ethernet/broadcom/bgmac.c
13 +++ b/drivers/net/ethernet/broadcom/bgmac.c
14 @@ -562,18 +562,26 @@ static void bgmac_dma_ring_desc_free(str
15                           ring->dma_base);
16  }
17  
18 -static void bgmac_dma_free(struct bgmac *bgmac)
19 +static void bgmac_dma_cleanup(struct bgmac *bgmac)
20  {
21         int i;
22  
23 -       for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
24 +       for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
25                 bgmac_dma_tx_ring_free(bgmac, &bgmac->tx_ring[i]);
26 -               bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]);
27 -       }
28 -       for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
29 +
30 +       for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
31                 bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]);
32 +}
33 +
34 +static void bgmac_dma_free(struct bgmac *bgmac)
35 +{
36 +       int i;
37 +
38 +       for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
39 +               bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]);
40 +
41 +       for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
42                 bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]);
43 -       }
44  }
45  
46  static int bgmac_dma_alloc(struct bgmac *bgmac)
47 @@ -621,8 +629,6 @@ static int bgmac_dma_alloc(struct bgmac
48         }
49  
50         for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
51 -               int j;
52 -
53                 ring = &bgmac->rx_ring[i];
54                 ring->num_slots = BGMAC_RX_RING_SLOTS;
55                 ring->mmio_base = ring_base[i];
56 @@ -645,15 +651,6 @@ static int bgmac_dma_alloc(struct bgmac
57                         ring->index_base = lower_32_bits(ring->dma_base);
58                 else
59                         ring->index_base = 0;
60 -
61 -               /* Alloc RX slots */
62 -               for (j = 0; j < ring->num_slots; j++) {
63 -                       err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
64 -                       if (err) {
65 -                               bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n");
66 -                               goto err_dma_free;
67 -                       }
68 -               }
69         }
70  
71         return 0;
72 @@ -663,10 +660,10 @@ err_dma_free:
73         return -ENOMEM;
74  }
75  
76 -static void bgmac_dma_init(struct bgmac *bgmac)
77 +static int bgmac_dma_init(struct bgmac *bgmac)
78  {
79         struct bgmac_dma_ring *ring;
80 -       int i;
81 +       int i, err;
82  
83         for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
84                 ring = &bgmac->tx_ring[i];
85 @@ -698,8 +695,13 @@ static void bgmac_dma_init(struct bgmac
86                 if (ring->unaligned)
87                         bgmac_dma_rx_enable(bgmac, ring);
88  
89 -               for (j = 0; j < ring->num_slots; j++)
90 +               for (j = 0; j < ring->num_slots; j++) {
91 +                       err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
92 +                       if (err)
93 +                               goto error;
94 +
95                         bgmac_dma_rx_setup_desc(bgmac, ring, j);
96 +               }
97  
98                 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
99                             ring->index_base +
100 @@ -708,6 +710,12 @@ static void bgmac_dma_init(struct bgmac
101                 ring->start = 0;
102                 ring->end = 0;
103         }
104 +
105 +       return 0;
106 +
107 +error:
108 +       bgmac_dma_cleanup(bgmac);
109 +       return err;
110  }
111  
112  /**************************************************
113 @@ -1183,11 +1191,8 @@ static void bgmac_enable(struct bgmac *b
114  }
115  
116  /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
117 -static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
118 +static void bgmac_chip_init(struct bgmac *bgmac)
119  {
120 -       struct bgmac_dma_ring *ring;
121 -       int i;
122 -
123         /* 1 interrupt per received frame */
124         bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
125  
126 @@ -1205,16 +1210,7 @@ static void bgmac_chip_init(struct bgmac
127  
128         bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
129  
130 -       if (full_init) {
131 -               bgmac_dma_init(bgmac);
132 -               if (1) /* FIXME: is there any case we don't want IRQs? */
133 -                       bgmac_chip_intrs_on(bgmac);
134 -       } else {
135 -               for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
136 -                       ring = &bgmac->rx_ring[i];
137 -                       bgmac_dma_rx_enable(bgmac, ring);
138 -               }
139 -       }
140 +       bgmac_chip_intrs_on(bgmac);
141  
142         bgmac_enable(bgmac);
143  }
144 @@ -1274,23 +1270,27 @@ static int bgmac_open(struct net_device
145         int err = 0;
146  
147         bgmac_chip_reset(bgmac);
148 +
149 +       err = bgmac_dma_init(bgmac);
150 +       if (err)
151 +               return err;
152 +
153         /* Specs say about reclaiming rings here, but we do that in DMA init */
154 -       bgmac_chip_init(bgmac, true);
155 +       bgmac_chip_init(bgmac);
156  
157         err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
158                           KBUILD_MODNAME, net_dev);
159         if (err < 0) {
160                 bgmac_err(bgmac, "IRQ request error: %d!\n", err);
161 -               goto err_out;
162 +               bgmac_dma_cleanup(bgmac);
163 +               return err;
164         }
165         napi_enable(&bgmac->napi);
166  
167         phy_start(bgmac->phy_dev);
168  
169         netif_carrier_on(net_dev);
170 -
171 -err_out:
172 -       return err;
173 +       return 0;
174  }
175  
176  static int bgmac_stop(struct net_device *net_dev)
177 @@ -1306,6 +1306,7 @@ static int bgmac_stop(struct net_device
178         free_irq(bgmac->core->irq, net_dev);
179  
180         bgmac_chip_reset(bgmac);
181 +       bgmac_dma_cleanup(bgmac);
182  
183         return 0;
184  }