socsvn commit: r289821 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve

iateaca at FreeBSD.org iateaca at FreeBSD.org
Mon Aug 17 09:13:45 UTC 2015


Author: iateaca
Date: Mon Aug 17 09:13:43 2015
New Revision: 289821
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289821

Log:
  redesign the emulation of the CR register

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	Mon Aug 17 07:36:12 2015	(r289820)
+++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c	Mon Aug 17 09:13:43 2015	(r289821)
@@ -124,6 +124,8 @@
 ne2000_write_asic(struct pci_ne2000_softc *sc, uint8_t offset, uint16_t value);
 
 static int
+ne2000_emul_reg_cr(struct pci_ne2000_softc *sc, uint8_t value);
+static int
 ne2000_emul_reg_page0(struct pci_ne2000_softc *sc, uint8_t offset,
 		uint8_t value);
 static int
@@ -653,24 +655,9 @@
 {
 	int err;
 
-	/* check is not selected a new page */
-	if (offset == ED_P0_CR) {
-		switch (value & (ED_CR_PS0 | ED_CR_PS1)) {
-		case ED_CR_PAGE_0:
-			sc->page = NE2000_P0;
-			break;
-		case ED_CR_PAGE_1:
-			sc->page = NE2000_P1;
-			break;
-		case ED_CR_PAGE_2:
-			DPRINTF("The ED driver seleted PAGE2");
-			assert(0);
-			break;
-		case ED_CR_PAGE_3:
-			sc->page = NE2000_P3;
-			break;
-		}
-	}
+	/* the CR register is located always at offset = 0 */
+	if (offset == ED_P0_CR || offset == ED_P1_CR || offset == ED_P2_CR)
+		return ne2000_emul_reg_cr(sc, value);
 
 	if (!(sc->page == NE2000_P0 && offset == ED_P0_ISR))
 		ne2000_set_reg_by_offset(sc, sc->page, offset, value);
@@ -768,8 +755,7 @@
 }
 
 static int
-ne2000_emul_reg_page0(struct pci_ne2000_softc *sc, uint8_t offset,
-		uint8_t value)
+ne2000_emul_reg_cr(struct pci_ne2000_softc *sc, uint8_t value)
 {
 	int err;
 	uint8_t rbcr0 = 0;
@@ -786,56 +772,85 @@
 	uint16_t tbcr = 0;
 	uint8_t tpsr = 0;
 
+	/* check is not selected a new page */
+	switch (value & (ED_CR_PS0 | ED_CR_PS1)) {
+	case ED_CR_PAGE_0:
+		sc->page = NE2000_P0;
+		break;
+	case ED_CR_PAGE_1:
+		sc->page = NE2000_P1;
+		break;
+	case ED_CR_PAGE_2:
+		DPRINTF("The ED driver seleted PAGE2");
+		assert(0);
+		break;
+	case ED_CR_PAGE_3:
+		sc->page = NE2000_P3;
+		break;
+	}
+
+	/* emulate any command specified in the CR register */
+	if (value & ED_CR_STP) {
+		err = ne2000_software_reset(sc);
+		assert(err == 0);
+	}
+	if (value & ED_CR_RD2)
+		assert(!(sc->remote_read || sc->remote_write));
+	if (value & (ED_CR_RD0 | ED_CR_RD1)) {
+		assert(value & ED_CR_STA);
+
+		if (value & ED_CR_RD0)
+			sc->remote_read = 1;
+		else
+			sc->remote_write = 1;
+
+		rbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+				ED_P0_RBCR0);
+		rbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+				ED_P0_RBCR1);
+		rbcr = rbcr0 | (rbcr1 << 8);
+
+		rsar0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+				ED_P0_RSAR0);
+		rsar1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+				ED_P0_RSAR1);
+		rsar = rsar0 | (rsar1 << 8);
+
+		DPRINTF("Remote DMA %s: from %d address of %d bytes",
+			sc->remote_read ? "read" : "write", rsar, rbcr);
+	}
+	if (value & ED_CR_TXP) {
+		assert(!(sc->remote_read || sc->remote_write));
+		assert(value & ED_CR_STA);
+
+		tpsr = ne2000_get_reg_by_offset(sc, NE2000_P0,
+				ED_P0_TPSR);
+		tbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+				ED_P0_TBCR0);
+		tbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
+				ED_P0_TBCR1);
+		tbcr = tbcr0 | (tbcr1 << 8);
+
+		err = ne2000_tap_tx(sc, tpsr, tbcr);
+		assert(err == 0);
+	}
+
+	/* store the value in the CR register located in the Page0 */
+	ne2000_set_reg_by_offset(sc, NE2000_P0, ED_P0_CR, value);
+
+	return 0;
+}
+
+static int
+ne2000_emul_reg_page0(struct pci_ne2000_softc *sc, uint8_t offset,
+		uint8_t value)
+{
 	uint8_t pstart = 0;
 	uint8_t pstop = 0;
 
-	switch (offset) {
-	case ED_P0_CR:
-		if (value & ED_CR_STP) {
-			err = ne2000_software_reset(sc);
-			assert(err == 0);
-		}
-		if (value & ED_CR_RD2)
-			assert(!(sc->remote_read || sc->remote_write));
-		if (value & (ED_CR_RD0 | ED_CR_RD1)) {
-			assert(value & ED_CR_STA);
-
-			if (value & ED_CR_RD0)
-				sc->remote_read = 1;
-			else
-				sc->remote_write = 1;
-
-			rbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
-					ED_P0_RBCR0);
-			rbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
-					ED_P0_RBCR1);
-			rbcr = rbcr0 | (rbcr1 << 8);
-
-			rsar0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
-					ED_P0_RSAR0);
-			rsar1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
-					ED_P0_RSAR1);
-			rsar = rsar0 | (rsar1 << 8);
+	assert(offset != ED_P0_CR);
 
-			DPRINTF("Remote DMA %s: from %d address of %d bytes",
-				sc->remote_read ? "read" : "write", rsar, rbcr);
-		}
-		if (value & ED_CR_TXP) {
-			assert(!(sc->remote_read || sc->remote_write));
-			assert(value & ED_CR_STA);
-
-			tpsr = ne2000_get_reg_by_offset(sc, NE2000_P0,
-					ED_P0_TPSR);
-			tbcr0 = ne2000_get_reg_by_offset(sc, NE2000_P0,
-					ED_P0_TBCR0);
-			tbcr1 = ne2000_get_reg_by_offset(sc, NE2000_P0,
-					ED_P0_TBCR1);
-			tbcr = tbcr0 | (tbcr1 << 8);
-
-			err = ne2000_tap_tx(sc, tpsr, tbcr);
-			assert(err == 0);
-		}
-		break;
+	switch (offset) {
 	case ED_P0_PSTART:
 		DPRINTF("Page Start Register: %d", value);
 		assert(value > 0 && value * ED_PAGE_SIZE < NE2000_MEM_SIZE);
@@ -867,15 +882,12 @@
 ne2000_emul_reg_page1(struct pci_ne2000_softc *sc, uint8_t offset,
 		uint8_t value)
 {
-	int err;
 	uint8_t pstart = 0;
 	uint8_t pstop = 0;
 
+	assert(offset != ED_P1_CR);
+
 	switch (offset) {
-	case ED_P1_CR:
-		err = ne2000_emul_reg_page0(sc, offset, value);
-		assert(err == 0);
-		break;
 	case ED_P1_PAR0 ... ED_P1_PAR5:
 		DPRINTF("PAR[%d]: 0x%x", offset - ED_P1_PAR0, value);
 		break;


More information about the svn-soc-all mailing list