aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykyta Iziumtsev <mykyta.iziumtsev@linaro.org>2017-10-18 09:08:13 +0200
committerMykyta Iziumtsev <mykyta.iziumtsev@linaro.org>2017-10-18 12:00:21 +0200
commit68c793425069c36fb9489ef3ac73fb2c6344fae9 (patch)
tree4ae036139710fdcce31b3f3fb1bcfc390009877b
parentbc813281006f4267c1dc1797ac0aad05e1a53a9c (diff)
Attempt to fix e1000e TX pathe1000e_tx
-rw-r--r--drivers/e1000e.c59
-rw-r--r--drivers/r8169.c24
-rw-r--r--include/common.h12
-rw-r--r--include/drivers/driver_ops.h7
-rw-r--r--kernel/4.13.0/e1000e/netdev.c4
-rw-r--r--src/userspace_io.c9
6 files changed, 65 insertions, 50 deletions
diff --git a/drivers/e1000e.c b/drivers/e1000e.c
index cf022e7..43fbd66 100644
--- a/drivers/e1000e.c
+++ b/drivers/e1000e.c
@@ -2,11 +2,13 @@
#include <endian.h>
#include <unistd.h>
#include <stdint.h>
+#include <string.h>
#include <linux/types.h>
#include <drivers/driver_ops.h>
#include <mm_api.h>
#include <vfio_api.h>
+#include <reg_api.h>
extern void *bar0;
@@ -23,6 +25,9 @@ typedef uint64_t odpdrv_u64le_t;
typedef uint64_t odpdrv_u64be_t;
#define odpdrv_cpu_to_le_64(value) (value)
+#define odpdrv_cpu_to_le_32(value) (value)
+#define odpdrv_cpu_to_le_16(value) (value)
+#define odpdrv_le_to_cpu_64(value) (value)
#define odpdrv_le_to_cpu_32(value) (value)
#define odpdrv_le_to_cpu_16(value) (value)
@@ -46,6 +51,11 @@ typedef uint64_t odpdrv_u64be_t;
typedef struct e1000e_tx_desc {
odpdrv_u64le_t buffer_addr; /* Address of the descriptor's data buffer */
union {
+#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
+#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
+#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
+
odpdrv_u32le_t data;
struct {
odpdrv_u16le_t length; /* Data buffer length */
@@ -120,12 +130,10 @@ static void print_packet(unsigned char *buffer)
static void e1000e_rx_desc_push(e1000e_rx_desc_t *rx_ring, int idx, dma_addr_t dma_addr, volatile void *ioaddr)
{
- printf("Writing RX desc #%i (%p), buf at %p\n", idx, rx_ring + idx, (void *)dma_addr);
rx_ring[idx].read.buffer_addr = odpdrv_cpu_to_le_64(dma_addr);
dma_wmb();
- // FIXME: proper le register write
- *(uint32_t *)(ioaddr + E1000_RDT_OFFSET) = idx;
+ io_write32(odpdrv_cpu_to_le_32(idx), ioaddr + E1000_RDT_OFFSET);
}
static int e1000e_rx_fill(int device, void *rxring, struct iomem data,
@@ -186,11 +194,44 @@ void *e1000e_map_mmio(int device)
return vfio_mmap_region(device, 0);
}
-static int e1000e_tx_fill(int device, void *tx_data, struct iomem data,
- char *tx_buff[])
+void e1000e_xmit(void *txring, struct iomem data, volatile void *ioaddr)
{
- /* Nothing to do here */
- return 0;
+ /* test udp packet */
+ static const char pkt_udp[] = {
+ 0x02, 0x50, 0x43, 0xff, 0xff, 0x01, /* mac dst */
+ 0x00, 0x60, 0xdd, 0x45, 0xe5, 0x67, /* mac src */
+ 0x08, 0x00, 0x45, 0x00, 0x00, 0x32,
+ 0x38, 0xb8, 0x40, 0x00, 0x40, 0x11,
+ 0x1e, 0xae, 0xc0, 0xa8, 0x31, 0x03, /* ip src: 192.168.49.3 and dst 192.168.49.1 */
+ 0xc0, 0xa8, 0x31, 0x01, 0xed, 0x19,
+ 0x00, 0x35, 0x00, 0x1e, 0x8b, 0xf4,
+ 0xc4, 0x2e, 0x01, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x74, 0x65, 0x73, 0x74, 0x00,
+ 0x00, 0x01, 0x00, 0x01
+ };
+ const int idx = 0;
+ e1000_tx_desc_t *tx_desc = (e1000_tx_desc_t *)txring + idx;
+ char *tx_buff = (char *)(data.vaddr + idx * 2048);
+ uint32_t txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS |
+ E1000_TXD_CMD_IDE;
+
+ /* XXX FIXME need proper packet size and sizeof(src) *NOT* dst */
+ memcpy(tx_buff, pkt_udp, sizeof(pkt_udp));
+ tx_desc->buffer_addr = odpdrv_cpu_to_le_64(data.iova + idx * 2048);
+ tx_desc->lower.data = odpdrv_cpu_to_le_32(txd_cmd | sizeof(pkt_udp));
+ tx_desc->upper.data = odpdrv_cpu_to_le_32(0);
+
+ dma_wmb();
+
+ printf("Triggering xmit of dummy packet\n");
+ printf("tx_desc->buffer_addr == 0x%016lx\n", tx_desc->buffer_addr);
+ printf("tx_desc->lower == 0x%08x\n", tx_desc->lower.data);
+ printf("tx_desc->upper == 0x%08x\n", tx_desc->upper.data);
+
+ io_write32(odpdrv_cpu_to_le_32(idx + 1), ioaddr + E1000_TDT_OFFSET);
+
+ return;
}
const struct driver_ops e1000e_ops = {
@@ -198,8 +239,8 @@ const struct driver_ops e1000e_ops = {
.device = 0xdead,
.vfio_quirks = NULL,
.rx_fill = e1000e_rx_fill,
- .tx_fill = e1000e_tx_fill,
.recv = e1000e_recv,
- .xmit = NULL,
+ .xmit = e1000e_xmit,
.map_mmio = e1000e_map_mmio,
};
+
diff --git a/drivers/r8169.c b/drivers/r8169.c
index 922a6a0..e90ed7b 100644
--- a/drivers/r8169.c
+++ b/drivers/r8169.c
@@ -132,30 +132,19 @@ static inline void rtl8169_map_to_asic_tx(struct TxDesc *desc, dma_addr_t mappin
desc->addr = cpu_to_le64(mapping);
}
-static int r8169_tx_fill(int device, void *tx_data, struct iomem data,
- char *tx_buff[])
-{
- int i;
- struct TxDesc *r8169_txring = (struct TxDesc *) tx_data;
-
- for (i = 0; i < NUM_TX_DESC; i++) {
- rtl8169_map_to_asic_tx(&r8169_txring[i], data.iova + i * 2048,
- 2048);
- tx_buff[i] = (char *)(data.vaddr + i * 2048);
- }
-
- return 0;
-}
-
-void r8169_xmit(void *txring, char *tx_buff[], volatile void *ioaddr)
+void r8169_xmit(void *txring, struct iomem data, volatile void *ioaddr)
{
+ const int idx = 0;
__u32 opts[2];
__u32 status, len;
int entry = 0;
struct TxDesc *r8169_txring = (struct TxDesc *)txring;
+ char *tx_buff = (char *)(data.vaddr + idx * 2048);
/* XXX FIXME need proper packet size and sizeof(src) *NOT* dst */
- memcpy(tx_buff[0], pkt_udp, sizeof(pkt_udp));
+ memcpy(tx_buff, pkt_udp, sizeof(pkt_udp));
+ rtl8169_map_to_asic_tx(&r8169_txring[idx], data.iova + idx * 2048,
+ 2048);
/* FIXME no fragmentation support */
opts[0] = DescOwn;
opts[0] |= FirstFrag | LastFrag;
@@ -188,7 +177,6 @@ const struct driver_ops r8169_ops = {
.device = 0x8168,
.vfio_quirks = NULL,
.rx_fill = r8169_rx_fill,
- .tx_fill= r8169_tx_fill,
.recv = r8169_recv,
.xmit = r8169_xmit,
.map_mmio = r8169_map_mmio,
diff --git a/include/common.h b/include/common.h
index a59508e..38570d7 100644
--- a/include/common.h
+++ b/include/common.h
@@ -20,14 +20,6 @@ static inline int uio_rx_fill(const struct driver_ops *e, int device,
return 0;
}
-static inline int uio_tx_fill(const struct driver_ops *e, int device,
- void *txring, struct iomem data, char *tx_buf[])
-{
- if (e && e->tx_fill)
- return e->tx_fill(device, txring, data, tx_buf);
-
- return 0;
-}
static inline void uio_recv(const struct driver_ops *e, void *rxring,
char *rxbuffers[], volatile void *iomem)
@@ -39,10 +31,10 @@ static inline void uio_recv(const struct driver_ops *e, void *rxring,
}
static inline void uio_xmit(const struct driver_ops *e, void *txring,
- char *txbuffers[], volatile void *iomem)
+ struct iomem tx_data, volatile void *iomem)
{
if (e && e->xmit)
- e->xmit(txring, txbuffers, iomem);
+ e->xmit(txring, tx_data, iomem);
return;
}
diff --git a/include/drivers/driver_ops.h b/include/drivers/driver_ops.h
index 016d646..4ab973d 100644
--- a/include/drivers/driver_ops.h
+++ b/include/drivers/driver_ops.h
@@ -7,16 +7,13 @@ struct driver_ops {
__u16 device;
/* VFIO/PCI quirks */
int (*vfio_quirks)(void);
- /* prepare Tx descriptors */
+ /* prepare Rx descriptors */
int (*rx_fill)(int device, void *rxring, struct iomem data,
char *rx_buf[], volatile void *iomem);
- /* prepare Tx descriptors */
- int (*tx_fill)(int device, void *txring, struct iomem data,
- char *rx_buf[]);
/* receive */
void (*recv)(void *rxring, char *rxbuffers[], volatile void *iomem);
/* xmit */
- void (*xmit)(void *txring, char *txbuffers[], volatile void *iomem);
+ void (*xmit)(void *txring, struct iomem data, volatile void *iomem);
/* map MMIO */
void *(*map_mmio)(int device);
};
diff --git a/kernel/4.13.0/e1000e/netdev.c b/kernel/4.13.0/e1000e/netdev.c
index 5892d07..14dd72b 100644
--- a/kernel/4.13.0/e1000e/netdev.c
+++ b/kernel/4.13.0/e1000e/netdev.c
@@ -5688,6 +5688,10 @@ static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count)
*/
wmb();
+ printk("tx_desc->buffer_addr == 0x%016llx\n", tx_desc->buffer_addr);
+ printk("tx_desc->lower == 0x%08x\n", tx_desc->lower.data);
+ printk("tx_desc->upper == 0x%08x\n", tx_desc->upper.data);
+
tx_ring->next_to_use = i;
}
diff --git a/src/userspace_io.c b/src/userspace_io.c
index 3eae859..b7afb7e 100644
--- a/src/userspace_io.c
+++ b/src/userspace_io.c
@@ -80,7 +80,6 @@ int main(int argc, char *argv[])
char group_uuid[64]; /* 37 should be enough */
char drv_name[64];
char *rx_buff[256];
- char *tx_buff[256];
__u32 opts = 0;
memset(group_uuid, 0, sizeof(group_uuid));
@@ -164,14 +163,8 @@ int main(int argc, char *argv[])
goto out;
}
- /* Nothing to do actually */
- if (uio_tx_fill(exec_ops, device, txring, tx_data, tx_buff) != 0) {
- printf("Could not fill TxRing\n");
- goto out;
- }
-
ioctl(device, 500, NULL);
- uio_xmit(exec_ops, txring, tx_buff, mmio);
+ uio_xmit(exec_ops, txring, tx_data, mmio);
uio_recv(exec_ops, rxring, rx_buff, mmio);
out: