diff options
-rw-r--r-- | sys/dev/phy/rtl.c | 96 | ||||
-rw-r--r-- | sys/include/net/if_var.h | 82 | ||||
-rw-r--r-- | sys/include/net/netbuf.h | 40 | ||||
-rw-r--r-- | sys/net/if.c | 85 |
4 files changed, 282 insertions, 21 deletions
diff --git a/sys/dev/phy/rtl.c b/sys/dev/phy/rtl.c index e37caf7..8462a43 100644 --- a/sys/dev/phy/rtl.c +++ b/sys/dev/phy/rtl.c @@ -30,19 +30,23 @@ #include <sys/types.h> #include <sys/errno.h> #include <sys/syslog.h> +#include <sys/spinlock.h> #include <sys/driver.h> #include <sys/device.h> #include <dev/pci/pci.h> #include <dev/phy/rtl.h> #include <dev/timer.h> #include <dev/pci/pciregs.h> -#include <net/if_ether.h> +#include <net/netbuf.h> +#include <net/if_var.h> #include <vm/physmem.h> #include <vm/dynalloc.h> #include <vm/vm.h> #include <machine/pio.h> #include <string.h> +#define IFNAME "rt0" + /* TODO: Make this smoother */ #if defined(__x86_64__) #include <machine/intr.h> @@ -56,6 +60,7 @@ #define RX_BUF_SIZE 3 /* In pages */ #define RX_REAL_BUF_SIZE 8192 /* In bytes */ +#define TXQ_ENTRIES 4 #define RX_PTR_MASK (~3) @@ -66,18 +71,22 @@ #define HAVE_PIO 0 #endif /* _MACHINE_HAVE_PIO */ +static struct spinlock netif_lock; +static struct netbuf netif_buf[TXQ_ENTRIES]; static struct pci_device *dev; +static struct netif netif; static struct timer tmr; -static struct etherdev wire; +static uint32_t tx_ptr = 0; +static uint32_t netif_enq_ptr = 0; static uint16_t ioport; static paddr_t rxbuf, txbuf; /* TXAD regs */ -static uint16_t tsads[] = { +static uint16_t tsads[TXQ_ENTRIES] = { RT_TXAD_N(0), RT_TXAD_N(4), RT_TXAD_N(8), RT_TXAD_N(12) }; -static uint16_t tsds[] = { +static uint16_t tsds[TXQ_ENTRIES] = { RT_TXSTATUS_N(0), RT_TXSTATUS_N(4), RT_TXSTATUS_N(8), RT_TXSTATUS_N(8) }; @@ -170,7 +179,7 @@ rt_poll(uint8_t reg, uint8_t size, uint32_t bits, bool pollset) return val; } -__used static int +static int rt_tx(void *packet, size_t len) { static uint32_t tx_ptr = 0; @@ -186,22 +195,61 @@ rt_tx(void *packet, size_t len) tx_pa = VIRT_TO_PHYS(tx_data); rt_write(tsads[tx_ptr], 4, tx_pa); rt_write(tsds[tx_ptr++], 4, len); - if (tx_ptr) { + if (tx_ptr > TXQ_ENTRIES - 1) { tx_ptr = 0; } return 0; } +static void +__rt81xx_tx_start(struct netif *nifp) +{ + struct netbuf *dest; + int error; + + for (int i = 0; i < netif_enq_ptr; ++i) { + dest = &netif_buf[i]; + error = rt_tx(dest->data, dest->len); + if (error < 0) { + pr_error("tx_start fail @queue %d (errno=%d)\n", i, error); + } + } +} + +static void +rt81xx_tx_start(struct netif *nifp) +{ + spinlock_acquire(&netif_lock); + __rt81xx_tx_start(nifp); + spinlock_release(&netif_lock); +} + +static int +rt81xx_tx_enq(struct netif *nifp, struct netbuf *nbp, void *data) +{ + struct netbuf *dest; + + spinlock_acquire(&netif_lock); + dest = &netif_buf[netif_enq_ptr++]; + memcpy(dest, nbp, sizeof(*dest)); + + if (netif_enq_ptr > TXQ_ENTRIES - 1) { + __rt81xx_tx_start(nifp); + netif_enq_ptr = 0; + } + spinlock_release(&netif_lock); + return 0; +} + static int rt81xx_intr(void *sp) { - static uint32_t packet_ptr = 0; uint16_t len; uint16_t *p; uint16_t status; status = rt_read(RT_INTRSTATUS, 2); - p = (uint16_t *)(rxbuf + packet_ptr); + p = (uint16_t *)(rxbuf + tx_ptr); len = *(p + 1); /* Length after header */ p += 2; /* Points to data now */ @@ -215,11 +263,11 @@ rt81xx_intr(void *sp) } /* Update rxbuf offset in CAPR */ - packet_ptr = (packet_ptr + len + 4 + 3) & RX_PTR_MASK; - if (packet_ptr > RX_REAL_BUF_SIZE) { - packet_ptr -= RX_REAL_BUF_SIZE; + tx_ptr = (tx_ptr + len + 4 + 3) & RX_PTR_MASK; + if (tx_ptr > RX_REAL_BUF_SIZE) { + tx_ptr -= RX_REAL_BUF_SIZE; } - rt_write(RT_RXBUFTAIL, 2, packet_ptr - 0x10); + rt_write(RT_RXBUFTAIL, 2, tx_ptr - 0x10); rt_write(RT_INTRSTATUS, 2, RT_ACKW); return 1; /* handled */ } @@ -252,6 +300,7 @@ rt_init_pci(void) static int rt_init_mac(void) { + struct netif_addr *addr = &netif.addr; uint8_t conf; uint32_t tmp; int error; @@ -287,20 +336,20 @@ rt_init_mac(void) /* MAC address dword 0 */ tmp = rt_read(RT_IDR0, 4); - wire.mac_addr[0] = tmp & 0xFF; - wire.mac_addr[1] = (tmp >> 8) & 0xFF; - wire.mac_addr[2] = (tmp >> 16) & 0xFF; - wire.mac_addr[3] = (tmp >> 24) & 0xFF; + addr->data[0] = tmp & 0xFF; + addr->data[1] = (tmp >> 8) & 0xFF; + addr->data[2] = (tmp >> 16) & 0xFF; + addr->data[3] = (tmp >> 24) & 0xFF; /* MAC address word 1 */ tmp = rt_read(RT_IDR2, 4); - wire.mac_addr[4] = (tmp >> 16) & 0xFF; - wire.mac_addr[5] = (tmp >> 24) & 0xFF; + addr->data[4] = (tmp >> 16) & 0xFF; + addr->data[5] = (tmp >> 24) & 0xFF; pr_trace("MAC address: %x:%x:%x:%x:%x:%x\n", - (uint64_t)wire.mac_addr[0], (uint64_t)wire.mac_addr[1], - (uint64_t)wire.mac_addr[2], (uint64_t)wire.mac_addr[3], - (uint64_t)wire.mac_addr[4], (uint64_t)wire.mac_addr[5]); + (uint64_t)addr->data[0], (uint64_t)addr->data[1], + (uint64_t)addr->data[2], (uint64_t)addr->data[3], + (uint64_t)addr->data[4], (uint64_t)addr->data[5]); /* * Alright, now we don't want those EEM bits @@ -324,6 +373,11 @@ rt_init_mac(void) return -ENOMEM; } + memcpy(netif.name, IFNAME, strlen(IFNAME) + 1); + netif.tx_enq = rt81xx_tx_enq; + netif.tx_start = rt81xx_tx_start; + netif_add(&netif); + /* * Configure the chip: * diff --git a/sys/include/net/if_var.h b/sys/include/net/if_var.h new file mode 100644 index 0000000..e032ff4 --- /dev/null +++ b/sys/include/net/if_var.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _NET_IF_VAR_H_ +#define _NET_IF_VAR_H_ + +#include <sys/queue.h> +#include <sys/types.h> +#include <net/if.h> +#include <net/netbuf.h> + +#define NETIF_ADDR_LEN 32 /* In bytes */ + +/* Return values for netif hooks */ +#define NETIF_ENQ_OK 0 /* Enqueued */ +#define NETIF_ENQ_FLUSHED 1 /* Internal queue flushed */ + +/* Interface types */ +#define NETIF_TYPE_ANY 0 /* Any type */ +#define NETIF_TYPE_WIRE 1 /* Ethernet */ + +/* + * Represents the address of a network + * interface. + * + * @data: Raw address bytes + */ +struct netif_addr { + uint8_t data[NETIF_ADDR_LEN]; +}; + +/* + * Represents a network interface + * + * @name: Interface name + * @type: Interface type (see NETIF_TYPE*) + * @tx_enq: Enqueue a packet + * @tx_start: Start a packet + * + * XXX: tx_enq() returns 0 on success and 1 if a flush was needed + * and the packets have been transmitted. Less than zero values + * indicate failure. + */ +struct netif { + char name[IFNAMESIZ]; + uint8_t type; + TAILQ_ENTRY(netif) link; + struct netif_addr addr; + int(*tx_enq)(struct netif *nifp, struct netbuf *nbp, void *data); + void(*tx_start)(struct netif *nifp); +}; + +void netif_add(struct netif *nifp); +int netif_lookup(const char *name, uint8_t type, struct netif **res); + +#endif /* !_NET_IF_VAR_H_ */ diff --git a/sys/include/net/netbuf.h b/sys/include/net/netbuf.h new file mode 100644 index 0000000..33ba06f --- /dev/null +++ b/sys/include/net/netbuf.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _NET_NETBUF_H_ +#define _NET_NETBUF_H_ + +#define NETBUF_LEN 256 + +struct netbuf { + char data[NETBUF_LEN]; + size_t len; +}; + +#endif /* !_NET_NETBUF_H_ */ diff --git a/sys/net/if.c b/sys/net/if.c new file mode 100644 index 0000000..5c9bc01 --- /dev/null +++ b/sys/net/if.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/spinlock.h> +#include <sys/errno.h> +#include <net/if_var.h> +#include <string.h> + +static TAILQ_HEAD(, netif) netif_list; +static bool netif_init = false; + +/* + * Expose a network interface to the rest of the + * system. + */ +void +netif_add(struct netif *nifp) +{ + if (!netif_init) { + TAILQ_INIT(&netif_list); + netif_init = true; + } + + TAILQ_INSERT_TAIL(&netif_list, nifp, link); +} + +/* + * Lookup a network interface by name or type. + * + * @name: Name to lookup (use `type' if NULL) + * @type: Type to lookup (use if `name' is NULL) + */ +int +netif_lookup(const char *name, uint8_t type, struct netif **res) +{ + struct netif *netif; + + if (!netif_init) { + return -EAGAIN; + } + + TAILQ_FOREACH(netif, &netif_list, link) { + if (name != NULL) { + if (strcmp(netif->name, name) == 0) { + *res = netif; + return 0; + } + } + + if (name == NULL && netif->type == type) { + *res = netif; + return 0; + } + } + + return -ENODEV; +} |