summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-06-16 01:31:42 -0400
committerIan Moffett <ian@osmora.org>2025-06-16 01:31:42 -0400
commit8224cdd1059aec4a1342863caa687a28690e6af9 (patch)
tree2c1d489bd57371fc4c85b667e285e7abf2d27236
parent2f029ba398271f30cc917e755a49c7155f3d0801 (diff)
kernel: rtl: Expose NIC properly through if_var.h
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/dev/phy/rtl.c96
-rw-r--r--sys/include/net/if_var.h82
-rw-r--r--sys/include/net/netbuf.h40
-rw-r--r--sys/net/if.c85
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;
+}