Date: Thu, 20 Aug 2015 17:24:15 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r289975 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve Message-ID: <201508201724.t7KHOF65070468@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508201724.t7KHOF65070468>
