diff options
author | Ilias Apalodimas <ilias.apalodimas@linaro.org> | 2017-10-12 22:49:16 +0300 |
---|---|---|
committer | Ilias Apalodimas <ilias.apalodimas@linaro.org> | 2017-10-12 22:49:16 +0300 |
commit | 992a1811b8cb491ca9fc80d747d823ba60585991 (patch) | |
tree | 3dff53a64c9e769497d41ba1afb9c39743ee767c | |
parent | 3f0a35b99993b121614bc20cacabffc17255aabf (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-- | Makefile | 2 | ||||
-rw-r--r-- | drivers/r8169.c | 110 | ||||
-rw-r--r-- | include/drivers/driver_ops.h | 19 | ||||
-rw-r--r-- | include/drivers/r8169.h | 1 | ||||
-rw-r--r-- | src/userspace_io.c | 118 |
5 files changed, 159 insertions, 91 deletions
@@ -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, ®ion_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, ®ion_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; + + +} |