Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_e82545.c
| Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
| #include <pthread.h> | #include <pthread.h> | ||||
| #include <pthread_np.h> | #include <pthread_np.h> | ||||
| #include "e1000_regs.h" | #include "e1000_regs.h" | ||||
| #include "e1000_defines.h" | #include "e1000_defines.h" | ||||
| #include "mii.h" | #include "mii.h" | ||||
| #include "bhyverun.h" | #include "bhyverun.h" | ||||
| #include "config.h" | |||||
| #include "debug.h" | #include "debug.h" | ||||
| #include "pci_emul.h" | #include "pci_emul.h" | ||||
| #include "mevent.h" | #include "mevent.h" | ||||
| #include "net_utils.h" | #include "net_utils.h" | ||||
| #include "net_backends.h" | #include "net_backends.h" | ||||
| /* Hardware/register definitions XXX: move some to common code. */ | /* Hardware/register definitions XXX: move some to common code. */ | ||||
| #define E82545_VENDOR_ID_INTEL 0x8086 | #define E82545_VENDOR_ID_INTEL 0x8086 | ||||
| ▲ Show 20 Lines • Show All 2,196 Lines • ▼ Show 20 Lines | e82545_reset(struct e82545_softc *sc, int drvr) | ||||
| sc->esc_TCTL = 0; | sc->esc_TCTL = 0; | ||||
| sc->esc_TDLEN = 0; | sc->esc_TDLEN = 0; | ||||
| sc->esc_TDT = 0; | sc->esc_TDT = 0; | ||||
| sc->esc_TDHr = sc->esc_TDH = 0; | sc->esc_TDHr = sc->esc_TDH = 0; | ||||
| sc->esc_TXDCTL = 0; | sc->esc_TXDCTL = 0; | ||||
| } | } | ||||
| static int | static int | ||||
| e82545_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | e82545_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | ||||
| { | { | ||||
| char nstr[80]; | char nstr[80]; | ||||
| struct e82545_softc *sc; | struct e82545_softc *sc; | ||||
| char *optscopy; | const char *mac; | ||||
| char *vtopts; | int err; | ||||
| int mac_provided; | |||||
| DPRINTF("Loading with options: %s", opts); | |||||
| /* Setup our softc */ | /* Setup our softc */ | ||||
| sc = calloc(1, sizeof(*sc)); | sc = calloc(1, sizeof(*sc)); | ||||
| pi->pi_arg = sc; | pi->pi_arg = sc; | ||||
| sc->esc_pi = pi; | sc->esc_pi = pi; | ||||
| sc->esc_ctx = ctx; | sc->esc_ctx = ctx; | ||||
| pthread_mutex_init(&sc->esc_mtx, NULL); | pthread_mutex_init(&sc->esc_mtx, NULL); | ||||
| Show All 20 Lines | e82545_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | ||||
| pci_emul_alloc_bar(pi, E82545_BAR_REGISTER, PCIBAR_MEM32, | pci_emul_alloc_bar(pi, E82545_BAR_REGISTER, PCIBAR_MEM32, | ||||
| E82545_BAR_REGISTER_LEN); | E82545_BAR_REGISTER_LEN); | ||||
| pci_emul_alloc_bar(pi, E82545_BAR_FLASH, PCIBAR_MEM32, | pci_emul_alloc_bar(pi, E82545_BAR_FLASH, PCIBAR_MEM32, | ||||
| E82545_BAR_FLASH_LEN); | E82545_BAR_FLASH_LEN); | ||||
| pci_emul_alloc_bar(pi, E82545_BAR_IO, PCIBAR_IO, | pci_emul_alloc_bar(pi, E82545_BAR_IO, PCIBAR_IO, | ||||
| E82545_BAR_IO_LEN); | E82545_BAR_IO_LEN); | ||||
| /* | mac = get_config_value_node(nvl, "mac"); | ||||
| * Attempt to open the net backend and read the MAC address | if (mac != NULL) { | ||||
| * if specified. Copied from virtio-net, slightly modified. | err = net_parsemac(mac, sc->esc_mac.octet); | ||||
| */ | |||||
| mac_provided = 0; | |||||
| sc->esc_be = NULL; | |||||
| if (opts != NULL) { | |||||
| int err = 0; | |||||
| optscopy = vtopts = strdup(opts); | |||||
| (void) strsep(&vtopts, ","); | |||||
| /* | |||||
| * Parse the list of options in the form | |||||
| * key1=value1,...,keyN=valueN. | |||||
| */ | |||||
| while (vtopts != NULL) { | |||||
| char *value = vtopts; | |||||
| char *key; | |||||
| key = strsep(&value, "="); | |||||
| if (value == NULL) | |||||
| break; | |||||
| vtopts = value; | |||||
| (void) strsep(&vtopts, ","); | |||||
| if (strcmp(key, "mac") == 0) { | |||||
| err = net_parsemac(value, sc->esc_mac.octet); | |||||
| if (err) | |||||
| break; | |||||
| mac_provided = 1; | |||||
| } | |||||
| } | |||||
| free(optscopy); | |||||
| if (err) { | if (err) { | ||||
| free(sc); | free(sc); | ||||
| return (err); | return (err); | ||||
| } | } | ||||
| } else | |||||
| net_genmac(pi, sc->esc_mac.octet); | |||||
| err = netbe_init(&sc->esc_be, opts, e82545_rx_callback, sc); | err = netbe_init(&sc->esc_be, nvl, e82545_rx_callback, sc); | ||||
| if (err) { | if (err) { | ||||
| free(sc); | free(sc); | ||||
| return (err); | return (err); | ||||
| } | } | ||||
| } | |||||
| if (!mac_provided) { | |||||
| net_genmac(pi, sc->esc_mac.octet); | |||||
| } | |||||
| netbe_rx_enable(sc->esc_be); | netbe_rx_enable(sc->esc_be); | ||||
| /* H/w initiated reset */ | /* H/w initiated reset */ | ||||
| e82545_reset(sc, 0); | e82545_reset(sc, 0); | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 149 Lines • ▼ Show 20 Lines | |||||
| done: | done: | ||||
| return (ret); | return (ret); | ||||
| } | } | ||||
| #endif | #endif | ||||
| struct pci_devemu pci_de_e82545 = { | struct pci_devemu pci_de_e82545 = { | ||||
| .pe_emu = "e1000", | .pe_emu = "e1000", | ||||
| .pe_init = e82545_init, | .pe_init = e82545_init, | ||||
| .pe_legacy_config = netbe_legacy_config, | |||||
| .pe_barwrite = e82545_write, | .pe_barwrite = e82545_write, | ||||
| .pe_barread = e82545_read, | .pe_barread = e82545_read, | ||||
| #ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
| .pe_snapshot = e82545_snapshot, | .pe_snapshot = e82545_snapshot, | ||||
| #endif | #endif | ||||
| }; | }; | ||||
| PCI_EMUL_SET(pci_de_e82545); | PCI_EMUL_SET(pci_de_e82545); | ||||