Revisión | 50b0df814b0f75c08a3d45a017016a75af3edb5d (tree) |
---|---|
Tiempo | 2014-02-07 23:17:05 |
Autor | Alexey Brodkin <Alexey.Brodkin@syno...> |
Commiter | Tom Rini |
net/designware: make driver compatible with data cache
Up until now this driver only worked with data cache disabled.
To make it work with enabled data cache following changes were required:
Cc: Joe Hershberger <joe.hershberger@ni.com>
Cc: Vipin Kumar <vipin.kumar@st.com>
Cc: Stefan Roese <sr@denx.de>
Cc: Mischa Jonker <mjonker@synopsys.com>
Cc: Shiraz Hashim <shiraz.hashim@st.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Cc: Amit Virdi <amit.virdi@st.com>
Cc: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
@@ -119,6 +119,11 @@ static void tx_descs_init(struct eth_device *dev) | ||
119 | 119 | /* Correcting the last pointer of the chain */ |
120 | 120 | desc_p->dmamac_next = &desc_table_p[0]; |
121 | 121 | |
122 | + /* Flush all Tx buffer descriptors at once */ | |
123 | + flush_dcache_range((unsigned int)priv->tx_mac_descrtable, | |
124 | + (unsigned int)priv->tx_mac_descrtable + | |
125 | + sizeof(priv->tx_mac_descrtable)); | |
126 | + | |
122 | 127 | writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr); |
123 | 128 | priv->tx_currdescnum = 0; |
124 | 129 | } |
@@ -132,6 +137,15 @@ static void rx_descs_init(struct eth_device *dev) | ||
132 | 137 | struct dmamacdescr *desc_p; |
133 | 138 | u32 idx; |
134 | 139 | |
140 | + /* Before passing buffers to GMAC we need to make sure zeros | |
141 | + * written there right after "priv" structure allocation were | |
142 | + * flushed into RAM. | |
143 | + * Otherwise there's a chance to get some of them flushed in RAM when | |
144 | + * GMAC is already pushing data to RAM via DMA. This way incoming from | |
145 | + * GMAC data will be corrupted. */ | |
146 | + flush_dcache_range((unsigned int)rxbuffs, (unsigned int)rxbuffs + | |
147 | + RX_TOTAL_BUFSIZE); | |
148 | + | |
135 | 149 | for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) { |
136 | 150 | desc_p = &desc_table_p[idx]; |
137 | 151 | desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE]; |
@@ -147,6 +161,11 @@ static void rx_descs_init(struct eth_device *dev) | ||
147 | 161 | /* Correcting the last pointer of the chain */ |
148 | 162 | desc_p->dmamac_next = &desc_table_p[0]; |
149 | 163 | |
164 | + /* Flush all Rx buffer descriptors at once */ | |
165 | + flush_dcache_range((unsigned int)priv->rx_mac_descrtable, | |
166 | + (unsigned int)priv->rx_mac_descrtable + | |
167 | + sizeof(priv->rx_mac_descrtable)); | |
168 | + | |
150 | 169 | writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr); |
151 | 170 | priv->rx_currdescnum = 0; |
152 | 171 | } |
@@ -261,6 +280,11 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) | ||
261 | 280 | u32 desc_num = priv->tx_currdescnum; |
262 | 281 | struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; |
263 | 282 | |
283 | + /* Invalidate only "status" field for the following check */ | |
284 | + invalidate_dcache_range((unsigned long)&desc_p->txrx_status, | |
285 | + (unsigned long)&desc_p->txrx_status + | |
286 | + sizeof(desc_p->txrx_status)); | |
287 | + | |
264 | 288 | /* Check if the descriptor is owned by CPU */ |
265 | 289 | if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { |
266 | 290 | printf("CPU not owner of tx frame\n"); |
@@ -269,6 +293,10 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) | ||
269 | 293 | |
270 | 294 | memcpy((void *)desc_p->dmamac_addr, packet, length); |
271 | 295 | |
296 | + /* Flush data to be sent */ | |
297 | + flush_dcache_range((unsigned long)desc_p->dmamac_addr, | |
298 | + (unsigned long)desc_p->dmamac_addr + length); | |
299 | + | |
272 | 300 | #if defined(CONFIG_DW_ALTDESCRIPTOR) |
273 | 301 | desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; |
274 | 302 | desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \ |
@@ -284,6 +312,10 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) | ||
284 | 312 | desc_p->txrx_status = DESC_TXSTS_OWNBYDMA; |
285 | 313 | #endif |
286 | 314 | |
315 | + /* Flush modified buffer descriptor */ | |
316 | + flush_dcache_range((unsigned long)desc_p, | |
317 | + (unsigned long)desc_p + sizeof(struct dmamacdescr)); | |
318 | + | |
287 | 319 | /* Test the wrap-around condition. */ |
288 | 320 | if (++desc_num >= CONFIG_TX_DESCR_NUM) |
289 | 321 | desc_num = 0; |
@@ -299,18 +331,28 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) | ||
299 | 331 | static int dw_eth_recv(struct eth_device *dev) |
300 | 332 | { |
301 | 333 | struct dw_eth_dev *priv = dev->priv; |
302 | - u32 desc_num = priv->rx_currdescnum; | |
334 | + u32 status, desc_num = priv->rx_currdescnum; | |
303 | 335 | struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; |
304 | - | |
305 | - u32 status = desc_p->txrx_status; | |
306 | 336 | int length = 0; |
307 | 337 | |
338 | + /* Invalidate entire buffer descriptor */ | |
339 | + invalidate_dcache_range((unsigned long)desc_p, | |
340 | + (unsigned long)desc_p + | |
341 | + sizeof(struct dmamacdescr)); | |
342 | + | |
343 | + status = desc_p->txrx_status; | |
344 | + | |
308 | 345 | /* Check if the owner is the CPU */ |
309 | 346 | if (!(status & DESC_RXSTS_OWNBYDMA)) { |
310 | 347 | |
311 | 348 | length = (status & DESC_RXSTS_FRMLENMSK) >> \ |
312 | 349 | DESC_RXSTS_FRMLENSHFT; |
313 | 350 | |
351 | + /* Invalidate received data */ | |
352 | + invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, | |
353 | + (unsigned long)desc_p->dmamac_addr + | |
354 | + length); | |
355 | + | |
314 | 356 | NetReceive(desc_p->dmamac_addr, length); |
315 | 357 | |
316 | 358 | /* |
@@ -319,6 +361,11 @@ static int dw_eth_recv(struct eth_device *dev) | ||
319 | 361 | */ |
320 | 362 | desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; |
321 | 363 | |
364 | + /* Flush only status field - others weren't changed */ | |
365 | + flush_dcache_range((unsigned long)&desc_p->txrx_status, | |
366 | + (unsigned long)&desc_p->txrx_status + | |
367 | + sizeof(desc_p->txrx_status)); | |
368 | + | |
322 | 369 | /* Test the wrap-around condition. */ |
323 | 370 | if (++desc_num >= CONFIG_RX_DESCR_NUM) |
324 | 371 | desc_num = 0; |