svn commit: r304424 - stable/11/usr.sbin/bhyve
Alexander Motin
mav at FreeBSD.org
Thu Aug 18 11:51:15 UTC 2016
Author: mav
Date: Thu Aug 18 11:51:14 2016
New Revision: 304424
URL: https://svnweb.freebsd.org/changeset/base/304424
Log:
MFC r302504, r302666, r302668, r302932, r302933:
Add emulation for Intel e1000 (e82545) network adapter.
The code was successfully tested with FreeBSD, Linux, Solaris and Windows
guests. This interface is predictably slower (about 2x) then virtio-net,
but it is very helpful for guests not supporting virtio-net by default.
Thanks to Jeremiah Lott and Peter Grehan for doing original heavy lifting.
Added:
stable/11/usr.sbin/bhyve/pci_e82545.c
- copied, changed from r302504, head/usr.sbin/bhyve/pci_e82545.c
Modified:
stable/11/usr.sbin/bhyve/Makefile
stable/11/usr.sbin/bhyve/bhyve.8
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/usr.sbin/bhyve/Makefile
==============================================================================
--- stable/11/usr.sbin/bhyve/Makefile Thu Aug 18 11:49:49 2016 (r304423)
+++ stable/11/usr.sbin/bhyve/Makefile Thu Aug 18 11:51:14 2016 (r304424)
@@ -28,6 +28,7 @@ SRCS= \
mevent.c \
mptbl.c \
pci_ahci.c \
+ pci_e82545.c \
pci_emul.c \
pci_fbuf.c \
pci_hostbridge.c \
@@ -61,6 +62,8 @@ SRCS+= vmm_instruction_emul.c
LIBADD= vmmapi md pthread z
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/e1000
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/mii
CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/usb/controller
WARNS?= 2
Modified: stable/11/usr.sbin/bhyve/bhyve.8
==============================================================================
--- stable/11/usr.sbin/bhyve/bhyve.8 Thu Aug 18 11:49:49 2016 (r304423)
+++ stable/11/usr.sbin/bhyve/bhyve.8 Thu Aug 18 11:51:14 2016 (r304424)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 8, 2016
+.Dd July 9, 2016
.Dt BHYVE 8
.Os
.Sh NAME
@@ -177,6 +177,8 @@ AHCI controller attached to arbitraty de
AHCI controller attached to an ATAPI CD/DVD.
.It Li ahci-hd
AHCI controller attached to a SATA hard-drive.
+.It Li e1000
+Intel e82545 network interface.
.It Li uart
PCI 16550 serial device.
.It Li lpc
Copied and modified: stable/11/usr.sbin/bhyve/pci_e82545.c (from r302504, head/usr.sbin/bhyve/pci_e82545.c)
==============================================================================
--- head/usr.sbin/bhyve/pci_e82545.c Sat Jul 9 20:41:59 2016 (r302504, copy source)
+++ stable/11/usr.sbin/bhyve/pci_e82545.c Thu Aug 18 11:51:14 2016 (r304424)
@@ -109,12 +109,8 @@ __FBSDID("$FreeBSD$");
#define E1000_ICR_SRPD 0x00010000
-/*
- * XXX does this actually have a limit on the 82545 ?
- * There is a limit on the max number of bytes, but perhaps not
- * on descriptors ??
- */
-#define I82545_MAX_TXSEGS 20
+/* This is an arbitrary number. There is no hard limit on the chip. */
+#define I82545_MAX_TXSEGS 64
/* Legacy receive descriptor */
struct e1000_rx_desc {
@@ -1050,15 +1046,18 @@ e82545_transmit_backend(struct e82545_so
}
static void
-e82545_transmit_done(struct e82545_softc *sc, union e1000_tx_udesc **txwb,
- int nwb)
+e82545_transmit_done(struct e82545_softc *sc, uint16_t head, uint16_t tail,
+ uint16_t dsize, int *tdwb)
{
- int i;
+ union e1000_tx_udesc *dsc;
- /* Write-back tx descriptor status */
- for (i = 0; i < nwb; i++)
- txwb[i]->td.upper.data |= E1000_TXD_STAT_DD;
- /* XXX wmb() */
+ for ( ; head != tail; head = (head + 1) % dsize) {
+ dsc = &sc->esc_txdesc[head];
+ if (dsc->td.lower.data & E1000_TXD_CMD_RS) {
+ dsc->td.upper.data |= E1000_TXD_STAT_DD;
+ *tdwb = 1;
+ }
+ }
}
static int
@@ -1068,22 +1067,21 @@ e82545_transmit(struct e82545_softc *sc,
uint8_t *hdr, *hdrp;
struct iovec iovb[I82545_MAX_TXSEGS + 2];
struct iovec tiov[I82545_MAX_TXSEGS + 2];
- union e1000_tx_udesc *txwb[I82545_MAX_TXSEGS];
struct e1000_context_desc *cd;
struct ck_info ckinfo[2];
struct iovec *iov;
union e1000_tx_udesc *dsc;
- int desc, dtype, len, ntype, nwb, iovcnt, tlen, hdrlen, vlen, tcp, tso;
+ int desc, dtype, len, ntype, iovcnt, tlen, hdrlen, vlen, tcp, tso;
int mss, paylen, seg, tiovcnt, left, now, nleft, nnow, pv, pvoff;
uint32_t tcpsum, tcpseq;
- uint16_t ipcs, tcpcs, ipid;
+ uint16_t ipcs, tcpcs, ipid, ohead;
ckinfo[0].ck_valid = ckinfo[1].ck_valid = 0;
iovcnt = 0;
tlen = 0;
- nwb = 0;
ntype = 0;
tso = 0;
+ ohead = head;
/* iovb[0/1] may be used for writable copy of headers. */
iov = &iovb[2];
@@ -1104,11 +1102,8 @@ e82545_transmit(struct e82545_softc *sc,
head, dsc->td.buffer_addr,
dsc->td.upper.data, dsc->td.lower.data);
/* Save context and return */
- /* XXX ignore DD processing here */
sc->esc_txctx = dsc->cd;
- *rhead = (head + 1) % dsize;
- return (1);
- break;
+ goto done;
case E1000_TXD_TYP_L:
DPRINTF("tx legacy desc idx %d: %08x%08x\r\n",
head, dsc->td.upper.data, dsc->td.lower.data);
@@ -1142,16 +1137,14 @@ e82545_transmit(struct e82545_softc *sc,
(dsc->td.lower.data & E1000_TXD_CMD_IFCS) == 0)
len -= 2;
tlen += len;
- iov[iovcnt].iov_base = paddr_guest2host(sc->esc_ctx,
- dsc->td.buffer_addr, len);
- iov[iovcnt].iov_len = len;
+ if (iovcnt < I82545_MAX_TXSEGS) {
+ iov[iovcnt].iov_base = paddr_guest2host(
+ sc->esc_ctx, dsc->td.buffer_addr, len);
+ iov[iovcnt].iov_len = len;
+ }
iovcnt++;
}
- /* Record the descriptor addres if write-back requested */
- if (dsc->td.lower.data & E1000_TXD_CMD_RS)
- txwb[nwb++] = dsc;
-
/*
* Pull out info that is valid in the final descriptor
* and exit descriptor loop.
@@ -1197,6 +1190,12 @@ e82545_transmit(struct e82545_softc *sc,
}
}
+ if (iovcnt > I82545_MAX_TXSEGS) {
+ WPRINTF("tx too many descriptors (%d > %d) -- dropped\r\n",
+ iovcnt, I82545_MAX_TXSEGS);
+ goto done;
+ }
+
hdrlen = vlen = 0;
/* Estimate writable space for VLAN header insertion. */
if ((sc->esc_CTRL & E1000_CTRL_VME) &&
@@ -1356,12 +1355,10 @@ e82545_transmit(struct e82545_softc *sc,
}
done:
- /* Record if tx descs were written back */
- e82545_transmit_done(sc, txwb, nwb);
- if (nwb)
- *tdwb = 1;
+ head = (head + 1) % dsize;
+ e82545_transmit_done(sc, ohead, head, dsize, tdwb);
- *rhead = (head + 1) % dsize;
+ *rhead = head;
return (desc + 1);
}
@@ -2000,6 +1997,7 @@ e82545_read_register(struct e82545_softc
break;
default:
DPRINTF("Unknown read register: 0x%x\r\n", offset);
+ retval = 0;
break;
}
@@ -2040,6 +2038,7 @@ e82545_write(struct vmctx *ctx, int vcpu
DPRINTF("Unknown io bar write offset:0x%lx value:0x%lx size:%d\r\n", offset, value, size);
break;
}
+ break;
case E82545_BAR_REGISTER:
if (size != 4) {
DPRINTF("Wrong register write size:%d offset:0x%lx value:0x%lx\r\n", size, offset, value);
@@ -2092,6 +2091,7 @@ e82545_read(struct vmctx *ctx, int vcpu,
offset, size);
break;
}
+ break;
case E82545_BAR_REGISTER:
if (size != 4) {
DPRINTF("Wrong register read size:%d offset:0x%lx\r\n",
More information about the svn-src-stable
mailing list