Author: mav
Date: Thu Aug 18 11:56:07 2016
New Revision: 304425
URL: https://svnweb.freebsd.org/changeset/base/304425

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/10/usr.sbin/bhyve/pci_e82545.c
     - copied, changed from r302504, head/usr.sbin/bhyve/pci_e82545.c
Modified:
  stable/10/usr.sbin/bhyve/Makefile
  stable/10/usr.sbin/bhyve/bhyve.8
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/bhyve/Makefile
==============================================================================
--- stable/10/usr.sbin/bhyve/Makefile   Thu Aug 18 11:51:14 2016        
(r304424)
+++ stable/10/usr.sbin/bhyve/Makefile   Thu Aug 18 11:56:07 2016        
(r304425)
@@ -23,6 +23,7 @@ SRCS= \
        mevent.c                \
        mptbl.c                 \
        pci_ahci.c              \
+       pci_e82545.c            \
        pci_emul.c              \
        pci_hostbridge.c        \
        pci_irq.c               \
@@ -48,6 +49,10 @@ SRCS+=       vmm_instruction_emul.c
 DPADD= ${LIBVMMAPI} ${LIBMD} ${LIBUTIL} ${LIBPTHREAD}
 LDADD= -lvmmapi -lmd -lutil -lpthread
 
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/e1000
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/mii
+CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/usb/controller
+
 WARNS?=        2
 
 .include <bsd.prog.mk>

Modified: stable/10/usr.sbin/bhyve/bhyve.8
==============================================================================
--- stable/10/usr.sbin/bhyve/bhyve.8    Thu Aug 18 11:51:14 2016        
(r304424)
+++ stable/10/usr.sbin/bhyve/bhyve.8    Thu Aug 18 11:56:07 2016        
(r304425)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 8, 2016
+.Dd July 9, 2016
 .Dt BHYVE 8
 .Os
 .Sh NAME
@@ -174,6 +174,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/10/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/10/usr.sbin/bhyve/pci_e82545.c       Thu Aug 18 11:56:07 2016        
(r304425)
@@ -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",
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to