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