16bb64870dc06d05484d437be65ddcbb743ec515
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.18 / 077-10-bgmac-simplify-dma-init-cleanup.patch
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
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@openwrt.org>
10 ---
11
12 --- a/drivers/net/ethernet/broadcom/bgmac.c
13 +++ b/drivers/net/ethernet/broadcom/bgmac.c
14 @@ -545,18 +545,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 @@ -604,8 +612,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 @@ -628,15 +634,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 @@ -646,10 +643,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 @@ -681,8 +678,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 + return err;
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 @@ -691,6 +693,8 @@ static void bgmac_dma_init(struct bgmac
101 ring->start = 0;
102 ring->end = 0;
103 }
104 +
105 + return 0;
106 }
107
108 /**************************************************
109 @@ -1166,11 +1170,8 @@ static void bgmac_enable(struct bgmac *b
110 }
111
112 /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
113 -static void bgmac_chip_init(struct bgmac *bgmac, bool full_init)
114 +static void bgmac_chip_init(struct bgmac *bgmac)
115 {
116 - struct bgmac_dma_ring *ring;
117 - int i;
118 -
119 /* 1 interrupt per received frame */
120 bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
121
122 @@ -1188,16 +1189,7 @@ static void bgmac_chip_init(struct bgmac
123
124 bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN);
125
126 - if (full_init) {
127 - bgmac_dma_init(bgmac);
128 - if (1) /* FIXME: is there any case we don't want IRQs? */
129 - bgmac_chip_intrs_on(bgmac);
130 - } else {
131 - for (i = 0; i < BGMAC_MAX_RX_RINGS; i++) {
132 - ring = &bgmac->rx_ring[i];
133 - bgmac_dma_rx_enable(bgmac, ring);
134 - }
135 - }
136 + bgmac_chip_intrs_on(bgmac);
137
138 bgmac_enable(bgmac);
139 }
140 @@ -1257,8 +1249,13 @@ static int bgmac_open(struct net_device
141 int err = 0;
142
143 bgmac_chip_reset(bgmac);
144 +
145 + err = bgmac_dma_init(bgmac);
146 + if (err)
147 + goto err_out;
148 +
149 /* Specs say about reclaiming rings here, but we do that in DMA init */
150 - bgmac_chip_init(bgmac, true);
151 + bgmac_chip_init(bgmac);
152
153 err = request_irq(bgmac->core->irq, bgmac_interrupt, IRQF_SHARED,
154 KBUILD_MODNAME, net_dev);
155 @@ -1273,6 +1270,7 @@ static int bgmac_open(struct net_device
156 netif_carrier_on(net_dev);
157
158 err_out:
159 + bgmac_dma_cleanup(bgmac);
160 return err;
161 }
162
163 @@ -1289,6 +1287,7 @@ static int bgmac_stop(struct net_device
164 free_irq(bgmac->core->irq, net_dev);
165
166 bgmac_chip_reset(bgmac);
167 + bgmac_dma_cleanup(bgmac);
168
169 return 0;
170 }