[PATCH rtems-libbsd 2/2] microblaze: Finish AXI Ethernet support
Alex White
alex.white at oarcorp.com
Thu Jan 20 03:54:13 UTC 2022
---
freebsd/sys/dev/xdma/xdma_sg.c | 3 ++-
freebsd/sys/dev/xilinx/axidma.c | 14 ++++++++++++--
freebsd/sys/dev/xilinx/if_xae.c | 4 ++--
freebsd/sys/netinet/tcp_input.c | 9 +++++++++
freebsd/sys/netinet/tcp_subr.c | 10 ++++++++++
freebsd/sys/netinet6/ip6_input.c | 10 ++++++++++
.../include/rtems/bsd/test/network-config.h.in | 2 ++
7 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/freebsd/sys/dev/xdma/xdma_sg.c b/freebsd/sys/dev/xdma/xdma_sg.c
index fa69a297..74fad421 100644
--- a/freebsd/sys/dev/xdma/xdma_sg.c
+++ b/freebsd/sys/dev/xdma/xdma_sg.c
@@ -107,6 +107,7 @@ xchan_bufs_alloc_reserved(xdma_channel_t *xchan)
for (i = 0; i < xchan->xr_num; i++) {
xr = &xchan->xr_mem[i];
size = round_page(xchan->maxsegsize);
+#ifndef __rtems__
if (vmem_alloc(xchan->vmem, size,
M_BESTFIT | M_NOWAIT, &addr)) {
device_printf(xdma->dev,
@@ -117,10 +118,10 @@ xchan_bufs_alloc_reserved(xdma_channel_t *xchan)
xr->buf.size = size;
xr->buf.paddr = addr;
-#ifndef __rtems__
xr->buf.vaddr = kva_alloc(size);
#else
xr->buf.vaddr = calloc(1,size);
+ xr->buf.paddr = xr->buf.vaddr;
#endif
if (xr->buf.vaddr == 0) {
device_printf(xdma->dev,
diff --git a/freebsd/sys/dev/xilinx/axidma.c b/freebsd/sys/dev/xilinx/axidma.c
index 00ae2f1d..4fbb3104 100644
--- a/freebsd/sys/dev/xilinx/axidma.c
+++ b/freebsd/sys/dev/xilinx/axidma.c
@@ -68,6 +68,8 @@ __FBSDID("$FreeBSD$");
#ifdef __rtems__
#include <sys/endian.h>
+
+#define AXIDMA_DESCRIPTOR_ALIGNMENT 64
#endif
#ifdef AXIDMA_DEBUG
@@ -182,6 +184,10 @@ axidma_intr(struct axidma_softc *sc,
st.error = errors;
st.transferred = desc->status & BD_CONTROL_LEN_M;
+ /* Handle Control / Status Streams. */
+ if (!st.transferred) {
+ st.transferred = desc->app4 & 0xFF;
+ }
tot_copied += st.transferred;
xchan_seg_done(xchan, &st);
@@ -362,16 +368,20 @@ axidma_desc_alloc(struct axidma_softc *sc, struct xdma_channel *xchan,
chan->descs_phys = malloc(nsegments * sizeof(bus_dma_segment_t),
M_DEVBUF, M_NOWAIT | M_ZERO);
chan->mem_size = desc_size * nsegments;
+#ifndef __rtems__
if (vmem_alloc(xchan->vmem, chan->mem_size, M_FIRSTFIT | M_NOWAIT,
&chan->mem_paddr)) {
device_printf(sc->dev, "Failed to allocate memory.\n");
return (-1);
}
-#ifndef __rtems__
chan->mem_vaddr = kva_alloc(chan->mem_size);
pmap_kenter_device(chan->mem_vaddr, chan->mem_size, chan->mem_paddr);
#else
- chan->mem_vaddr = calloc(1, chan->mem_size);
+ /* Align DMA descriptors */
+ chan->mem_vaddr = calloc(1, chan->mem_size + AXIDMA_DESCRIPTOR_ALIGNMENT - 1);
+ chan->mem_vaddr = ((uintptr_t)chan->mem_vaddr +
+ AXIDMA_DESCRIPTOR_ALIGNMENT - 1) & ~0x3F;
+ chan->mem_paddr = chan->mem_vaddr;
#endif
device_printf(sc->dev, "Allocated chunk %lx %d\n",
diff --git a/freebsd/sys/dev/xilinx/if_xae.c b/freebsd/sys/dev/xilinx/if_xae.c
index 0582a588..3b23c5d4 100644
--- a/freebsd/sys/dev/xilinx/if_xae.c
+++ b/freebsd/sys/dev/xilinx/if_xae.c
@@ -729,7 +729,7 @@ xae_miibus_read_reg(device_t dev, int phy, int reg)
#if defined(__rtems__) && defined(DEBUG_MII)
dprintf("%s: reg: %d phy %d val 0x%x\n", __func__, reg, phy, rv);
#endif
- return (rv);
+ return (rv & 0xFFFF);
}
static int
@@ -980,7 +980,7 @@ xae_attach(device_t dev)
sc->mii_softc = device_get_softc(sc->miibus);
/* Apply vcu118 workaround. */
- // if (OF_getproplen(node, "xlnx,vcu118") >= 0)
+ if (OF_getproplen(node, "xlnx,vcu118") >= 0)
xae_phy_fixup(sc);
/* All ready to run, attach the ethernet interface. */
diff --git a/freebsd/sys/netinet/tcp_input.c b/freebsd/sys/netinet/tcp_input.c
index fc111d9c..60f9123a 100644
--- a/freebsd/sys/netinet/tcp_input.c
+++ b/freebsd/sys/netinet/tcp_input.c
@@ -721,6 +721,15 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
}
#endif /* INET */
+#ifdef __rtems__
+#ifdef __MICROBLAZE__
+ /* Ensure that the TCP header is properly aligned in memory. */
+ struct tcphdr aligned_hdr;
+ memcpy(&aligned_hdr, th, sizeof(struct tcphdr));
+ th = &aligned_hdr;
+#endif
+#endif
+
/*
* Check that TCP offset makes sense,
* pull out TCP options and adjust length. XXX
diff --git a/freebsd/sys/netinet/tcp_subr.c b/freebsd/sys/netinet/tcp_subr.c
index eae696c1..d0025c01 100644
--- a/freebsd/sys/netinet/tcp_subr.c
+++ b/freebsd/sys/netinet/tcp_subr.c
@@ -1520,6 +1520,16 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
mac_netinet_tcp_reply(m);
}
#endif
+
+#ifdef __rtems__
+#ifdef __MICROBLAZE__
+ /* Ensure that the TCP header is properly aligned in memory. */
+ struct tcphdr aligned_hdr;
+ memcpy(&aligned_hdr, nth, sizeof(struct tcphdr));
+ nth = &aligned_hdr;
+#endif
+#endif
+
nth->th_seq = htonl(seq);
nth->th_ack = htonl(ack);
nth->th_x2 = 0;
diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c
index 6800d002..961e4e79 100644
--- a/freebsd/sys/netinet6/ip6_input.c
+++ b/freebsd/sys/netinet6/ip6_input.c
@@ -623,6 +623,16 @@ ip6_input(struct mbuf *m)
}
ip6 = mtod(m, struct ip6_hdr *);
+
+#ifdef __rtems__
+#ifdef __MICROBLAZE__
+ /* Ensure that the IPv6 header is properly aligned in memory. */
+ struct ip6_hdr aligned_hdr;
+ memcpy(&aligned_hdr, ip6, sizeof(struct ip6_hdr));
+ ip6 = &aligned_hdr;
+#endif
+#endif
+
if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
IP6STAT_INC(ip6s_badvers);
in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
diff --git a/testsuite/include/rtems/bsd/test/network-config.h.in b/testsuite/include/rtems/bsd/test/network-config.h.in
index fd63eded..69609854 100755
--- a/testsuite/include/rtems/bsd/test/network-config.h.in
+++ b/testsuite/include/rtems/bsd/test/network-config.h.in
@@ -52,6 +52,8 @@
#endif
#elif defined(LIBBSP_ARM_ATSAM_BSP_H)
#define NET_CFG_INTERFACE_0 "if_atsam0"
+#elif defined(LIBBSP_MICROBLAZE_FPGA_BSP_H)
+ #define NET_CFG_INTERFACE_0 "xae0"
#else
#define NET_CFG_INTERFACE_0 "@NET_CFG_INTERFACE_0@"
#endif
--
2.30.2
More information about the devel
mailing list