From owner-svn-soc-all@FreeBSD.ORG Sat Jun 13 15:47:48 2015 Return-Path: Delivered-To: svn-soc-all@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0F48D54E for ; Sat, 13 Jun 2015 15:47:48 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id F11288ED for ; Sat, 13 Jun 2015 15:47:47 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id t5DFll8f052998 for ; Sat, 13 Jun 2015 15:47:47 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id t5DFllwF052996 for svn-soc-all@FreeBSD.org; Sat, 13 Jun 2015 15:47:47 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 13 Jun 2015 15:47:47 GMT Message-Id: <201506131547.t5DFllwF052996@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r287036 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Jun 2015 15:47:48 -0000 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 + #include #include +#include +#include #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: