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); | ||||