socsvn commit: r287036 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve
iateaca at FreeBSD.org
iateaca at FreeBSD.org
Sat Jun 13 15:47:48 UTC 2015
Author: iateaca
Date: Sat Jun 13 15:47:46 2015
New Revision: 287036
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287036
Log:
implement a mechanism to transmit and receive packets using a tap interface
Modified:
soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c
Modified: soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c
==============================================================================
--- soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Sat Jun 13 14:24:31 2015 (r287035)
+++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Sat Jun 13 15:47:46 2015 (r287036)
@@ -1,8 +1,14 @@
+
+#include <sys/ioctl.h>
+
#include <stdio.h>
#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "pci_emul.h"
+#include "mevent.h"
#include "if_edreg.h"
/*
@@ -56,6 +62,7 @@
uint8_t reset;
/* State Variables */
+ int tapfd;
uint8_t lintr;
uint8_t page;
uint8_t remote_read;
@@ -110,6 +117,14 @@
static int ne2000_reset_board(void);
static int ne2000_software_reset(struct pci_ne2000_softc *sc);
+static int
+ne2000_tap_init(struct pci_ne2000_softc *sc, char *tap_name);
+static int
+ne2000_tap_tx(struct pci_ne2000_softc *sc, uint8_t tpsr, uint16_t tbcr);
+static int
+ne2000_tap_rx(struct pci_ne2000_softc *sc);
+static void
+ne2000_tap_callback(int fd, enum ev_type type, void *param);
/*
* NE2000 module function definitions
@@ -171,9 +186,77 @@
}
static int
+ne2000_tap_init(struct pci_ne2000_softc *sc, char *tap_name)
+{
+ int err;
+ int opt = 1;
+ struct mevent *evf_read = NULL;
+
+ assert(tap_name != NULL);
+
+ sc->tapfd = open(tap_name, O_RDWR);
+ assert(sc->tapfd != -1);
+
+ err = ioctl(sc->tapfd, FIONBIO, &opt);
+ assert(err >= 0);
+
+ evf_read = mevent_add(sc->tapfd, EVF_READ, ne2000_tap_callback, sc);
+ assert(evf_read != NULL);
+
+ DPRINTF("Tap interface: fd: %d, opt: %d", sc->tapfd, opt);
+
+ return 0;
+}
+
+static int
+ne2000_tap_tx(struct pci_ne2000_softc *sc, uint8_t tpsr, uint16_t tbcr)
+{
+ ssize_t write_len;
+
+ write_len = write(sc->tapfd, sc->ram + tpsr * ED_PAGE_SIZE, tbcr);
+ assert(write_len > 0 && write_len == tbcr);
+
+ DPRINTF("Transmit Packet: from %d address of %d bytes",
+ tpsr * ED_PAGE_SIZE, tbcr);
+
+ ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR,
+ ED_ISR_PTX, ED_ISR_PTX);
+ pci_ne2000_update_intr(sc);
+
+ return 0;
+}
+
+static int
+ne2000_tap_rx(struct pci_ne2000_softc *sc)
+{
+ uint8_t dummybuf[2048];
+ ssize_t read_len;
+
+ read_len = read(sc->tapfd, dummybuf, sizeof(dummybuf));
+
+ DPRINTF("Receive Packet: from tap interface of %zd bytes", read_len);
+
+ return 0;
+}
+
+static void
+ne2000_tap_callback(int fd, enum ev_type type, void *param)
+{
+ int err;
+ struct pci_ne2000_softc *sc = (struct pci_ne2000_softc *)param;
+ assert(sc != NULL);
+
+ err = ne2000_tap_rx(sc);
+ assert(err == 0);
+
+ return;
+}
+
+static int
pci_ne2000_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
{
struct pci_ne2000_softc *sc = NULL;
+ int err;
#if DEBUG_NE2000 == 1
dbg = fopen("/tmp/bhyve_ne2000.log", "w+");
@@ -187,6 +270,11 @@
pi->pi_arg = sc;
sc->asc_pi = pi;
+ /* TODO - implement a better parsing of the input opts and get the name
+ * of the tap interface */
+ err = ne2000_tap_init(sc, "/dev/tap0");
+ assert(err == 0);
+
/* probe a RTL8029 PCI card as a generic NE2000 device */
pci_set_cfgdata16(pi, PCIR_DEVICE, 0x8029);
pci_set_cfgdata16(pi, PCIR_VENDOR, 0x10ec);
@@ -412,14 +500,8 @@
ED_P0_TBCR1);
tbcr = tbcr0 | (tbcr1 << 8);
- DPRINTF("Transmit Packet: from %d address of %d bytes",
- tpsr * ED_PAGE_SIZE, tbcr);
-
- /* TODO send the packet on the tap interface */
-
- ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR,
- ED_ISR_PTX, ED_ISR_PTX);
- pci_ne2000_update_intr(sc);
+ err = ne2000_tap_tx(sc, tpsr, tbcr);
+ assert(err == 0);
}
break;
case ED_P0_ISR:
More information about the svn-soc-all
mailing list