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