• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisión50b0df814b0f75c08a3d45a017016a75af3edb5d (tree)
Tiempo2014-02-07 23:17:05
AutorAlexey Brodkin <Alexey.Brodkin@syno...>
CommiterTom Rini

Log Message

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:

  • Flush Tx/Rx buffer descriptors their modification
  • Invalidate Tx/Rx buffer descriptors before reading its values
  • Flush cache for data passed from CPU to GMAC
  • Invalidate cache for data passed from GMAC to CPU

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>

Cambiar Resumen

Diferencia incremental

--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -119,6 +119,11 @@ static void tx_descs_init(struct eth_device *dev)
119119 /* Correcting the last pointer of the chain */
120120 desc_p->dmamac_next = &desc_table_p[0];
121121
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+
122127 writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
123128 priv->tx_currdescnum = 0;
124129 }
@@ -132,6 +137,15 @@ static void rx_descs_init(struct eth_device *dev)
132137 struct dmamacdescr *desc_p;
133138 u32 idx;
134139
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+
135149 for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
136150 desc_p = &desc_table_p[idx];
137151 desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
@@ -147,6 +161,11 @@ static void rx_descs_init(struct eth_device *dev)
147161 /* Correcting the last pointer of the chain */
148162 desc_p->dmamac_next = &desc_table_p[0];
149163
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+
150169 writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
151170 priv->rx_currdescnum = 0;
152171 }
@@ -261,6 +280,11 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
261280 u32 desc_num = priv->tx_currdescnum;
262281 struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
263282
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+
264288 /* Check if the descriptor is owned by CPU */
265289 if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
266290 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)
269293
270294 memcpy((void *)desc_p->dmamac_addr, packet, length);
271295
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+
272300 #if defined(CONFIG_DW_ALTDESCRIPTOR)
273301 desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
274302 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)
284312 desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
285313 #endif
286314
315+ /* Flush modified buffer descriptor */
316+ flush_dcache_range((unsigned long)desc_p,
317+ (unsigned long)desc_p + sizeof(struct dmamacdescr));
318+
287319 /* Test the wrap-around condition. */
288320 if (++desc_num >= CONFIG_TX_DESCR_NUM)
289321 desc_num = 0;
@@ -299,18 +331,28 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
299331 static int dw_eth_recv(struct eth_device *dev)
300332 {
301333 struct dw_eth_dev *priv = dev->priv;
302- u32 desc_num = priv->rx_currdescnum;
334+ u32 status, desc_num = priv->rx_currdescnum;
303335 struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
304-
305- u32 status = desc_p->txrx_status;
306336 int length = 0;
307337
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+
308345 /* Check if the owner is the CPU */
309346 if (!(status & DESC_RXSTS_OWNBYDMA)) {
310347
311348 length = (status & DESC_RXSTS_FRMLENMSK) >> \
312349 DESC_RXSTS_FRMLENSHFT;
313350
351+ /* Invalidate received data */
352+ invalidate_dcache_range((unsigned long)desc_p->dmamac_addr,
353+ (unsigned long)desc_p->dmamac_addr +
354+ length);
355+
314356 NetReceive(desc_p->dmamac_addr, length);
315357
316358 /*
@@ -319,6 +361,11 @@ static int dw_eth_recv(struct eth_device *dev)
319361 */
320362 desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
321363
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+
322369 /* Test the wrap-around condition. */
323370 if (++desc_num >= CONFIG_RX_DESCR_NUM)
324371 desc_num = 0;