From 0d01966ac302b9362baf29320773430a1f8f5c29 Mon Sep 17 00:00:00 2001 From: ed Date: Sun, 3 Nov 2024 17:39:16 +0000 Subject: [PATCH 1/2] wiznet w5x00: fixes aiming towards getting UDP reads working. previously when processing incoming UDP packets we kept reading the same offsets as it read from the read pointer. rename dequeue to read and add an offset parameter. also read port correctly. --- Kernel/dev/net/net_w5x00.c | 38 +++++++++++++++++++++----------------- Kernel/network.c | 2 +- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Kernel/dev/net/net_w5x00.c b/Kernel/dev/net/net_w5x00.c index 7a550a8cfc..a8ae437462 100644 --- a/Kernel/dev/net/net_w5x00.c +++ b/Kernel/dev/net/net_w5x00.c @@ -388,30 +388,28 @@ static void w5x00_queue_u(uint16_t i, uint16_t n, void *p) w5x00_bwriteu(i, dm, p, n); } -static void w5x00_dequeue(uint16_t i, uint16_t n, void *p) +static void w5x00_read(uint16_t i, uint16_t off, uint16_t n, void *p) { - uint16_t dm = w5x00_readsw(i, Sn_RX_RD0) & RX_MASK; i = SOCK2BANK_R(i); - if (dm + n > RX_MASK) { - uint16_t us = RX_MASK + 1 - dm; - w5x00_bread(i, dm, p, us); + if (off + n > RX_MASK) { + uint16_t us = RX_MASK + 1 - off; + w5x00_bread(i, off, p, us); w5x00_bread(i, 0, (uint8_t *)p + us, n - us); } else - w5x00_bread(i, dm, p, n); + w5x00_bread(i, off, p, n); } -static void w5x00_dequeue_u(uint16_t i, uint16_t n, void *p) +static void w5x00_read_u(uint16_t i, uint16_t off, uint16_t n, void *p) { - uint16_t dm = w5x00_readsw(i, Sn_RX_RD0) & RX_MASK; i = SOCK2BANK_R(i); - if (dm + n > RX_MASK) { - uint16_t us = RX_MASK + 1 - dm; - w5x00_breadu(i, dm, p, us); + if (off + n > RX_MASK) { + uint16_t us = RX_MASK + 1 - off; + w5x00_breadu(i, off, p, us); w5x00_breadu(i, 0, (uint8_t *)p + us, n - us); } else - w5x00_breadu(i, dm, p, n); + w5x00_breadu(i, off, p, n); } static void w5x00_cmd(uint8_t s, uint8_t v) @@ -868,6 +866,7 @@ int netproto_read(struct socket *s) uint16_t n; register uint16_t r; uint_fast8_t filtered; + uint16_t off; if (udata.u_count == 0) return 0; @@ -887,18 +886,23 @@ int netproto_read(struct socket *s) memcpy(&udata.u_net.addrbuf, &s->dst_addr, sizeof(struct ksockaddr)); + off = w5x00_readsw(i, Sn_RX_RD0) & RX_MASK; + switch (s->s_type) { case W5100_RAW: case W5100_UDP: /* UDP comes with a header */ - w5x00_dequeue(i, 4, &udata.u_net.addrbuf.sa.sin.sin_addr); + w5x00_read(i, off, 4, &udata.u_net.addrbuf.sa.sin.sin_addr); + off +=4; if (s->s_type == W5100_UDP) { - w5x00_dequeue(i, 2, &udata.u_net.addrbuf.sa.sin.sin_addr); + w5x00_read(i, off, 2, &udata.u_net.addrbuf.sa.sin.sin_port); + off +=2; if (s->src_addr.sa.sin.sin_addr.s_addr && s->src_addr.sa.sin.sin_addr.s_addr != udata.u_net.addrbuf.sa.sin.sin_addr.s_addr) filtered = 1; } - w5x00_dequeue(i, 2, (uint8_t *) & n); /* Actual packet size */ + w5x00_read(i, off, 2, (uint8_t *) &n); /* Actual packet size */ + off +=2; n = ntohs(n); /* Big endian on device */ /* Fall through */ case W5100_TCP: @@ -912,8 +916,8 @@ int netproto_read(struct socket *s) /* Wait */ return 1; } - /* Now dequeue some bytes into udata.u_base */ - w5x00_dequeue_u(i, r, udata.u_base); + /* Now read some bytes into udata.u_base */ + w5x00_read_u(i, off, r, udata.u_base); udata.u_done += r; udata.u_base += r; } diff --git a/Kernel/network.c b/Kernel/network.c index 03a34a0080..6f4a7c65d2 100644 --- a/Kernel/network.c +++ b/Kernel/network.c @@ -102,7 +102,7 @@ int net_syscall(void) return 0; if (s->s_state < SS_BOUND) break; - /* This will put the address into u_net.n_addr for us */ + /* This will put the address into u_net.addrbuf for us */ r = netproto_read(s); udata.u_retval = udata.u_done; return r; From ae94bbadff8f31e566009baf07feb3cba8787b11 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 5 Nov 2024 20:44:52 +0000 Subject: [PATCH 2/2] net: fix addr_out error checking --- Kernel/syscall_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kernel/syscall_net.c b/Kernel/syscall_net.c index 81556045eb..90b74abee9 100644 --- a/Kernel/syscall_net.c +++ b/Kernel/syscall_net.c @@ -230,7 +230,7 @@ arg_t _netcall(void) /* Copy the buffer, oe less if truncated by size */ if (s > udata.u_net.addrlen) s = udata.u_net.addrlen; - if (uput(&udata.u_net.addrbuf, (void *) *ap, s) != s) { + if (uput(&udata.u_net.addrbuf, (void *) *ap, s) < 0) { udata.u_error = EFAULT; return -1; }