1*6f3fbe4eSDmitry Fleytman /* 2*6f3fbe4eSDmitry Fleytman * QEMU INTEL 82574 GbE NIC emulation 3*6f3fbe4eSDmitry Fleytman * 4*6f3fbe4eSDmitry Fleytman * Software developer's manuals: 5*6f3fbe4eSDmitry Fleytman * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf 6*6f3fbe4eSDmitry Fleytman * 7*6f3fbe4eSDmitry Fleytman * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) 8*6f3fbe4eSDmitry Fleytman * Developed by Daynix Computing LTD (http://www.daynix.com) 9*6f3fbe4eSDmitry Fleytman * 10*6f3fbe4eSDmitry Fleytman * Authors: 11*6f3fbe4eSDmitry Fleytman * Dmitry Fleytman <dmitry@daynix.com> 12*6f3fbe4eSDmitry Fleytman * Leonid Bloch <leonid@daynix.com> 13*6f3fbe4eSDmitry Fleytman * Yan Vugenfirer <yan@daynix.com> 14*6f3fbe4eSDmitry Fleytman * 15*6f3fbe4eSDmitry Fleytman * Based on work done by: 16*6f3fbe4eSDmitry Fleytman * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. 17*6f3fbe4eSDmitry Fleytman * Copyright (c) 2008 Qumranet 18*6f3fbe4eSDmitry Fleytman * Based on work done by: 19*6f3fbe4eSDmitry Fleytman * Copyright (c) 2007 Dan Aloni 20*6f3fbe4eSDmitry Fleytman * Copyright (c) 2004 Antony T Curtis 21*6f3fbe4eSDmitry Fleytman * 22*6f3fbe4eSDmitry Fleytman * This library is free software; you can redistribute it and/or 23*6f3fbe4eSDmitry Fleytman * modify it under the terms of the GNU Lesser General Public 24*6f3fbe4eSDmitry Fleytman * License as published by the Free Software Foundation; either 25*6f3fbe4eSDmitry Fleytman * version 2 of the License, or (at your option) any later version. 26*6f3fbe4eSDmitry Fleytman * 27*6f3fbe4eSDmitry Fleytman * This library is distributed in the hope that it will be useful, 28*6f3fbe4eSDmitry Fleytman * but WITHOUT ANY WARRANTY; without even the implied warranty of 29*6f3fbe4eSDmitry Fleytman * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30*6f3fbe4eSDmitry Fleytman * Lesser General Public License for more details. 31*6f3fbe4eSDmitry Fleytman * 32*6f3fbe4eSDmitry Fleytman * You should have received a copy of the GNU Lesser General Public 33*6f3fbe4eSDmitry Fleytman * License along with this library; if not, see <http://www.gnu.org/licenses/>. 34*6f3fbe4eSDmitry Fleytman */ 35*6f3fbe4eSDmitry Fleytman 36*6f3fbe4eSDmitry Fleytman #include "qemu/osdep.h" 37*6f3fbe4eSDmitry Fleytman #include "net/net.h" 38*6f3fbe4eSDmitry Fleytman #include "net/tap.h" 39*6f3fbe4eSDmitry Fleytman #include "qemu/range.h" 40*6f3fbe4eSDmitry Fleytman #include "sysemu/sysemu.h" 41*6f3fbe4eSDmitry Fleytman #include "hw/pci/msi.h" 42*6f3fbe4eSDmitry Fleytman #include "hw/pci/msix.h" 43*6f3fbe4eSDmitry Fleytman 44*6f3fbe4eSDmitry Fleytman #include "hw/net/e1000_regs.h" 45*6f3fbe4eSDmitry Fleytman 46*6f3fbe4eSDmitry Fleytman #include "e1000x_common.h" 47*6f3fbe4eSDmitry Fleytman #include "e1000e_core.h" 48*6f3fbe4eSDmitry Fleytman 49*6f3fbe4eSDmitry Fleytman #include "trace.h" 50*6f3fbe4eSDmitry Fleytman 51*6f3fbe4eSDmitry Fleytman #define TYPE_E1000E "e1000e" 52*6f3fbe4eSDmitry Fleytman #define E1000E(obj) OBJECT_CHECK(E1000EState, (obj), TYPE_E1000E) 53*6f3fbe4eSDmitry Fleytman 54*6f3fbe4eSDmitry Fleytman typedef struct E1000EState { 55*6f3fbe4eSDmitry Fleytman PCIDevice parent_obj; 56*6f3fbe4eSDmitry Fleytman NICState *nic; 57*6f3fbe4eSDmitry Fleytman NICConf conf; 58*6f3fbe4eSDmitry Fleytman 59*6f3fbe4eSDmitry Fleytman MemoryRegion mmio; 60*6f3fbe4eSDmitry Fleytman MemoryRegion flash; 61*6f3fbe4eSDmitry Fleytman MemoryRegion io; 62*6f3fbe4eSDmitry Fleytman MemoryRegion msix; 63*6f3fbe4eSDmitry Fleytman 64*6f3fbe4eSDmitry Fleytman uint32_t ioaddr; 65*6f3fbe4eSDmitry Fleytman 66*6f3fbe4eSDmitry Fleytman uint16_t subsys_ven; 67*6f3fbe4eSDmitry Fleytman uint16_t subsys; 68*6f3fbe4eSDmitry Fleytman 69*6f3fbe4eSDmitry Fleytman uint16_t subsys_ven_used; 70*6f3fbe4eSDmitry Fleytman uint16_t subsys_used; 71*6f3fbe4eSDmitry Fleytman 72*6f3fbe4eSDmitry Fleytman uint32_t intr_state; 73*6f3fbe4eSDmitry Fleytman bool disable_vnet; 74*6f3fbe4eSDmitry Fleytman 75*6f3fbe4eSDmitry Fleytman E1000ECore core; 76*6f3fbe4eSDmitry Fleytman 77*6f3fbe4eSDmitry Fleytman } E1000EState; 78*6f3fbe4eSDmitry Fleytman 79*6f3fbe4eSDmitry Fleytman #define E1000E_MMIO_IDX 0 80*6f3fbe4eSDmitry Fleytman #define E1000E_FLASH_IDX 1 81*6f3fbe4eSDmitry Fleytman #define E1000E_IO_IDX 2 82*6f3fbe4eSDmitry Fleytman #define E1000E_MSIX_IDX 3 83*6f3fbe4eSDmitry Fleytman 84*6f3fbe4eSDmitry Fleytman #define E1000E_MMIO_SIZE (128 * 1024) 85*6f3fbe4eSDmitry Fleytman #define E1000E_FLASH_SIZE (128 * 1024) 86*6f3fbe4eSDmitry Fleytman #define E1000E_IO_SIZE (32) 87*6f3fbe4eSDmitry Fleytman #define E1000E_MSIX_SIZE (16 * 1024) 88*6f3fbe4eSDmitry Fleytman 89*6f3fbe4eSDmitry Fleytman #define E1000E_MSIX_TABLE (0x0000) 90*6f3fbe4eSDmitry Fleytman #define E1000E_MSIX_PBA (0x2000) 91*6f3fbe4eSDmitry Fleytman 92*6f3fbe4eSDmitry Fleytman #define E1000E_USE_MSI BIT(0) 93*6f3fbe4eSDmitry Fleytman #define E1000E_USE_MSIX BIT(1) 94*6f3fbe4eSDmitry Fleytman 95*6f3fbe4eSDmitry Fleytman static uint64_t 96*6f3fbe4eSDmitry Fleytman e1000e_mmio_read(void *opaque, hwaddr addr, unsigned size) 97*6f3fbe4eSDmitry Fleytman { 98*6f3fbe4eSDmitry Fleytman E1000EState *s = opaque; 99*6f3fbe4eSDmitry Fleytman return e1000e_core_read(&s->core, addr, size); 100*6f3fbe4eSDmitry Fleytman } 101*6f3fbe4eSDmitry Fleytman 102*6f3fbe4eSDmitry Fleytman static void 103*6f3fbe4eSDmitry Fleytman e1000e_mmio_write(void *opaque, hwaddr addr, 104*6f3fbe4eSDmitry Fleytman uint64_t val, unsigned size) 105*6f3fbe4eSDmitry Fleytman { 106*6f3fbe4eSDmitry Fleytman E1000EState *s = opaque; 107*6f3fbe4eSDmitry Fleytman e1000e_core_write(&s->core, addr, val, size); 108*6f3fbe4eSDmitry Fleytman } 109*6f3fbe4eSDmitry Fleytman 110*6f3fbe4eSDmitry Fleytman static bool 111*6f3fbe4eSDmitry Fleytman e1000e_io_get_reg_index(E1000EState *s, uint32_t *idx) 112*6f3fbe4eSDmitry Fleytman { 113*6f3fbe4eSDmitry Fleytman if (s->ioaddr < 0x1FFFF) { 114*6f3fbe4eSDmitry Fleytman *idx = s->ioaddr; 115*6f3fbe4eSDmitry Fleytman return true; 116*6f3fbe4eSDmitry Fleytman } 117*6f3fbe4eSDmitry Fleytman 118*6f3fbe4eSDmitry Fleytman if (s->ioaddr < 0x7FFFF) { 119*6f3fbe4eSDmitry Fleytman trace_e1000e_wrn_io_addr_undefined(s->ioaddr); 120*6f3fbe4eSDmitry Fleytman return false; 121*6f3fbe4eSDmitry Fleytman } 122*6f3fbe4eSDmitry Fleytman 123*6f3fbe4eSDmitry Fleytman if (s->ioaddr < 0xFFFFF) { 124*6f3fbe4eSDmitry Fleytman trace_e1000e_wrn_io_addr_flash(s->ioaddr); 125*6f3fbe4eSDmitry Fleytman return false; 126*6f3fbe4eSDmitry Fleytman } 127*6f3fbe4eSDmitry Fleytman 128*6f3fbe4eSDmitry Fleytman trace_e1000e_wrn_io_addr_unknown(s->ioaddr); 129*6f3fbe4eSDmitry Fleytman return false; 130*6f3fbe4eSDmitry Fleytman } 131*6f3fbe4eSDmitry Fleytman 132*6f3fbe4eSDmitry Fleytman static uint64_t 133*6f3fbe4eSDmitry Fleytman e1000e_io_read(void *opaque, hwaddr addr, unsigned size) 134*6f3fbe4eSDmitry Fleytman { 135*6f3fbe4eSDmitry Fleytman E1000EState *s = opaque; 136*6f3fbe4eSDmitry Fleytman uint32_t idx; 137*6f3fbe4eSDmitry Fleytman uint64_t val; 138*6f3fbe4eSDmitry Fleytman 139*6f3fbe4eSDmitry Fleytman switch (addr) { 140*6f3fbe4eSDmitry Fleytman case E1000_IOADDR: 141*6f3fbe4eSDmitry Fleytman trace_e1000e_io_read_addr(s->ioaddr); 142*6f3fbe4eSDmitry Fleytman return s->ioaddr; 143*6f3fbe4eSDmitry Fleytman case E1000_IODATA: 144*6f3fbe4eSDmitry Fleytman if (e1000e_io_get_reg_index(s, &idx)) { 145*6f3fbe4eSDmitry Fleytman val = e1000e_core_read(&s->core, idx, sizeof(val)); 146*6f3fbe4eSDmitry Fleytman trace_e1000e_io_read_data(idx, val); 147*6f3fbe4eSDmitry Fleytman return val; 148*6f3fbe4eSDmitry Fleytman } 149*6f3fbe4eSDmitry Fleytman return 0; 150*6f3fbe4eSDmitry Fleytman default: 151*6f3fbe4eSDmitry Fleytman trace_e1000e_wrn_io_read_unknown(addr); 152*6f3fbe4eSDmitry Fleytman return 0; 153*6f3fbe4eSDmitry Fleytman } 154*6f3fbe4eSDmitry Fleytman } 155*6f3fbe4eSDmitry Fleytman 156*6f3fbe4eSDmitry Fleytman static void 157*6f3fbe4eSDmitry Fleytman e1000e_io_write(void *opaque, hwaddr addr, 158*6f3fbe4eSDmitry Fleytman uint64_t val, unsigned size) 159*6f3fbe4eSDmitry Fleytman { 160*6f3fbe4eSDmitry Fleytman E1000EState *s = opaque; 161*6f3fbe4eSDmitry Fleytman uint32_t idx; 162*6f3fbe4eSDmitry Fleytman 163*6f3fbe4eSDmitry Fleytman switch (addr) { 164*6f3fbe4eSDmitry Fleytman case E1000_IOADDR: 165*6f3fbe4eSDmitry Fleytman trace_e1000e_io_write_addr(val); 166*6f3fbe4eSDmitry Fleytman s->ioaddr = (uint32_t) val; 167*6f3fbe4eSDmitry Fleytman return; 168*6f3fbe4eSDmitry Fleytman case E1000_IODATA: 169*6f3fbe4eSDmitry Fleytman if (e1000e_io_get_reg_index(s, &idx)) { 170*6f3fbe4eSDmitry Fleytman trace_e1000e_io_write_data(idx, val); 171*6f3fbe4eSDmitry Fleytman e1000e_core_write(&s->core, idx, val, sizeof(val)); 172*6f3fbe4eSDmitry Fleytman } 173*6f3fbe4eSDmitry Fleytman return; 174*6f3fbe4eSDmitry Fleytman default: 175*6f3fbe4eSDmitry Fleytman trace_e1000e_wrn_io_write_unknown(addr); 176*6f3fbe4eSDmitry Fleytman return; 177*6f3fbe4eSDmitry Fleytman } 178*6f3fbe4eSDmitry Fleytman } 179*6f3fbe4eSDmitry Fleytman 180*6f3fbe4eSDmitry Fleytman static const MemoryRegionOps mmio_ops = { 181*6f3fbe4eSDmitry Fleytman .read = e1000e_mmio_read, 182*6f3fbe4eSDmitry Fleytman .write = e1000e_mmio_write, 183*6f3fbe4eSDmitry Fleytman .endianness = DEVICE_LITTLE_ENDIAN, 184*6f3fbe4eSDmitry Fleytman .impl = { 185*6f3fbe4eSDmitry Fleytman .min_access_size = 4, 186*6f3fbe4eSDmitry Fleytman .max_access_size = 4, 187*6f3fbe4eSDmitry Fleytman }, 188*6f3fbe4eSDmitry Fleytman }; 189*6f3fbe4eSDmitry Fleytman 190*6f3fbe4eSDmitry Fleytman static const MemoryRegionOps io_ops = { 191*6f3fbe4eSDmitry Fleytman .read = e1000e_io_read, 192*6f3fbe4eSDmitry Fleytman .write = e1000e_io_write, 193*6f3fbe4eSDmitry Fleytman .endianness = DEVICE_LITTLE_ENDIAN, 194*6f3fbe4eSDmitry Fleytman .impl = { 195*6f3fbe4eSDmitry Fleytman .min_access_size = 4, 196*6f3fbe4eSDmitry Fleytman .max_access_size = 4, 197*6f3fbe4eSDmitry Fleytman }, 198*6f3fbe4eSDmitry Fleytman }; 199*6f3fbe4eSDmitry Fleytman 200*6f3fbe4eSDmitry Fleytman static int 201*6f3fbe4eSDmitry Fleytman e1000e_nc_can_receive(NetClientState *nc) 202*6f3fbe4eSDmitry Fleytman { 203*6f3fbe4eSDmitry Fleytman E1000EState *s = qemu_get_nic_opaque(nc); 204*6f3fbe4eSDmitry Fleytman return e1000e_can_receive(&s->core); 205*6f3fbe4eSDmitry Fleytman } 206*6f3fbe4eSDmitry Fleytman 207*6f3fbe4eSDmitry Fleytman static ssize_t 208*6f3fbe4eSDmitry Fleytman e1000e_nc_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) 209*6f3fbe4eSDmitry Fleytman { 210*6f3fbe4eSDmitry Fleytman E1000EState *s = qemu_get_nic_opaque(nc); 211*6f3fbe4eSDmitry Fleytman return e1000e_receive_iov(&s->core, iov, iovcnt); 212*6f3fbe4eSDmitry Fleytman } 213*6f3fbe4eSDmitry Fleytman 214*6f3fbe4eSDmitry Fleytman static ssize_t 215*6f3fbe4eSDmitry Fleytman e1000e_nc_receive(NetClientState *nc, const uint8_t *buf, size_t size) 216*6f3fbe4eSDmitry Fleytman { 217*6f3fbe4eSDmitry Fleytman E1000EState *s = qemu_get_nic_opaque(nc); 218*6f3fbe4eSDmitry Fleytman return e1000e_receive(&s->core, buf, size); 219*6f3fbe4eSDmitry Fleytman } 220*6f3fbe4eSDmitry Fleytman 221*6f3fbe4eSDmitry Fleytman static void 222*6f3fbe4eSDmitry Fleytman e1000e_set_link_status(NetClientState *nc) 223*6f3fbe4eSDmitry Fleytman { 224*6f3fbe4eSDmitry Fleytman E1000EState *s = qemu_get_nic_opaque(nc); 225*6f3fbe4eSDmitry Fleytman e1000e_core_set_link_status(&s->core); 226*6f3fbe4eSDmitry Fleytman } 227*6f3fbe4eSDmitry Fleytman 228*6f3fbe4eSDmitry Fleytman static NetClientInfo net_e1000e_info = { 229*6f3fbe4eSDmitry Fleytman .type = NET_CLIENT_OPTIONS_KIND_NIC, 230*6f3fbe4eSDmitry Fleytman .size = sizeof(NICState), 231*6f3fbe4eSDmitry Fleytman .can_receive = e1000e_nc_can_receive, 232*6f3fbe4eSDmitry Fleytman .receive = e1000e_nc_receive, 233*6f3fbe4eSDmitry Fleytman .receive_iov = e1000e_nc_receive_iov, 234*6f3fbe4eSDmitry Fleytman .link_status_changed = e1000e_set_link_status, 235*6f3fbe4eSDmitry Fleytman }; 236*6f3fbe4eSDmitry Fleytman 237*6f3fbe4eSDmitry Fleytman /* 238*6f3fbe4eSDmitry Fleytman * EEPROM (NVM) contents documented in Table 36, section 6.1 239*6f3fbe4eSDmitry Fleytman * and generally 6.1.2 Software accessed words. 240*6f3fbe4eSDmitry Fleytman */ 241*6f3fbe4eSDmitry Fleytman static const uint16_t e1000e_eeprom_template[64] = { 242*6f3fbe4eSDmitry Fleytman /* Address | Compat. | ImVer | Compat. */ 243*6f3fbe4eSDmitry Fleytman 0x0000, 0x0000, 0x0000, 0x0420, 0xf746, 0x2010, 0xffff, 0xffff, 244*6f3fbe4eSDmitry Fleytman /* PBA |ICtrl1 | SSID | SVID | DevID |-------|ICtrl2 */ 245*6f3fbe4eSDmitry Fleytman 0x0000, 0x0000, 0x026b, 0x0000, 0x8086, 0x0000, 0x0000, 0x8058, 246*6f3fbe4eSDmitry Fleytman /* NVM words 1,2,3 |-------------------------------|PCI-EID*/ 247*6f3fbe4eSDmitry Fleytman 0x0000, 0x2001, 0x7e7c, 0xffff, 0x1000, 0x00c8, 0x0000, 0x2704, 248*6f3fbe4eSDmitry Fleytman /* PCIe Init. Conf 1,2,3 |PCICtrl|PHY|LD1|-------| RevID | LD0,2 */ 249*6f3fbe4eSDmitry Fleytman 0x6cc9, 0x3150, 0x070e, 0x460b, 0x2d84, 0x0100, 0xf000, 0x0706, 250*6f3fbe4eSDmitry Fleytman /* FLPAR |FLANADD|LAN-PWR|FlVndr |ICtrl3 |APTSMBA|APTRxEP|APTSMBC*/ 251*6f3fbe4eSDmitry Fleytman 0x6000, 0x0080, 0x0f04, 0x7fff, 0x4f01, 0xc600, 0x0000, 0x20ff, 252*6f3fbe4eSDmitry Fleytman /* APTIF | APTMC |APTuCP |LSWFWID|MSWFWID|NC-SIMC|NC-SIC | VPDP */ 253*6f3fbe4eSDmitry Fleytman 0x0028, 0x0003, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, 0xffff, 254*6f3fbe4eSDmitry Fleytman /* SW Section */ 255*6f3fbe4eSDmitry Fleytman 0x0100, 0xc000, 0x121c, 0xc007, 0xffff, 0xffff, 0xffff, 0xffff, 256*6f3fbe4eSDmitry Fleytman /* SW Section |CHKSUM */ 257*6f3fbe4eSDmitry Fleytman 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0120, 0xffff, 0x0000, 258*6f3fbe4eSDmitry Fleytman }; 259*6f3fbe4eSDmitry Fleytman 260*6f3fbe4eSDmitry Fleytman static void e1000e_core_realize(E1000EState *s) 261*6f3fbe4eSDmitry Fleytman { 262*6f3fbe4eSDmitry Fleytman s->core.owner = &s->parent_obj; 263*6f3fbe4eSDmitry Fleytman s->core.owner_nic = s->nic; 264*6f3fbe4eSDmitry Fleytman } 265*6f3fbe4eSDmitry Fleytman 266*6f3fbe4eSDmitry Fleytman static void 267*6f3fbe4eSDmitry Fleytman e1000e_init_msi(E1000EState *s) 268*6f3fbe4eSDmitry Fleytman { 269*6f3fbe4eSDmitry Fleytman int res; 270*6f3fbe4eSDmitry Fleytman 271*6f3fbe4eSDmitry Fleytman res = msi_init(PCI_DEVICE(s), 272*6f3fbe4eSDmitry Fleytman 0xD0, /* MSI capability offset */ 273*6f3fbe4eSDmitry Fleytman 1, /* MAC MSI interrupts */ 274*6f3fbe4eSDmitry Fleytman true, /* 64-bit message addresses supported */ 275*6f3fbe4eSDmitry Fleytman false); /* Per vector mask supported */ 276*6f3fbe4eSDmitry Fleytman 277*6f3fbe4eSDmitry Fleytman if (res > 0) { 278*6f3fbe4eSDmitry Fleytman s->intr_state |= E1000E_USE_MSI; 279*6f3fbe4eSDmitry Fleytman } else { 280*6f3fbe4eSDmitry Fleytman trace_e1000e_msi_init_fail(res); 281*6f3fbe4eSDmitry Fleytman } 282*6f3fbe4eSDmitry Fleytman } 283*6f3fbe4eSDmitry Fleytman 284*6f3fbe4eSDmitry Fleytman static void 285*6f3fbe4eSDmitry Fleytman e1000e_cleanup_msi(E1000EState *s) 286*6f3fbe4eSDmitry Fleytman { 287*6f3fbe4eSDmitry Fleytman if (s->intr_state & E1000E_USE_MSI) { 288*6f3fbe4eSDmitry Fleytman msi_uninit(PCI_DEVICE(s)); 289*6f3fbe4eSDmitry Fleytman } 290*6f3fbe4eSDmitry Fleytman } 291*6f3fbe4eSDmitry Fleytman 292*6f3fbe4eSDmitry Fleytman static void 293*6f3fbe4eSDmitry Fleytman e1000e_unuse_msix_vectors(E1000EState *s, int num_vectors) 294*6f3fbe4eSDmitry Fleytman { 295*6f3fbe4eSDmitry Fleytman int i; 296*6f3fbe4eSDmitry Fleytman for (i = 0; i < num_vectors; i++) { 297*6f3fbe4eSDmitry Fleytman msix_vector_unuse(PCI_DEVICE(s), i); 298*6f3fbe4eSDmitry Fleytman } 299*6f3fbe4eSDmitry Fleytman } 300*6f3fbe4eSDmitry Fleytman 301*6f3fbe4eSDmitry Fleytman static bool 302*6f3fbe4eSDmitry Fleytman e1000e_use_msix_vectors(E1000EState *s, int num_vectors) 303*6f3fbe4eSDmitry Fleytman { 304*6f3fbe4eSDmitry Fleytman int i; 305*6f3fbe4eSDmitry Fleytman for (i = 0; i < num_vectors; i++) { 306*6f3fbe4eSDmitry Fleytman int res = msix_vector_use(PCI_DEVICE(s), i); 307*6f3fbe4eSDmitry Fleytman if (res < 0) { 308*6f3fbe4eSDmitry Fleytman trace_e1000e_msix_use_vector_fail(i, res); 309*6f3fbe4eSDmitry Fleytman e1000e_unuse_msix_vectors(s, i); 310*6f3fbe4eSDmitry Fleytman return false; 311*6f3fbe4eSDmitry Fleytman } 312*6f3fbe4eSDmitry Fleytman } 313*6f3fbe4eSDmitry Fleytman return true; 314*6f3fbe4eSDmitry Fleytman } 315*6f3fbe4eSDmitry Fleytman 316*6f3fbe4eSDmitry Fleytman static void 317*6f3fbe4eSDmitry Fleytman e1000e_init_msix(E1000EState *s) 318*6f3fbe4eSDmitry Fleytman { 319*6f3fbe4eSDmitry Fleytman PCIDevice *d = PCI_DEVICE(s); 320*6f3fbe4eSDmitry Fleytman int res = msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM, 321*6f3fbe4eSDmitry Fleytman &s->msix, 322*6f3fbe4eSDmitry Fleytman E1000E_MSIX_IDX, E1000E_MSIX_TABLE, 323*6f3fbe4eSDmitry Fleytman &s->msix, 324*6f3fbe4eSDmitry Fleytman E1000E_MSIX_IDX, E1000E_MSIX_PBA, 325*6f3fbe4eSDmitry Fleytman 0xA0); 326*6f3fbe4eSDmitry Fleytman 327*6f3fbe4eSDmitry Fleytman if (res < 0) { 328*6f3fbe4eSDmitry Fleytman trace_e1000e_msix_init_fail(res); 329*6f3fbe4eSDmitry Fleytman } else { 330*6f3fbe4eSDmitry Fleytman if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) { 331*6f3fbe4eSDmitry Fleytman msix_uninit(d, &s->msix, &s->msix); 332*6f3fbe4eSDmitry Fleytman } else { 333*6f3fbe4eSDmitry Fleytman s->intr_state |= E1000E_USE_MSIX; 334*6f3fbe4eSDmitry Fleytman } 335*6f3fbe4eSDmitry Fleytman } 336*6f3fbe4eSDmitry Fleytman } 337*6f3fbe4eSDmitry Fleytman 338*6f3fbe4eSDmitry Fleytman static void 339*6f3fbe4eSDmitry Fleytman e1000e_cleanup_msix(E1000EState *s) 340*6f3fbe4eSDmitry Fleytman { 341*6f3fbe4eSDmitry Fleytman if (s->intr_state & E1000E_USE_MSIX) { 342*6f3fbe4eSDmitry Fleytman e1000e_unuse_msix_vectors(s, E1000E_MSIX_VEC_NUM); 343*6f3fbe4eSDmitry Fleytman msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix); 344*6f3fbe4eSDmitry Fleytman } 345*6f3fbe4eSDmitry Fleytman } 346*6f3fbe4eSDmitry Fleytman 347*6f3fbe4eSDmitry Fleytman static void 348*6f3fbe4eSDmitry Fleytman e1000e_init_net_peer(E1000EState *s, PCIDevice *pci_dev, uint8_t *macaddr) 349*6f3fbe4eSDmitry Fleytman { 350*6f3fbe4eSDmitry Fleytman DeviceState *dev = DEVICE(pci_dev); 351*6f3fbe4eSDmitry Fleytman NetClientState *nc; 352*6f3fbe4eSDmitry Fleytman int i; 353*6f3fbe4eSDmitry Fleytman 354*6f3fbe4eSDmitry Fleytman s->nic = qemu_new_nic(&net_e1000e_info, &s->conf, 355*6f3fbe4eSDmitry Fleytman object_get_typename(OBJECT(s)), dev->id, s); 356*6f3fbe4eSDmitry Fleytman 357*6f3fbe4eSDmitry Fleytman s->core.max_queue_num = s->conf.peers.queues - 1; 358*6f3fbe4eSDmitry Fleytman 359*6f3fbe4eSDmitry Fleytman trace_e1000e_mac_set_permanent(MAC_ARG(macaddr)); 360*6f3fbe4eSDmitry Fleytman memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac)); 361*6f3fbe4eSDmitry Fleytman 362*6f3fbe4eSDmitry Fleytman qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr); 363*6f3fbe4eSDmitry Fleytman 364*6f3fbe4eSDmitry Fleytman /* Setup virtio headers */ 365*6f3fbe4eSDmitry Fleytman if (s->disable_vnet) { 366*6f3fbe4eSDmitry Fleytman s->core.has_vnet = false; 367*6f3fbe4eSDmitry Fleytman trace_e1000e_cfg_support_virtio(false); 368*6f3fbe4eSDmitry Fleytman return; 369*6f3fbe4eSDmitry Fleytman } else { 370*6f3fbe4eSDmitry Fleytman s->core.has_vnet = true; 371*6f3fbe4eSDmitry Fleytman } 372*6f3fbe4eSDmitry Fleytman 373*6f3fbe4eSDmitry Fleytman for (i = 0; i < s->conf.peers.queues; i++) { 374*6f3fbe4eSDmitry Fleytman nc = qemu_get_subqueue(s->nic, i); 375*6f3fbe4eSDmitry Fleytman if (!nc->peer || !qemu_has_vnet_hdr(nc->peer)) { 376*6f3fbe4eSDmitry Fleytman s->core.has_vnet = false; 377*6f3fbe4eSDmitry Fleytman trace_e1000e_cfg_support_virtio(false); 378*6f3fbe4eSDmitry Fleytman return; 379*6f3fbe4eSDmitry Fleytman } 380*6f3fbe4eSDmitry Fleytman } 381*6f3fbe4eSDmitry Fleytman 382*6f3fbe4eSDmitry Fleytman trace_e1000e_cfg_support_virtio(true); 383*6f3fbe4eSDmitry Fleytman 384*6f3fbe4eSDmitry Fleytman for (i = 0; i < s->conf.peers.queues; i++) { 385*6f3fbe4eSDmitry Fleytman nc = qemu_get_subqueue(s->nic, i); 386*6f3fbe4eSDmitry Fleytman qemu_set_vnet_hdr_len(nc->peer, sizeof(struct virtio_net_hdr)); 387*6f3fbe4eSDmitry Fleytman qemu_using_vnet_hdr(nc->peer, true); 388*6f3fbe4eSDmitry Fleytman } 389*6f3fbe4eSDmitry Fleytman } 390*6f3fbe4eSDmitry Fleytman 391*6f3fbe4eSDmitry Fleytman static inline uint64_t 392*6f3fbe4eSDmitry Fleytman e1000e_gen_dsn(uint8_t *mac) 393*6f3fbe4eSDmitry Fleytman { 394*6f3fbe4eSDmitry Fleytman return (uint64_t)(mac[5]) | 395*6f3fbe4eSDmitry Fleytman (uint64_t)(mac[4]) << 8 | 396*6f3fbe4eSDmitry Fleytman (uint64_t)(mac[3]) << 16 | 397*6f3fbe4eSDmitry Fleytman (uint64_t)(0x00FF) << 24 | 398*6f3fbe4eSDmitry Fleytman (uint64_t)(0x00FF) << 32 | 399*6f3fbe4eSDmitry Fleytman (uint64_t)(mac[2]) << 40 | 400*6f3fbe4eSDmitry Fleytman (uint64_t)(mac[1]) << 48 | 401*6f3fbe4eSDmitry Fleytman (uint64_t)(mac[0]) << 56; 402*6f3fbe4eSDmitry Fleytman } 403*6f3fbe4eSDmitry Fleytman 404*6f3fbe4eSDmitry Fleytman static int 405*6f3fbe4eSDmitry Fleytman e1000e_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc) 406*6f3fbe4eSDmitry Fleytman { 407*6f3fbe4eSDmitry Fleytman int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset, PCI_PM_SIZEOF); 408*6f3fbe4eSDmitry Fleytman 409*6f3fbe4eSDmitry Fleytman if (ret >= 0) { 410*6f3fbe4eSDmitry Fleytman pci_set_word(pdev->config + offset + PCI_PM_PMC, 411*6f3fbe4eSDmitry Fleytman PCI_PM_CAP_VER_1_1 | 412*6f3fbe4eSDmitry Fleytman pmc); 413*6f3fbe4eSDmitry Fleytman 414*6f3fbe4eSDmitry Fleytman pci_set_word(pdev->wmask + offset + PCI_PM_CTRL, 415*6f3fbe4eSDmitry Fleytman PCI_PM_CTRL_STATE_MASK | 416*6f3fbe4eSDmitry Fleytman PCI_PM_CTRL_PME_ENABLE | 417*6f3fbe4eSDmitry Fleytman PCI_PM_CTRL_DATA_SEL_MASK); 418*6f3fbe4eSDmitry Fleytman 419*6f3fbe4eSDmitry Fleytman pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL, 420*6f3fbe4eSDmitry Fleytman PCI_PM_CTRL_PME_STATUS); 421*6f3fbe4eSDmitry Fleytman } 422*6f3fbe4eSDmitry Fleytman 423*6f3fbe4eSDmitry Fleytman return ret; 424*6f3fbe4eSDmitry Fleytman } 425*6f3fbe4eSDmitry Fleytman 426*6f3fbe4eSDmitry Fleytman static void e1000e_write_config(PCIDevice *pci_dev, uint32_t address, 427*6f3fbe4eSDmitry Fleytman uint32_t val, int len) 428*6f3fbe4eSDmitry Fleytman { 429*6f3fbe4eSDmitry Fleytman E1000EState *s = E1000E(pci_dev); 430*6f3fbe4eSDmitry Fleytman 431*6f3fbe4eSDmitry Fleytman pci_default_write_config(pci_dev, address, val, len); 432*6f3fbe4eSDmitry Fleytman 433*6f3fbe4eSDmitry Fleytman if (range_covers_byte(address, len, PCI_COMMAND) && 434*6f3fbe4eSDmitry Fleytman (pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { 435*6f3fbe4eSDmitry Fleytman qemu_flush_queued_packets(qemu_get_queue(s->nic)); 436*6f3fbe4eSDmitry Fleytman } 437*6f3fbe4eSDmitry Fleytman } 438*6f3fbe4eSDmitry Fleytman 439*6f3fbe4eSDmitry Fleytman static void e1000e_pci_realize(PCIDevice *pci_dev, Error **errp) 440*6f3fbe4eSDmitry Fleytman { 441*6f3fbe4eSDmitry Fleytman static const uint16_t e1000e_pmrb_offset = 0x0C8; 442*6f3fbe4eSDmitry Fleytman static const uint16_t e1000e_pcie_offset = 0x0E0; 443*6f3fbe4eSDmitry Fleytman static const uint16_t e1000e_aer_offset = 0x100; 444*6f3fbe4eSDmitry Fleytman static const uint16_t e1000e_dsn_offset = 0x140; 445*6f3fbe4eSDmitry Fleytman E1000EState *s = E1000E(pci_dev); 446*6f3fbe4eSDmitry Fleytman uint8_t *macaddr; 447*6f3fbe4eSDmitry Fleytman 448*6f3fbe4eSDmitry Fleytman trace_e1000e_cb_pci_realize(); 449*6f3fbe4eSDmitry Fleytman 450*6f3fbe4eSDmitry Fleytman pci_dev->config_write = e1000e_write_config; 451*6f3fbe4eSDmitry Fleytman 452*6f3fbe4eSDmitry Fleytman pci_dev->config[PCI_CACHE_LINE_SIZE] = 0x10; 453*6f3fbe4eSDmitry Fleytman pci_dev->config[PCI_INTERRUPT_PIN] = 1; 454*6f3fbe4eSDmitry Fleytman 455*6f3fbe4eSDmitry Fleytman pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, s->subsys_ven); 456*6f3fbe4eSDmitry Fleytman pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, s->subsys); 457*6f3fbe4eSDmitry Fleytman 458*6f3fbe4eSDmitry Fleytman s->subsys_ven_used = s->subsys_ven; 459*6f3fbe4eSDmitry Fleytman s->subsys_used = s->subsys; 460*6f3fbe4eSDmitry Fleytman 461*6f3fbe4eSDmitry Fleytman /* Define IO/MMIO regions */ 462*6f3fbe4eSDmitry Fleytman memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s, 463*6f3fbe4eSDmitry Fleytman "e1000e-mmio", E1000E_MMIO_SIZE); 464*6f3fbe4eSDmitry Fleytman pci_register_bar(pci_dev, E1000E_MMIO_IDX, 465*6f3fbe4eSDmitry Fleytman PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio); 466*6f3fbe4eSDmitry Fleytman 467*6f3fbe4eSDmitry Fleytman /* 468*6f3fbe4eSDmitry Fleytman * We provide a dummy implementation for the flash BAR 469*6f3fbe4eSDmitry Fleytman * for drivers that may theoretically probe for its presence. 470*6f3fbe4eSDmitry Fleytman */ 471*6f3fbe4eSDmitry Fleytman memory_region_init(&s->flash, OBJECT(s), 472*6f3fbe4eSDmitry Fleytman "e1000e-flash", E1000E_FLASH_SIZE); 473*6f3fbe4eSDmitry Fleytman pci_register_bar(pci_dev, E1000E_FLASH_IDX, 474*6f3fbe4eSDmitry Fleytman PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash); 475*6f3fbe4eSDmitry Fleytman 476*6f3fbe4eSDmitry Fleytman memory_region_init_io(&s->io, OBJECT(s), &io_ops, s, 477*6f3fbe4eSDmitry Fleytman "e1000e-io", E1000E_IO_SIZE); 478*6f3fbe4eSDmitry Fleytman pci_register_bar(pci_dev, E1000E_IO_IDX, 479*6f3fbe4eSDmitry Fleytman PCI_BASE_ADDRESS_SPACE_IO, &s->io); 480*6f3fbe4eSDmitry Fleytman 481*6f3fbe4eSDmitry Fleytman memory_region_init(&s->msix, OBJECT(s), "e1000e-msix", 482*6f3fbe4eSDmitry Fleytman E1000E_MSIX_SIZE); 483*6f3fbe4eSDmitry Fleytman pci_register_bar(pci_dev, E1000E_MSIX_IDX, 484*6f3fbe4eSDmitry Fleytman PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix); 485*6f3fbe4eSDmitry Fleytman 486*6f3fbe4eSDmitry Fleytman /* Create networking backend */ 487*6f3fbe4eSDmitry Fleytman qemu_macaddr_default_if_unset(&s->conf.macaddr); 488*6f3fbe4eSDmitry Fleytman macaddr = s->conf.macaddr.a; 489*6f3fbe4eSDmitry Fleytman 490*6f3fbe4eSDmitry Fleytman e1000e_init_msix(s); 491*6f3fbe4eSDmitry Fleytman 492*6f3fbe4eSDmitry Fleytman if (pcie_endpoint_cap_v1_init(pci_dev, e1000e_pcie_offset) < 0) { 493*6f3fbe4eSDmitry Fleytman hw_error("Failed to initialize PCIe capability"); 494*6f3fbe4eSDmitry Fleytman } 495*6f3fbe4eSDmitry Fleytman 496*6f3fbe4eSDmitry Fleytman e1000e_init_msi(s); 497*6f3fbe4eSDmitry Fleytman 498*6f3fbe4eSDmitry Fleytman if (e1000e_add_pm_capability(pci_dev, e1000e_pmrb_offset, 499*6f3fbe4eSDmitry Fleytman PCI_PM_CAP_DSI) < 0) { 500*6f3fbe4eSDmitry Fleytman hw_error("Failed to initialize PM capability"); 501*6f3fbe4eSDmitry Fleytman } 502*6f3fbe4eSDmitry Fleytman 503*6f3fbe4eSDmitry Fleytman if (pcie_aer_init(pci_dev, e1000e_aer_offset, PCI_ERR_SIZEOF) < 0) { 504*6f3fbe4eSDmitry Fleytman hw_error("Failed to initialize AER capability"); 505*6f3fbe4eSDmitry Fleytman } 506*6f3fbe4eSDmitry Fleytman 507*6f3fbe4eSDmitry Fleytman pcie_dev_ser_num_init(pci_dev, e1000e_dsn_offset, 508*6f3fbe4eSDmitry Fleytman e1000e_gen_dsn(macaddr)); 509*6f3fbe4eSDmitry Fleytman 510*6f3fbe4eSDmitry Fleytman e1000e_init_net_peer(s, pci_dev, macaddr); 511*6f3fbe4eSDmitry Fleytman 512*6f3fbe4eSDmitry Fleytman /* Initialize core */ 513*6f3fbe4eSDmitry Fleytman e1000e_core_realize(s); 514*6f3fbe4eSDmitry Fleytman 515*6f3fbe4eSDmitry Fleytman e1000e_core_pci_realize(&s->core, 516*6f3fbe4eSDmitry Fleytman e1000e_eeprom_template, 517*6f3fbe4eSDmitry Fleytman sizeof(e1000e_eeprom_template), 518*6f3fbe4eSDmitry Fleytman macaddr); 519*6f3fbe4eSDmitry Fleytman } 520*6f3fbe4eSDmitry Fleytman 521*6f3fbe4eSDmitry Fleytman static void e1000e_pci_uninit(PCIDevice *pci_dev) 522*6f3fbe4eSDmitry Fleytman { 523*6f3fbe4eSDmitry Fleytman E1000EState *s = E1000E(pci_dev); 524*6f3fbe4eSDmitry Fleytman 525*6f3fbe4eSDmitry Fleytman trace_e1000e_cb_pci_uninit(); 526*6f3fbe4eSDmitry Fleytman 527*6f3fbe4eSDmitry Fleytman e1000e_core_pci_uninit(&s->core); 528*6f3fbe4eSDmitry Fleytman 529*6f3fbe4eSDmitry Fleytman pcie_aer_exit(pci_dev); 530*6f3fbe4eSDmitry Fleytman pcie_cap_exit(pci_dev); 531*6f3fbe4eSDmitry Fleytman 532*6f3fbe4eSDmitry Fleytman qemu_del_nic(s->nic); 533*6f3fbe4eSDmitry Fleytman 534*6f3fbe4eSDmitry Fleytman e1000e_cleanup_msix(s); 535*6f3fbe4eSDmitry Fleytman e1000e_cleanup_msi(s); 536*6f3fbe4eSDmitry Fleytman } 537*6f3fbe4eSDmitry Fleytman 538*6f3fbe4eSDmitry Fleytman static void e1000e_qdev_reset(DeviceState *dev) 539*6f3fbe4eSDmitry Fleytman { 540*6f3fbe4eSDmitry Fleytman E1000EState *s = E1000E(dev); 541*6f3fbe4eSDmitry Fleytman 542*6f3fbe4eSDmitry Fleytman trace_e1000e_cb_qdev_reset(); 543*6f3fbe4eSDmitry Fleytman 544*6f3fbe4eSDmitry Fleytman e1000e_core_reset(&s->core); 545*6f3fbe4eSDmitry Fleytman } 546*6f3fbe4eSDmitry Fleytman 547*6f3fbe4eSDmitry Fleytman static void e1000e_pre_save(void *opaque) 548*6f3fbe4eSDmitry Fleytman { 549*6f3fbe4eSDmitry Fleytman E1000EState *s = opaque; 550*6f3fbe4eSDmitry Fleytman 551*6f3fbe4eSDmitry Fleytman trace_e1000e_cb_pre_save(); 552*6f3fbe4eSDmitry Fleytman 553*6f3fbe4eSDmitry Fleytman e1000e_core_pre_save(&s->core); 554*6f3fbe4eSDmitry Fleytman } 555*6f3fbe4eSDmitry Fleytman 556*6f3fbe4eSDmitry Fleytman static int e1000e_post_load(void *opaque, int version_id) 557*6f3fbe4eSDmitry Fleytman { 558*6f3fbe4eSDmitry Fleytman E1000EState *s = opaque; 559*6f3fbe4eSDmitry Fleytman 560*6f3fbe4eSDmitry Fleytman trace_e1000e_cb_post_load(); 561*6f3fbe4eSDmitry Fleytman 562*6f3fbe4eSDmitry Fleytman if ((s->subsys != s->subsys_used) || 563*6f3fbe4eSDmitry Fleytman (s->subsys_ven != s->subsys_ven_used)) { 564*6f3fbe4eSDmitry Fleytman fprintf(stderr, 565*6f3fbe4eSDmitry Fleytman "ERROR: Cannot migrate while device properties " 566*6f3fbe4eSDmitry Fleytman "(subsys/subsys_ven) differ"); 567*6f3fbe4eSDmitry Fleytman return -1; 568*6f3fbe4eSDmitry Fleytman } 569*6f3fbe4eSDmitry Fleytman 570*6f3fbe4eSDmitry Fleytman return e1000e_core_post_load(&s->core); 571*6f3fbe4eSDmitry Fleytman } 572*6f3fbe4eSDmitry Fleytman 573*6f3fbe4eSDmitry Fleytman static const VMStateDescription e1000e_vmstate_tx = { 574*6f3fbe4eSDmitry Fleytman .name = "e1000e-tx", 575*6f3fbe4eSDmitry Fleytman .version_id = 1, 576*6f3fbe4eSDmitry Fleytman .minimum_version_id = 1, 577*6f3fbe4eSDmitry Fleytman .fields = (VMStateField[]) { 578*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8(props.sum_needed, struct e1000e_tx), 579*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8(props.ipcss, struct e1000e_tx), 580*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8(props.ipcso, struct e1000e_tx), 581*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16(props.ipcse, struct e1000e_tx), 582*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8(props.tucss, struct e1000e_tx), 583*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8(props.tucso, struct e1000e_tx), 584*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16(props.tucse, struct e1000e_tx), 585*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8(props.hdr_len, struct e1000e_tx), 586*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16(props.mss, struct e1000e_tx), 587*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32(props.paylen, struct e1000e_tx), 588*6f3fbe4eSDmitry Fleytman VMSTATE_INT8(props.ip, struct e1000e_tx), 589*6f3fbe4eSDmitry Fleytman VMSTATE_INT8(props.tcp, struct e1000e_tx), 590*6f3fbe4eSDmitry Fleytman VMSTATE_BOOL(props.tse, struct e1000e_tx), 591*6f3fbe4eSDmitry Fleytman VMSTATE_BOOL(props.cptse, struct e1000e_tx), 592*6f3fbe4eSDmitry Fleytman VMSTATE_BOOL(skip_cp, struct e1000e_tx), 593*6f3fbe4eSDmitry Fleytman VMSTATE_END_OF_LIST() 594*6f3fbe4eSDmitry Fleytman } 595*6f3fbe4eSDmitry Fleytman }; 596*6f3fbe4eSDmitry Fleytman 597*6f3fbe4eSDmitry Fleytman static const VMStateDescription e1000e_vmstate_intr_timer = { 598*6f3fbe4eSDmitry Fleytman .name = "e1000e-intr-timer", 599*6f3fbe4eSDmitry Fleytman .version_id = 1, 600*6f3fbe4eSDmitry Fleytman .minimum_version_id = 1, 601*6f3fbe4eSDmitry Fleytman .fields = (VMStateField[]) { 602*6f3fbe4eSDmitry Fleytman VMSTATE_TIMER_PTR(timer, E1000IntrDelayTimer), 603*6f3fbe4eSDmitry Fleytman VMSTATE_BOOL(running, E1000IntrDelayTimer), 604*6f3fbe4eSDmitry Fleytman VMSTATE_END_OF_LIST() 605*6f3fbe4eSDmitry Fleytman } 606*6f3fbe4eSDmitry Fleytman }; 607*6f3fbe4eSDmitry Fleytman 608*6f3fbe4eSDmitry Fleytman #define VMSTATE_E1000E_INTR_DELAY_TIMER(_f, _s) \ 609*6f3fbe4eSDmitry Fleytman VMSTATE_STRUCT(_f, _s, 0, \ 610*6f3fbe4eSDmitry Fleytman e1000e_vmstate_intr_timer, E1000IntrDelayTimer) 611*6f3fbe4eSDmitry Fleytman 612*6f3fbe4eSDmitry Fleytman #define VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(_f, _s, _num) \ 613*6f3fbe4eSDmitry Fleytman VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \ 614*6f3fbe4eSDmitry Fleytman e1000e_vmstate_intr_timer, E1000IntrDelayTimer) 615*6f3fbe4eSDmitry Fleytman 616*6f3fbe4eSDmitry Fleytman static const VMStateDescription e1000e_vmstate = { 617*6f3fbe4eSDmitry Fleytman .name = "e1000e", 618*6f3fbe4eSDmitry Fleytman .version_id = 1, 619*6f3fbe4eSDmitry Fleytman .minimum_version_id = 1, 620*6f3fbe4eSDmitry Fleytman .pre_save = e1000e_pre_save, 621*6f3fbe4eSDmitry Fleytman .post_load = e1000e_post_load, 622*6f3fbe4eSDmitry Fleytman .fields = (VMStateField[]) { 623*6f3fbe4eSDmitry Fleytman VMSTATE_PCIE_DEVICE(parent_obj, E1000EState), 624*6f3fbe4eSDmitry Fleytman VMSTATE_MSIX(parent_obj, E1000EState), 625*6f3fbe4eSDmitry Fleytman 626*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32(ioaddr, E1000EState), 627*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32(intr_state, E1000EState), 628*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32(core.rxbuf_min_shift, E1000EState), 629*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8(core.rx_desc_len, E1000EState), 630*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32_ARRAY(core.rxbuf_sizes, E1000EState, 631*6f3fbe4eSDmitry Fleytman E1000_PSRCTL_BUFFS_PER_DESC), 632*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32(core.rx_desc_buf_size, E1000EState), 633*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16_ARRAY(core.eeprom, E1000EState, E1000E_EEPROM_SIZE), 634*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16_2DARRAY(core.phy, E1000EState, 635*6f3fbe4eSDmitry Fleytman E1000E_PHY_PAGES, E1000E_PHY_PAGE_SIZE), 636*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32_ARRAY(core.mac, E1000EState, E1000E_MAC_SIZE), 637*6f3fbe4eSDmitry Fleytman VMSTATE_UINT8_ARRAY(core.permanent_mac, E1000EState, ETH_ALEN), 638*6f3fbe4eSDmitry Fleytman 639*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32(core.delayed_causes, E1000EState), 640*6f3fbe4eSDmitry Fleytman 641*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16(subsys, E1000EState), 642*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16(subsys_ven, E1000EState), 643*6f3fbe4eSDmitry Fleytman 644*6f3fbe4eSDmitry Fleytman VMSTATE_E1000E_INTR_DELAY_TIMER(core.rdtr, E1000EState), 645*6f3fbe4eSDmitry Fleytman VMSTATE_E1000E_INTR_DELAY_TIMER(core.radv, E1000EState), 646*6f3fbe4eSDmitry Fleytman VMSTATE_E1000E_INTR_DELAY_TIMER(core.raid, E1000EState), 647*6f3fbe4eSDmitry Fleytman VMSTATE_E1000E_INTR_DELAY_TIMER(core.tadv, E1000EState), 648*6f3fbe4eSDmitry Fleytman VMSTATE_E1000E_INTR_DELAY_TIMER(core.tidv, E1000EState), 649*6f3fbe4eSDmitry Fleytman 650*6f3fbe4eSDmitry Fleytman VMSTATE_E1000E_INTR_DELAY_TIMER(core.itr, E1000EState), 651*6f3fbe4eSDmitry Fleytman VMSTATE_BOOL(core.itr_intr_pending, E1000EState), 652*6f3fbe4eSDmitry Fleytman 653*6f3fbe4eSDmitry Fleytman VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(core.eitr, E1000EState, 654*6f3fbe4eSDmitry Fleytman E1000E_MSIX_VEC_NUM), 655*6f3fbe4eSDmitry Fleytman VMSTATE_BOOL_ARRAY(core.eitr_intr_pending, E1000EState, 656*6f3fbe4eSDmitry Fleytman E1000E_MSIX_VEC_NUM), 657*6f3fbe4eSDmitry Fleytman 658*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32(core.itr_guest_value, E1000EState), 659*6f3fbe4eSDmitry Fleytman VMSTATE_UINT32_ARRAY(core.eitr_guest_value, E1000EState, 660*6f3fbe4eSDmitry Fleytman E1000E_MSIX_VEC_NUM), 661*6f3fbe4eSDmitry Fleytman 662*6f3fbe4eSDmitry Fleytman VMSTATE_UINT16(core.vet, E1000EState), 663*6f3fbe4eSDmitry Fleytman 664*6f3fbe4eSDmitry Fleytman VMSTATE_STRUCT_ARRAY(core.tx, E1000EState, E1000E_NUM_QUEUES, 0, 665*6f3fbe4eSDmitry Fleytman e1000e_vmstate_tx, struct e1000e_tx), 666*6f3fbe4eSDmitry Fleytman VMSTATE_END_OF_LIST() 667*6f3fbe4eSDmitry Fleytman } 668*6f3fbe4eSDmitry Fleytman }; 669*6f3fbe4eSDmitry Fleytman 670*6f3fbe4eSDmitry Fleytman static PropertyInfo e1000e_prop_disable_vnet, 671*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys_ven, 672*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys; 673*6f3fbe4eSDmitry Fleytman 674*6f3fbe4eSDmitry Fleytman static Property e1000e_properties[] = { 675*6f3fbe4eSDmitry Fleytman DEFINE_NIC_PROPERTIES(E1000EState, conf), 676*6f3fbe4eSDmitry Fleytman DEFINE_PROP_DEFAULT("disable_vnet_hdr", E1000EState, disable_vnet, false, 677*6f3fbe4eSDmitry Fleytman e1000e_prop_disable_vnet, bool), 678*6f3fbe4eSDmitry Fleytman DEFINE_PROP_DEFAULT("subsys_ven", E1000EState, subsys_ven, 679*6f3fbe4eSDmitry Fleytman PCI_VENDOR_ID_INTEL, 680*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys_ven, uint16_t), 681*6f3fbe4eSDmitry Fleytman DEFINE_PROP_DEFAULT("subsys", E1000EState, subsys, 0, 682*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys, uint16_t), 683*6f3fbe4eSDmitry Fleytman DEFINE_PROP_END_OF_LIST(), 684*6f3fbe4eSDmitry Fleytman }; 685*6f3fbe4eSDmitry Fleytman 686*6f3fbe4eSDmitry Fleytman static void e1000e_class_init(ObjectClass *class, void *data) 687*6f3fbe4eSDmitry Fleytman { 688*6f3fbe4eSDmitry Fleytman DeviceClass *dc = DEVICE_CLASS(class); 689*6f3fbe4eSDmitry Fleytman PCIDeviceClass *c = PCI_DEVICE_CLASS(class); 690*6f3fbe4eSDmitry Fleytman 691*6f3fbe4eSDmitry Fleytman c->realize = e1000e_pci_realize; 692*6f3fbe4eSDmitry Fleytman c->exit = e1000e_pci_uninit; 693*6f3fbe4eSDmitry Fleytman c->vendor_id = PCI_VENDOR_ID_INTEL; 694*6f3fbe4eSDmitry Fleytman c->device_id = E1000_DEV_ID_82574L; 695*6f3fbe4eSDmitry Fleytman c->revision = 0; 696*6f3fbe4eSDmitry Fleytman c->class_id = PCI_CLASS_NETWORK_ETHERNET; 697*6f3fbe4eSDmitry Fleytman c->is_express = 1; 698*6f3fbe4eSDmitry Fleytman 699*6f3fbe4eSDmitry Fleytman dc->desc = "Intel 82574L GbE Controller"; 700*6f3fbe4eSDmitry Fleytman dc->reset = e1000e_qdev_reset; 701*6f3fbe4eSDmitry Fleytman dc->vmsd = &e1000e_vmstate; 702*6f3fbe4eSDmitry Fleytman dc->props = e1000e_properties; 703*6f3fbe4eSDmitry Fleytman 704*6f3fbe4eSDmitry Fleytman e1000e_prop_disable_vnet = qdev_prop_uint8; 705*6f3fbe4eSDmitry Fleytman e1000e_prop_disable_vnet.description = "Do not use virtio headers, " 706*6f3fbe4eSDmitry Fleytman "perform SW offloads emulation " 707*6f3fbe4eSDmitry Fleytman "instead"; 708*6f3fbe4eSDmitry Fleytman 709*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys_ven = qdev_prop_uint16; 710*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys_ven.description = "PCI device Subsystem Vendor ID"; 711*6f3fbe4eSDmitry Fleytman 712*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys = qdev_prop_uint16; 713*6f3fbe4eSDmitry Fleytman e1000e_prop_subsys.description = "PCI device Subsystem ID"; 714*6f3fbe4eSDmitry Fleytman 715*6f3fbe4eSDmitry Fleytman set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); 716*6f3fbe4eSDmitry Fleytman } 717*6f3fbe4eSDmitry Fleytman 718*6f3fbe4eSDmitry Fleytman static void e1000e_instance_init(Object *obj) 719*6f3fbe4eSDmitry Fleytman { 720*6f3fbe4eSDmitry Fleytman E1000EState *s = E1000E(obj); 721*6f3fbe4eSDmitry Fleytman device_add_bootindex_property(obj, &s->conf.bootindex, 722*6f3fbe4eSDmitry Fleytman "bootindex", "/ethernet-phy@0", 723*6f3fbe4eSDmitry Fleytman DEVICE(obj), NULL); 724*6f3fbe4eSDmitry Fleytman } 725*6f3fbe4eSDmitry Fleytman 726*6f3fbe4eSDmitry Fleytman static const TypeInfo e1000e_info = { 727*6f3fbe4eSDmitry Fleytman .name = TYPE_E1000E, 728*6f3fbe4eSDmitry Fleytman .parent = TYPE_PCI_DEVICE, 729*6f3fbe4eSDmitry Fleytman .instance_size = sizeof(E1000EState), 730*6f3fbe4eSDmitry Fleytman .class_init = e1000e_class_init, 731*6f3fbe4eSDmitry Fleytman .instance_init = e1000e_instance_init, 732*6f3fbe4eSDmitry Fleytman }; 733*6f3fbe4eSDmitry Fleytman 734*6f3fbe4eSDmitry Fleytman static void e1000e_register_types(void) 735*6f3fbe4eSDmitry Fleytman { 736*6f3fbe4eSDmitry Fleytman type_register_static(&e1000e_info); 737*6f3fbe4eSDmitry Fleytman } 738*6f3fbe4eSDmitry Fleytman 739*6f3fbe4eSDmitry Fleytman type_init(e1000e_register_types) 740