diff options
Diffstat (limited to 'drivers/e1000e.c')
-rw-r--r-- | drivers/e1000e.c | 63 |
1 files changed, 41 insertions, 22 deletions
diff --git a/drivers/e1000e.c b/drivers/e1000e.c index f3e4cf6..1b30a32 100644 --- a/drivers/e1000e.c +++ b/drivers/e1000e.c @@ -128,40 +128,46 @@ static void print_packet(unsigned char *buffer) } #endif -static void e1000e_rx_desc_push(e1000e_rx_desc_t *rx_ring, int idx, dma_addr_t dma_addr, volatile void *ioaddr) -{ - rx_ring[idx].read.buffer_addr = odpdrv_cpu_to_le_64(dma_addr); - dma_wmb(); - - io_write32(odpdrv_cpu_to_le_32(idx), ioaddr + E1000_RDT_OFFSET); -} - static int e1000e_rx_fill(int device, void *rxring, struct iomem data, - char *rx_buff[], volatile void *ioaddr) + volatile char *rx_buff[], volatile void *ioaddr) { - e1000e_rx_desc_t *rx_ring = (e1000e_rx_desc_t *)rxring; + volatile e1000e_rx_desc_t *rx_ring = (e1000e_rx_desc_t *) rxring; int i; + memset((void *)rx_ring, 0, E1000E_RX_RING_SIZE_DEFAULT * sizeof(e1000e_rx_desc_t)); + /* TODO: support variable rx_ring size, configuration via ethtool */ - for (i = 0; i < E1000E_RX_RING_SIZE_DEFAULT; i++) { - rx_buff[i] = (char *)(data.vaddr + i * E1000E_RX_BUF_SIZE); - e1000e_rx_desc_push(rx_ring, i, data.iova + i * E1000E_RX_BUF_SIZE, ioaddr); + for (i = 0; i < E1000E_RX_RING_SIZE_DEFAULT - 1; i++) { + rx_buff[i] = + (char *) (data.vaddr + i * E1000E_RX_BUF_SIZE); + memset((void *) rx_buff[i], 0xa5, E1000E_RX_BUF_SIZE); + rx_ring[i].read.buffer_addr = + odpdrv_cpu_to_le_64(data.iova + + i * E1000E_RX_BUF_SIZE); + if (!(i & 15)) { + dma_wmb(); + io_write32(odpdrv_cpu_to_le_32(i), + ioaddr + E1000_RDT_OFFSET); + } } return 0; } -static void e1000e_recv(void *rxring, char *rx_buff[], volatile void *ioaddr) +static void e1000e_recv(void *rxring, volatile char *rx_buff[], volatile void *ioaddr) { - e1000e_rx_desc_t *rx_ring = (e1000e_rx_desc_t *)rxring; + volatile e1000e_rx_desc_t *rx_ring = (e1000e_rx_desc_t *)rxring; int i = 0; while (1) { if (i >= E1000E_RX_RING_SIZE_DEFAULT) i = 0; for (; i < E1000E_RX_RING_SIZE_DEFAULT; i++) { - e1000e_rx_desc_t *rx_desc = rx_ring + i; - uint32_t status = odpdrv_le_to_cpu_32(rx_desc->wb.upper.status_error); + volatile e1000e_rx_desc_t *rx_desc = rx_ring + i; + uint32_t status; + + dma_rmb(); + status = odpdrv_le_to_cpu_32(rx_desc->wb.upper.status_error); if (!(status & E1000E_RX_DESC_STAT_DONE)) { usleep(100*1000); @@ -179,6 +185,13 @@ static void e1000e_recv(void *rxring, char *rx_buff[], volatile void *ioaddr) } else { int pkt_size = odpdrv_le_to_cpu_16(rx_desc->wb.upper.length); +#if 0 + while ((unsigned char)rx_buff[i][0] == 0xa5U) { + printf("Packet payload is garbage, waiting ...\n"); + usleep(1000); + printf("Done waiting\n"); + } +#endif printf("desc[%03d]: size= %5d ", i, pkt_size); print_packet((unsigned char *)rx_buff[i]); printf("\n"); @@ -197,9 +210,9 @@ void *e1000e_map_mmio(int device) void e1000e_xmit(void *txring, struct iomem data, volatile void *ioaddr) { /* test udp packet */ - static const char pkt_udp[] = { + static const unsigned char pkt_udp[] = { 0x02, 0x50, 0x43, 0xff, 0xff, 0x01, /* mac dst */ - 0x00, 0x60, 0xdd, 0x45, 0xe5, 0x67, /* mac src */ + 0xf4, 0x4d, 0x30, 0x64, 0x43, 0xf7, /* 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 */ @@ -216,12 +229,12 @@ void e1000e_xmit(void *txring, struct iomem data, volatile void *ioaddr) E1000_TXD_CMD_IDE; for (idx = 0; idx < 100; idx++) { - e1000_tx_desc_t *tx_desc = + volatile e1000_tx_desc_t *tx_desc = (e1000_tx_desc_t *) txring + idx; - char *tx_buff = (char *) (data.vaddr + idx * 2048); + volatile unsigned char *tx_buff = (unsigned char *) (data.vaddr + idx * 2048); /* XXX FIXME need proper packet size and sizeof(src) *NOT* dst */ - memcpy(tx_buff, pkt_udp, sizeof(pkt_udp)); + memcpy((void *)tx_buff, pkt_udp, sizeof(pkt_udp)); tx_desc->buffer_addr = odpdrv_cpu_to_le_64(data.iova + idx * 2048); tx_desc->lower.data = @@ -231,6 +244,8 @@ void e1000e_xmit(void *txring, struct iomem data, volatile void *ioaddr) dma_wmb(); printf("Triggering xmit of dummy packet\n"); + print_packet((void *)tx_buff); + printf("tx_desc->buffer_addr == 0x%016lx\n", tx_desc->buffer_addr); printf("tx_desc->lower == 0x%08x\n", tx_desc->lower.data); @@ -247,6 +262,10 @@ void e1000e_xmit(void *txring, struct iomem data, volatile void *ioaddr) printf("TDT == 0x%08x\n", io_read32(ioaddr + E1000_TDT_OFFSET)); printf("TDH == 0x%08x\n", io_read32(ioaddr + E1000_TDH_OFFSET)); + 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); } return; |