[rtems-libbsd commit] if_ffec: Fix cache handling on tx

Christian Mauderer christianm at rtems.org
Fri Nov 20 08:00:51 UTC 2020


Module:    rtems-libbsd
Branch:    6-freebsd-12
Commit:    a58f553e9dda119aa149fd8ba814c564a5d4a9b2
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=a58f553e9dda119aa149fd8ba814c564a5d4a9b2

Author:    Christian Mauderer <christian.mauderer at embedded-brains.de>
Date:      Fri Nov  6 09:53:05 2020 +0100

if_ffec: Fix cache handling on tx

With the previous fix, it could happen that the end of the packet hasn't
been flushed. For example assume the following addresses:

ds_addr: 0x81c804A
ds_len: 0x57

In that case the data ends at 0x81c80a1. But due to the rounding the
area from 0x81c8040 to 0x81c80a0 would have been flushed.

This fix now first calculates the start and end address, aligns these
addresses and then recalculates the len that has to be flushed.

Update #4180

---

 freebsd/sys/dev/ffec/if_ffec.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/freebsd/sys/dev/ffec/if_ffec.c b/freebsd/sys/dev/ffec/if_ffec.c
index e8287ed..47c0f77 100644
--- a/freebsd/sys/dev/ffec/if_ffec.c
+++ b/freebsd/sys/dev/ffec/if_ffec.c
@@ -714,15 +714,16 @@ ffec_encap(struct ifnet *ifp, struct ffec_softc *sc, struct mbuf *m0,
 		tx_desc->buf_paddr = segs[i].ds_addr;
 		tx_desc->flags2 = flags2;
 #ifdef __rtems__
-		uintptr_t addr_flush = (uintptr_t)segs[i].ds_addr;
+		uintptr_t first_flush = (uintptr_t)segs[i].ds_addr;
 		size_t len_flush = segs[i].ds_len;
 #ifdef CPU_CACHE_LINE_BYTES
+		uintptr_t last_flush = first_flush + len_flush;
 		/* mbufs should be cache line aligned. So we can just round. */
-		addr_flush = addr_flush & ~(CPU_CACHE_LINE_BYTES - 1);
-		len_flush = (len_flush + (CPU_CACHE_LINE_BYTES - 1)) &
-		    ~(CPU_CACHE_LINE_BYTES - 1);
+		first_flush = rounddown2(first_flush, CPU_CACHE_LINE_BYTES);
+		last_flush = roundup2(last_flush, CPU_CACHE_LINE_BYTES);
+		len_flush = last_flush - first_flush;
 #endif
-		rtems_cache_flush_multiple_data_lines((void*)addr_flush,
+		rtems_cache_flush_multiple_data_lines((void*)first_flush,
 		    len_flush);
 #endif /* __rtems__ */
 



More information about the vc mailing list