aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlias Apalodimas <ilias.apalodimas@linaro.org>2017-10-12 22:49:16 +0300
committerIlias Apalodimas <ilias.apalodimas@linaro.org>2017-10-12 22:49:16 +0300
commit992a1811b8cb491ca9fc80d747d823ba60585991 (patch)
tree3dff53a64c9e769497d41ba1afb9c39743ee767c
parent3f0a35b99993b121614bc20cacabffc17255aabf (diff)
Added structs for driver_ops, Modularized r8169 driver even more.
NEED TESTING Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r--Makefile2
-rw-r--r--drivers/r8169.c110
-rw-r--r--include/drivers/driver_ops.h19
-rw-r--r--include/drivers/r8169.h1
-rw-r--r--src/userspace_io.c118
5 files changed, 159 insertions, 91 deletions
diff --git a/Makefile b/Makefile
index 65cee0e..e54aa9b 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CFLAGS=-Iinclude/ -Wall -Werror -Wunused
all: r8169
-R8169_OBJS:= drivers/r8169.o api/vfio_api.o api/mm.o
+R8169_OBJS:= drivers/r8169.o api/vfio_api.o api/mm.o src/userspace_io.o
r8169: $(R8169_OBJS)
$(CC) $(R8169_OBJS) -o r8169 $(CFLAGS)
diff --git a/drivers/r8169.c b/drivers/r8169.c
index 8089a35..5d58251 100644
--- a/drivers/r8169.c
+++ b/drivers/r8169.c
@@ -1,25 +1,12 @@
-#include <fcntl.h>
-#include <unistd.h>
#include <stdio.h>
-#include <malloc.h>
-#include <string.h>
-#include <arpa/inet.h>
#include <endian.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-
-#include <linux/vfio.h>
-
-/* Us */
+#include <unistd.h>
+/* Our */
#include <drivers/r8169.h>
-#include <vfio_api.h>
+#include <drivers/driver_ops.h>
#include <mm_api.h>
typedef unsigned long dma_addr_t;
-char *rxBuffers[256];
static void print_packet(unsigned char *buffer)
{
@@ -52,15 +39,15 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
rtl8169_mark_to_asic(desc, rx_buf_sz);
}
-
static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
{
desc->opts1 |= cpu_to_le32(RingEnd);
}
-int rtl8169_rx_fill(int device, struct RxDesc *rxRing, struct iomem *data)
+static int rtl8169_rx_fill(int device, void *rx_data, struct iomem *data, char *rxBuffers[])
{
int i;
+ struct RxDesc *rxRing = (struct RxDesc *) rx_data;
for (i = 0; i < NUM_RX_DESC; i++) {
rtl8169_map_to_asic(&rxRing[i], data->iova + i * 2048, 2048);
@@ -71,71 +58,11 @@ int rtl8169_rx_fill(int device, struct RxDesc *rxRing, struct iomem *data)
return 0;
}
-void usage(char *name)
-{
- printf("usage: %s <group id>\n", name);
-}
-
-int main(int argc, char *argv[])
+void r8169_recv(void *rxring, char *rxBuffers[])
{
- int container = -1, group = -1, device, i = 0;
- int group_id;
- char group_uuid[64]; /* 37 should be enough */
- struct vfio_group_status group_status = { .argsz = sizeof(group_status) };
- struct vfio_iommu_type1_info iommu_info = { .argsz = sizeof(iommu_info) };
- struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
- struct vfio_region_info region_info = { .argsz = sizeof(region_info) };
- struct RxDesc *rxRing = NULL;
- void *iobase, *iocur;
- struct iomem rx_data;
- int ret;
-
- if (argc != 3) {
- usage(argv[0]);
- return -1;
- }
- iobase = iomem_init();
- if (!iobase)
- return -ENOMEM;
- iocur = iobase;
-
- /* Create a new container */
- container = get_container();
- if (container < 0)
- goto out;
-
- group_id = atoi(argv[1]);
- group = get_group(group_id);
- if (group < 0)
- goto out;
-
- strncpy(group_uuid, argv[2], sizeof(group_uuid));
- device = vfio_init_dev(group, container, &group_status, &iommu_info,
- &device_info, &region_info, group_uuid);
-
- printf("Region:%d size %llu, offset 0x%llx, flags 0x%x\n", i,
- region_info.size, region_info.offset, region_info.flags);
-
- rxRing = mmap(NULL, region_info.size, PROT_READ | PROT_WRITE,
- MAP_SHARED, device, region_info.offset);
- if (rxRing == MAP_FAILED) {
- printf("Could not reserve on contiguous 4GB address space\n");
- goto out;
- }
- printf("iobase: %p iocur : %p\n", iobase, iocur);
- ret = iomem_alloc(device, 2 * 1024 * 1024, &iocur, &rx_data);
- if (ret)
- goto out;
- printf("iobase: %p iocur : %p\n", iobase, iocur);
-
- if (rtl8169_rx_fill(device, rxRing, &rx_data) != 0) {
- printf("Could not fill ring\n");
- goto out;
- }
+ int i = 0;
+ struct RxDesc *rxRing = (struct RxDesc *)rxring;
- /* signal ready */
- ioctl(device, 500, NULL);
- i = 0;
while (1) {
if (i >= NUM_RX_DESC)
i = 0;
@@ -226,13 +153,16 @@ process_pkt:
rtl8169_mark_to_asic(&rxRing[i], 2048);
}
}
-
-out:
- if (rxRing)
- munmap(rxRing, region_info.size);
- if (group)
- close(group);
- if (container)
- close(container);
- return -1;
}
+
+/* FIXME make this staic once we have loadbale module support */
+const struct driver_ops r8169_ops = {
+ /* endianess for vendor/id? */
+ .vendor = 0x10ec,
+ .device = 0x8168,
+ .vfio_quirks = NULL,
+ .rx_fill = rtl8169_rx_fill,
+ .tx_fill= NULL,
+ .recv = r8169_recv,
+ .xmit = NULL,
+};
diff --git a/include/drivers/driver_ops.h b/include/drivers/driver_ops.h
new file mode 100644
index 0000000..2c3c016
--- /dev/null
+++ b/include/drivers/driver_ops.h
@@ -0,0 +1,19 @@
+#ifndef _DRIVER_OPS_H
+#define _DRIVER_OPS_H
+#include <mm_api.h>
+
+struct driver_ops {
+ __u16 vendor;
+ __u16 device;
+ /* VFIO/PCI quirks */
+ int (*vfio_quirks)(void);
+ /* prepare Tx descriptors */
+ int (*rx_fill)(int device, void *rxring, struct iomem *data, char *rx_buf[]);
+ /* prepare Tx descriptors */
+ int (*tx_fill)(int device, void *txring, struct iomem *data);
+ /* receive */
+ void (*recv)(void *rxring, char *rxbuffers[]);
+ /* xmit */
+ void (*xmit)(void);
+};
+#endif
diff --git a/include/drivers/r8169.h b/include/drivers/r8169.h
index d3aca73..6bbcb61 100644
--- a/include/drivers/r8169.h
+++ b/include/drivers/r8169.h
@@ -1,5 +1,6 @@
#ifndef _R8169_H_
#define _R8169_H_
+#include <linux/types.h>
#define COMPILER_BARRIER() asm volatile("" ::: "memory")
#define MEMORY_BARRIER() asm volatile ("mfence" ::: "memory")
#define STORE_BARRIER() asm volatile ("sfence" ::: "memory")
diff --git a/src/userspace_io.c b/src/userspace_io.c
new file mode 100644
index 0000000..05521da
--- /dev/null
+++ b/src/userspace_io.c
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include <endian.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <arpa/inet.h>
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <linux/vfio.h>
+
+/* Us */
+#include <drivers/driver_ops.h>
+#include <vfio_api.h>
+#include <mm_api.h>
+#include <drivers/r8169.h>
+//#include <vfio_api.h>
+
+
+const struct driver_ops r8169_ops;
+
+static void usage(char *name)
+{
+ printf("usage: %s <group id>\n", name);
+}
+
+int main(int argc, char *argv[])
+{
+ /* FIXME select proper *_ops once we have loadable modules */
+ int container = -1, group = -1, device, i = 0;
+ int group_id;
+ char group_uuid[64]; /* 37 should be enough */
+ struct vfio_group_status group_status = { .argsz = sizeof(group_status) };
+ struct vfio_iommu_type1_info iommu_info = { .argsz = sizeof(iommu_info) };
+ struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
+ struct vfio_region_info region_info = { .argsz = sizeof(region_info) };
+ struct RxDesc *rxRing = NULL;
+ void *iobase, *iocur;
+ struct iomem rx_data;
+ int ret, c;
+ struct driver_ops exec_ops = r8169_ops;
+ char *rxBuffers[256];
+
+ while ((c = getopt(argc, argv, "d:i:f:")) != -1) {
+ switch (c) {
+ case 'd':
+ break;
+ case 'i':
+ break;
+ case 'f':
+ break;
+ }
+ }
+
+ if (argc != 3) {
+ usage(argv[0]);
+ return -1;
+ }
+
+ iobase = iomem_init();
+ if (!iobase)
+ return -ENOMEM;
+ iocur = iobase;
+
+ /* Create a new container */
+ container = get_container();
+ if (container < 0)
+ goto out;
+
+ group_id = atoi(argv[1]);
+ group = get_group(group_id);
+ if (group < 0)
+ goto out;
+
+ strncpy(group_uuid, argv[2], sizeof(group_uuid));
+ device = vfio_init_dev(group, container, &group_status, &iommu_info,
+ &device_info, &region_info, group_uuid);
+
+ printf("Region:%d size %llu, offset 0x%llx, flags 0x%x\n", i,
+ region_info.size, region_info.offset, region_info.flags);
+
+ rxRing = mmap(NULL, region_info.size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, device, region_info.offset);
+ if (rxRing == MAP_FAILED) {
+ printf("Could not reserve on contiguous 4GB address space\n");
+ goto out;
+ }
+ printf("iobase: %p iocur : %p\n", iobase, iocur);
+ ret = iomem_alloc(device, 2 * 1024 * 1024, &iocur, &rx_data);
+ if (ret)
+ goto out;
+ printf("iobase: %p iocur : %p\n", iobase, iocur);
+
+ if (exec_ops.rx_fill(device, rxRing, &rx_data, rxBuffers) != 0) {
+ printf("Could not fill ring\n");
+ goto out;
+ }
+
+ ioctl(device, 500, NULL);
+ exec_ops.recv(rxRing, rxBuffers);
+
+out:
+ if (rxRing)
+ munmap(rxRing, region_info.size);
+ if (group)
+ close(group);
+ if (container)
+ close(container);
+ return -1;
+
+
+}