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 "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 "pci_emul.h" | #include "pci_emul.h" | ||||
#include "mevent.h" | #include "mevent.h" | ||||
#include "net_utils.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 | ||||
#define E82545_DEV_ID_82545EM_COPPER 0x100F | #define E82545_DEV_ID_82545EM_COPPER 0x100F | ||||
#define E82545_SUBDEV_ID 0x1008 | #define E82545_SUBDEV_ID 0x1008 | ||||
#define E82545_REVISION_4 4 | #define E82545_REVISION_4 4 | ||||
▲ Show 20 Lines • Show All 584 Lines • ▼ Show 20 Lines | |||||
if (sc->esc_mevp == NULL) { | if (sc->esc_mevp == NULL) { | ||||
DPRINTF("Could not register mevent %d\n", EVF_READ); | DPRINTF("Could not register mevent %d\n", EVF_READ); | ||||
close(sc->esc_tapfd); | close(sc->esc_tapfd); | ||||
sc->esc_tapfd = -1; | sc->esc_tapfd = -1; | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
e82545_parsemac(char *mac_str, uint8_t *mac_addr) | |||||
{ | |||||
struct ether_addr *ea; | |||||
char *tmpstr; | |||||
char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; | |||||
tmpstr = strsep(&mac_str,"="); | |||||
if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { | |||||
ea = ether_aton(mac_str); | |||||
if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || | |||||
memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { | |||||
fprintf(stderr, "Invalid MAC %s\n", mac_str); | |||||
return (1); | |||||
} else | |||||
memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); | |||||
} | |||||
return (0); | |||||
} | |||||
static int | |||||
e82545_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | e82545_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | ||||
{ | { | ||||
DPRINTF("Loading with options: %s\r\n", opts); | |||||
MD5_CTX mdctx; | |||||
unsigned char digest[16]; | |||||
char nstr[80]; | char nstr[80]; | ||||
struct e82545_softc *sc; | struct e82545_softc *sc; | ||||
char *devname; | char *devname; | ||||
char *vtopts; | char *vtopts; | ||||
int mac_provided; | int mac_provided; | ||||
DPRINTF("Loading with options: %s\r\n", 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 33 Lines | |||||
sc->esc_tapfd = -1; | sc->esc_tapfd = -1; | ||||
if (opts != NULL) { | if (opts != NULL) { | ||||
int err; | int err; | ||||
devname = vtopts = strdup(opts); | devname = vtopts = strdup(opts); | ||||
(void) strsep(&vtopts, ","); | (void) strsep(&vtopts, ","); | ||||
if (vtopts != NULL) { | if (vtopts != NULL) { | ||||
err = e82545_parsemac(vtopts, sc->esc_mac.octet); | err = net_parsemac(vtopts, sc->esc_mac.octet); | ||||
if (err != 0) { | if (err != 0) { | ||||
free(devname); | free(devname); | ||||
return (err); | return (err); | ||||
} | } | ||||
mac_provided = 1; | mac_provided = 1; | ||||
} | } | ||||
if (strncmp(devname, "tap", 3) == 0 || | if (strncmp(devname, "tap", 3) == 0 || | ||||
strncmp(devname, "vmnet", 5) == 0) | strncmp(devname, "vmnet", 5) == 0) | ||||
e82545_open_tap(sc, devname); | e82545_open_tap(sc, devname); | ||||
free(devname); | free(devname); | ||||
} | } | ||||
/* | |||||
* The default MAC address is the standard NetApp OUI of 00-a0-98, | |||||
* followed by an MD5 of the PCI slot/func number and dev name | |||||
*/ | |||||
if (!mac_provided) { | if (!mac_provided) { | ||||
snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, | net_genmac(pi, sc->esc_mac.octet); | ||||
pi->pi_func, vmname); | |||||
MD5Init(&mdctx); | |||||
MD5Update(&mdctx, nstr, strlen(nstr)); | |||||
MD5Final(digest, &mdctx); | |||||
sc->esc_mac.octet[0] = 0x00; | |||||
sc->esc_mac.octet[1] = 0xa0; | |||||
sc->esc_mac.octet[2] = 0x98; | |||||
sc->esc_mac.octet[3] = digest[0]; | |||||
sc->esc_mac.octet[4] = digest[1]; | |||||
sc->esc_mac.octet[5] = digest[2]; | |||||
} | } | ||||
/* H/w initiated reset */ | /* H/w initiated reset */ | ||||
e82545_reset(sc, 0); | e82545_reset(sc, 0); | ||||
return (0); | return (0); | ||||
} | } | ||||
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 | ||||
}; | }; | ||||
PCI_EMUL_SET(pci_de_e82545); | PCI_EMUL_SET(pci_de_e82545); | ||||
Context not available. |