Cannot make if_stmac.c work with stm32h7 and data in SDRAM
Summary
At least with data in SDRAM (FMC) on a stm32h747, the if_stmac.c driver is not working properly. it might be due to stm32h747 not supporting unaligned access on FMC (see stm32h7 errata) or for some other reason, like the many erratas for the ethernet IP on this chip.
I spent a day trying to understand what is going on, without success.
When trying to ping from another host, the reception path got OK:
- I could receive a proper ARP packet
- The ARP response was correctly generated by the stack.
- No packet (or a corrupted packet) was received on the other side (transmission problem).
Steps to reproduce
Configure a stm32h7 eval board using SDRAM for data/bss/heap. Try networking with something like like media01.exe.
Minor issues:
During testing, I found out two minor problems, and came up with the following patch, included here in case it helps:
--- a/rtemsbsd/sys/dev/stmac/if_stmac.c
+++ b/rtemsbsd/sys/dev/stmac/if_stmac.c
@@ -50,6 +50,8 @@
#include <net/if_types.h>
#include <net/if_var.h>
+#include <net/bpf.h>
+
#include <machine/bus.h>
#include <dev/mii/mii.h>
@@ -115,9 +117,9 @@ stmac_new_mbuf(struct ifnet *ifp)
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m != NULL) {
+ rtems_cache_invalidate_multiple_data_lines(m->m_ext.ext_buf, m->m_ext.ext_size);
m->m_data = mtod(m, char *) + ETHER_ALIGN;
m->m_pkthdr.rcvif = ifp;
- rtems_cache_invalidate_multiple_data_lines(m->m_data, m->m_len);
}
return m;
@@ -793,6 +795,8 @@ stmac_tx_enqueue(struct stmac_softc *sc, struct ifnet *ifp, struct mbuf *m)
_ARM_Data_synchronization_barrier();
regs = sc->heth.Instance;
WRITE_REG(regs->DMACTDTPR, (uint32_t)&desc_ring[new_head_idx]);
+
+ ETHER_BPF_MTAP(sc->ifp, m);
return (0);
}
-
The
rtems_cache_invalidate_multiple_data_lines
call was doing nothing, sincem_len
is 0 for a new mbuf. -
ETHER_BPF_MTAP was missing to see the output packet with tcpdump.
Fun read
No idea if this is relevant, but the following blog is pretty fun (or horrifying)