Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_e82545.c
Show All 40 Lines | |||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <net/ethernet.h> | #include <net/ethernet.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/tcp.h> | #include <netinet/tcp.h> | ||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
#include <capsicum_helpers.h> | #include <capsicum_helpers.h> | ||||
#endif | #endif | ||||
#include <machine/vmm_snapshot.h> | |||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <md5.h> | #include <md5.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <sysexits.h> | #include <sysexits.h> | ||||
▲ Show 20 Lines • Show All 2,316 Lines • ▼ Show 20 Lines | e82545_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | ||||
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); | ||||
} | } | ||||
#ifdef BHYVE_SNAPSHOT | |||||
static int | |||||
e82545_snapshot(struct vm_snapshot_meta *meta) | |||||
{ | |||||
int i; | |||||
int ret; | |||||
struct e82545_softc *sc; | |||||
struct pci_devinst *pi; | |||||
uint64_t bitmap_value; | |||||
pi = meta->dev_data; | |||||
sc = pi->pi_arg; | |||||
/* esc_mevp and esc_mevpitr should be reinitiated at init. */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_mac, meta, ret, done); | |||||
/* General */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_CTRL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_FCAL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_FCAH, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_FCT, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_VET, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_FCTTV, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_LEDCTL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_PBA, meta, ret, done); | |||||
/* Interrupt control */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_irq_asserted, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_ICR, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_ITR, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_ICS, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_IMS, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_IMC, meta, ret, done); | |||||
/* | |||||
* Transmit | |||||
* | |||||
* The fields in the unions are in superposition to access certain | |||||
* bytes in the larger uint variables. | |||||
* e.g., ip_config = [ipcss|ipcso|ipcse0|ipcse1] | |||||
*/ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_txctx.lower_setup.ip_config, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_txctx.upper_setup.tcp_config, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_txctx.cmd_and_length, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_txctx.tcp_seg_setup.data, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_tx_enabled, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_tx_active, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TXCW, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TCTL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TIPG, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_AIT, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_tdba, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TDBAL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TDBAH, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TDLEN, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TDH, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TDHr, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TDT, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TIDV, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TXDCTL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_TADV, meta, ret, done); | |||||
/* Has dependency on esc_TDLEN; reoreder of fields from struct. */ | |||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->esc_txdesc, sc->esc_TDLEN, | |||||
true, meta, ret, done); | |||||
/* L2 frame acceptance */ | |||||
for (i = 0; i < nitems(sc->esc_uni); i++) { | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_uni[i].eu_valid, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_uni[i].eu_addrsel, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_uni[i].eu_eth, meta, ret, done); | |||||
} | |||||
SNAPSHOT_BUF_OR_LEAVE(sc->esc_fmcast, sizeof(sc->esc_fmcast), | |||||
meta, ret, done); | |||||
SNAPSHOT_BUF_OR_LEAVE(sc->esc_fvlan, sizeof(sc->esc_fvlan), | |||||
meta, ret, done); | |||||
/* Receive */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_rx_enabled, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_rx_active, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_rx_loopback, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RCTL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_FCRTL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_FCRTH, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_rdba, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RDBAL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RDBAH, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RDLEN, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RDH, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RDT, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RDTR, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RXDCTL, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RADV, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RSRPD, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->esc_RXCSUM, meta, ret, done); | |||||
/* Has dependency on esc_RDLEN; reoreder of fields from struct. */ | |||||
SNAPSHOT_GUEST2HOST_ADDR_OR_LEAVE(sc->esc_rxdesc, sc->esc_TDLEN, | |||||
true, meta, ret, done); | |||||
/* IO Port register access */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->io_addr, meta, ret, done); | |||||
/* Shadow copy of MDIC */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->mdi_control, meta, ret, done); | |||||
/* Shadow copy of EECD */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->eeprom_control, meta, ret, done); | |||||
/* Latest NVM in/out */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->nvm_data, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->nvm_opaddr, meta, ret, done); | |||||
/* Stats */ | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->missed_pkt_count, meta, ret, done); | |||||
SNAPSHOT_BUF_OR_LEAVE(sc->pkt_rx_by_size, sizeof(sc->pkt_rx_by_size), | |||||
meta, ret, done); | |||||
SNAPSHOT_BUF_OR_LEAVE(sc->pkt_tx_by_size, sizeof(sc->pkt_tx_by_size), | |||||
meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->good_pkt_rx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->bcast_pkt_rx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->mcast_pkt_rx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->good_pkt_tx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->bcast_pkt_tx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->mcast_pkt_tx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->oversize_rx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->tso_tx_count, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->good_octets_rx, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->good_octets_tx, meta, ret, done); | |||||
SNAPSHOT_VAR_OR_LEAVE(sc->missed_octets, meta, ret, done); | |||||
if (meta->op == VM_SNAPSHOT_SAVE) | |||||
bitmap_value = sc->nvm_bits; | |||||
SNAPSHOT_VAR_OR_LEAVE(bitmap_value, meta, ret, done); | |||||
if (meta->op == VM_SNAPSHOT_RESTORE) | |||||
sc->nvm_bits = bitmap_value; | |||||
if (meta->op == VM_SNAPSHOT_SAVE) | |||||
bitmap_value = sc->nvm_bits; | |||||
SNAPSHOT_VAR_OR_LEAVE(bitmap_value, meta, ret, done); | |||||
if (meta->op == VM_SNAPSHOT_RESTORE) | |||||
sc->nvm_bits = bitmap_value; | |||||
/* EEPROM data */ | |||||
SNAPSHOT_BUF_OR_LEAVE(sc->eeprom_data, sizeof(sc->eeprom_data), | |||||
meta, ret, done); | |||||
done: | |||||
return (ret); | |||||
} | |||||
#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_barwrite = e82545_write, | .pe_barwrite = e82545_write, | ||||
.pe_barread = e82545_read | .pe_barread = e82545_read, | ||||
#ifdef BHYVE_SNAPSHOT | |||||
.pe_snapshot = e82545_snapshot, | |||||
#endif | |||||
}; | }; | ||||
PCI_EMUL_SET(pci_de_e82545); | PCI_EMUL_SET(pci_de_e82545); | ||||