1 From: Felix Fietkau <nbd@openwrt.org>
2 Date: Sun, 12 Apr 2015 23:19:32 +0200
3 Subject: [PATCH] bgmac: simplify dma init/cleanup
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.
9 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
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
18 -static void bgmac_dma_free(struct bgmac *bgmac)
19 +static void bgmac_dma_cleanup(struct bgmac *bgmac)
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]);
28 - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
30 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
31 bgmac_dma_rx_ring_free(bgmac, &bgmac->rx_ring[i]);
34 +static void bgmac_dma_free(struct bgmac *bgmac)
38 + for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
39 + bgmac_dma_ring_desc_free(bgmac, &bgmac->tx_ring[i]);
41 + for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
42 bgmac_dma_ring_desc_free(bgmac, &bgmac->rx_ring[i]);
46 static int bgmac_dma_alloc(struct bgmac *bgmac)
47 @@ -621,8 +629,6 @@ static int bgmac_dma_alloc(struct bgmac
50 for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
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);
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]);
65 - bgmac_err(bgmac, "Can't allocate skb for slot in RX ring\n");
72 @@ -663,10 +660,10 @@ err_dma_free:
76 -static void bgmac_dma_init(struct bgmac *bgmac)
77 +static int bgmac_dma_init(struct bgmac *bgmac)
79 struct bgmac_dma_ring *ring;
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
87 bgmac_dma_rx_enable(bgmac, ring);
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]);
95 bgmac_dma_rx_setup_desc(bgmac, ring, j);
98 bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
100 @@ -708,6 +710,12 @@ static void bgmac_dma_init(struct bgmac
108 + bgmac_dma_cleanup(bgmac);
112 /**************************************************
113 @@ -1183,11 +1191,8 @@ static void bgmac_enable(struct bgmac *b
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)
120 - struct bgmac_dma_ring *ring;
123 /* 1 interrupt per received frame */
124 bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
126 @@ -1205,16 +1210,7 @@ static void bgmac_chip_init(struct bgmac
128 bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
131 - bgmac_dma_init(bgmac);
132 - if (1) /* FIXME: is there any case we don't want IRQs? */
133 - bgmac_chip_intrs_on(bgmac);
135 - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
136 - ring = &bgmac->rx_ring[i];
137 - bgmac_dma_rx_enable(bgmac, ring);
140 + bgmac_chip_intrs_on(bgmac);
144 @@ -1274,23 +1270,27 @@ static int bgmac_open(struct net_device
147 bgmac_chip_reset(bgmac);
149 + err = bgmac_dma_init(bgmac);
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);
157 err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
158 KBUILD_MODNAME, net_dev);
160 bgmac_err(bgmac, "IRQ request error: %d!\n", err);
162 + bgmac_dma_cleanup(bgmac);
165 napi_enable(&bgmac->napi);
167 phy_start(bgmac->phy_dev);
169 netif_carrier_on(net_dev);
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);
180 bgmac_chip_reset(bgmac);
181 + bgmac_dma_cleanup(bgmac);