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

iateaca at FreeBSD.org iateaca at FreeBSD.org
Thu Aug 20 17:24:16 UTC 2015


Author: iateaca
Date: Thu Aug 20 17:24:15 2015
New Revision: 289975
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289975

Log:
  redesign: implement the ne2000_update_intr function with generic handlers for both PCI and LPC

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	Thu Aug 20 16:07:51 2015	(r289974)
+++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c	Thu Aug 20 17:24:15 2015	(r289975)
@@ -58,18 +58,12 @@
 #define ETHER_MAX_FRAME_LEN	(ETHER_MAX_LEN - ETHER_CRC_LEN)
 #define ETHER_MIN_FRAME_LEN	(ETHER_MIN_LEN - ETHER_CRC_LEN)
 
+typedef void (*ne2000_intr_func_t)(void *arg);
+
 /*
  * NE2000 data structures
  */
 struct ne2000_softc {
-	struct pci_devinst *pci_inst;
-
-	/*
-	 * one single mutex used to lock the reception flow with
-	 * the .pe_barwrite and .pe_barwrite flows
-	 */
-	pthread_mutex_t mtx;
-
 	/* NIC registers */
 	uint8_t nic_regs[NE2000_PAGE_COUNT][NE2000_PAGE_SIZE];
 
@@ -86,6 +80,19 @@
 	/* NIC memory is 16k */
 	uint8_t ram[NE2000_MEM_SIZE];
 	uint8_t rcv_buf[ETHER_MAX_FRAME_LEN];
+
+	/*
+	 * one single mutex used to lock the reception flow with
+	 * the .pe_barwrite and .pe_barwrite flows
+	 */
+	pthread_mutex_t mtx;
+
+	/* Interrupts callbacks (PCI or LPC) */
+	ne2000_intr_func_t intr_assert;
+	ne2000_intr_func_t intr_deassert;
+
+	/* The argument used by the interrupts callbacks */
+	void *intr_arg;
 };
 
 /*
@@ -101,8 +108,12 @@
 ne2000_set_field_by_offset(struct ne2000_softc *sc, uint8_t page,
 		uint8_t offset, uint8_t mask, uint8_t value);
 
-static int
-ne2000_init(struct ne2000_softc *sc, char *opts);
+static struct ne2000_softc *
+ne2000_init(ne2000_intr_func_t intr_assert, ne2000_intr_func_t intr_deassert,
+		void *intr_arg, char *opts);
+
+static void
+ne2000_update_intr(struct ne2000_softc *sc);
 
 static uint8_t
 ne2000_read_nic(struct ne2000_softc *sc, uint8_t offset);
@@ -171,6 +182,11 @@
 pci_ne2000_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
 		int baridx, uint64_t offset, int size);
 
+static void
+pci_ne2000_intr_assert(void *arg);
+static void
+pci_ne2000_intr_deassert(void *arg);
+
 /*
  * NE2000 module function definitions
  */
@@ -208,28 +224,6 @@
 	ne2000_set_reg_by_offset(sc, page, offset, reg_value);
 }
 
-static void
-pci_ne2000_update_intr(struct ne2000_softc *sc)
-{
-	uint8_t isr = 0;
-	uint8_t imr = 0;
-
-	isr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_ISR);
-	imr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_IMR);
-
-	if (imr & isr) {
-		if (!sc->lintr) {
-			pci_lintr_assert(sc->pci_inst);
-			sc->lintr = 1;
-		}
-	} else {
-		if (sc->lintr) {
-			pci_lintr_deassert(sc->pci_inst);
-			sc->lintr = 0;
-		}
-	}
-}
-
 static int
 ne2000_tap_init(struct ne2000_softc *sc, char *tap_name)
 {
@@ -266,7 +260,7 @@
 
 	ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR,
 			ED_ISR_PTX, ED_ISR_PTX);
-	pci_ne2000_update_intr(sc);
+	ne2000_update_intr(sc);
 
 	return 0;
 }
@@ -358,7 +352,7 @@
 	ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR,
 			ED_ISR_PRX, ED_ISR_PRX);
 
-	pci_ne2000_update_intr(sc);
+	ne2000_update_intr(sc);
 
 	return 0;
 }
@@ -803,7 +797,7 @@
 	case ED_P0_ISR:
 		DPRINTF("ISR Register: %d", value);
 		ne2000_set_field_by_offset(sc, NE2000_P0, ED_P0_ISR, value, 0);
-		pci_ne2000_update_intr(sc);
+		ne2000_update_intr(sc);
 		break;
 	case ED_P0_RCR:
 		DPRINTF("RCR Register: %d", value);
@@ -863,23 +857,36 @@
 	return 0;
 }
 
-static int
-ne2000_init(struct ne2000_softc *sc, char *opts)
+static struct ne2000_softc *
+ne2000_init(ne2000_intr_func_t intr_assert, ne2000_intr_func_t intr_deassert,
+		void *intr_arg, char *opts)
 {
+	struct ne2000_softc *sc = NULL;
+
 	/* the default mac address is 00:a0:98:4a:0e:ee */
 	uint8_t mac[ETHER_ADDR_LEN] = {0x00, 0xa0, 0x98, 0x4a, 0x0e, 0xee};
 	char tap_name[MAX_INPUT_LEN];
 	int err;
 
+	assert(intr_assert);
+	assert(intr_deassert);
+	assert(intr_arg);
+
 #if DEBUG_NE2000 == 1
 	dbg = fopen("/tmp/bhyve_ne2000.log", "w+");
 #endif
 
+	sc = calloc(1, sizeof(struct ne2000_softc));
+
+	sc->intr_assert = intr_assert;
+	sc->intr_deassert = intr_deassert;
+	sc->intr_arg = intr_arg;
+
 	err = ne2000_parse_input(opts, tap_name, mac);
 	if (err != 0) {
 		printf("Use input param like: -s x:y,ne2000-net,tap_name[,mac address]");
 		free(sc);
-		return -1;
+		return NULL;
 	}
 
 	err = pthread_mutex_init(&sc->mtx, NULL);
@@ -902,7 +909,29 @@
 	sc->ram[8] = mac[4];
 	sc->ram[10] = mac[5];
 
-	return 0;
+	return sc;
+}
+
+static void
+ne2000_update_intr(struct ne2000_softc *sc)
+{
+	uint8_t isr = 0;
+	uint8_t imr = 0;
+
+	isr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_ISR);
+	imr = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_IMR);
+
+	if (imr & isr) {
+		if (!sc->lintr) {
+			sc->intr_assert(sc->intr_arg);
+			sc->lintr = 1;
+		}
+	} else {
+		if (sc->lintr) {
+			sc->intr_deassert(sc->intr_arg);
+			sc->lintr = 0;
+		}
+	}
 }
 
 static uint8_t
@@ -1117,16 +1146,6 @@
 	assert(ctx != NULL);
 	assert(pi != NULL);
 
-	sc = calloc(1, sizeof(struct ne2000_softc));
-
-	/* initialize the ne2000 data structure */
-	if (ne2000_init(sc, opts) != 0)
-		return 1;
-
-	/* save the pci instance into the ne2000 structure */
-	sc->pci_inst = pi;
-	pi->pi_arg = sc;
-
 	/* probe a RTL8029 PCI card as a generic NE2000 device */
 	pci_set_cfgdata16(pi, PCIR_DEVICE, 0x8029);
 	pci_set_cfgdata16(pi, PCIR_VENDOR, 0x10ec);
@@ -1138,6 +1157,13 @@
 	/* allocate an IRQ pin for our slot */
 	pci_lintr_request(pi);
 
+	/* initialize the ne2000 data structure */
+	sc = ne2000_init(pci_ne2000_intr_assert, pci_ne2000_intr_deassert, pi, opts);
+	if (sc == NULL)
+		return 1;
+
+	pi->pi_arg = sc;
+
 	return 0;
 }
 
@@ -1196,6 +1222,26 @@
 	return value;
 }
 
+static void
+pci_ne2000_intr_assert(void *arg)
+{
+	struct pci_devinst *pi = (struct pci_devinst *)arg;
+
+	pci_lintr_assert(pi);
+
+	return;
+}
+
+static void
+pci_ne2000_intr_deassert(void *arg)
+{
+	struct pci_devinst *pi = (struct pci_devinst *)arg;
+
+	pci_lintr_deassert(pi);
+
+	return;
+}
+
 struct pci_devemu pci_de_ne2000_net = {
 	.pe_emu         = "ne2000-net",
 	.pe_init        = pci_ne2000_init,


More information about the svn-soc-all mailing list