1 /* 2 * QEMU Intel 82576 SR/IOV Ethernet Controller Emulation 3 * 4 * Datasheet: 5 * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf 6 * 7 * Copyright (c) 2020-2023 Red Hat, Inc. 8 * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) 9 * Developed by Daynix Computing LTD (http://www.daynix.com) 10 * 11 * Authors: 12 * Akihiko Odaki <akihiko.odaki@daynix.com> 13 * Gal Hammmer <gal.hammer@sap.com> 14 * Marcel Apfelbaum <marcel.apfelbaum@gmail.com> 15 * Dmitry Fleytman <dmitry@daynix.com> 16 * Leonid Bloch <leonid@daynix.com> 17 * Yan Vugenfirer <yan@daynix.com> 18 * 19 * Based on work done by: 20 * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. 21 * Copyright (c) 2008 Qumranet 22 * Based on work done by: 23 * Copyright (c) 2007 Dan Aloni 24 * Copyright (c) 2004 Antony T Curtis 25 * 26 * This library is free software; you can redistribute it and/or 27 * modify it under the terms of the GNU Lesser General Public 28 * License as published by the Free Software Foundation; either 29 * version 2.1 of the License, or (at your option) any later version. 30 * 31 * This library is distributed in the hope that it will be useful, 32 * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 34 * Lesser General Public License for more details. 35 * 36 * You should have received a copy of the GNU Lesser General Public 37 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 38 */ 39 40 #include "qemu/osdep.h" 41 #include "hw/hw.h" 42 #include "hw/net/mii.h" 43 #include "hw/pci/pci_device.h" 44 #include "hw/pci/pcie.h" 45 #include "hw/pci/msix.h" 46 #include "net/eth.h" 47 #include "net/net.h" 48 #include "igb_common.h" 49 #include "igb_core.h" 50 #include "trace.h" 51 #include "qapi/error.h" 52 53 #define TYPE_IGBVF "igbvf" 54 OBJECT_DECLARE_SIMPLE_TYPE(IgbVfState, IGBVF) 55 56 #define IGBVF_MMIO_BAR_IDX (0) 57 #define IGBVF_MSIX_BAR_IDX (3) 58 59 #define IGBVF_MMIO_SIZE (16 * 1024) 60 #define IGBVF_MSIX_SIZE (16 * 1024) 61 62 struct IgbVfState { 63 PCIDevice parent_obj; 64 65 MemoryRegion mmio; 66 MemoryRegion msix; 67 }; 68 69 static hwaddr vf_to_pf_addr(hwaddr addr, uint16_t vfn, bool write) 70 { 71 switch (addr) { 72 case E1000_CTRL: 73 case E1000_CTRL_DUP: 74 return E1000_PVTCTRL(vfn); 75 case E1000_EICS: 76 return E1000_PVTEICS(vfn); 77 case E1000_EIMS: 78 return E1000_PVTEIMS(vfn); 79 case E1000_EIMC: 80 return E1000_PVTEIMC(vfn); 81 case E1000_EIAC: 82 return E1000_PVTEIAC(vfn); 83 case E1000_EIAM: 84 return E1000_PVTEIAM(vfn); 85 case E1000_EICR: 86 return E1000_PVTEICR(vfn); 87 case E1000_EITR(0): 88 case E1000_EITR(1): 89 case E1000_EITR(2): 90 return E1000_EITR(22) + (addr - E1000_EITR(0)) - vfn * 0xC; 91 case E1000_IVAR0: 92 return E1000_VTIVAR + vfn * 4; 93 case E1000_IVAR_MISC: 94 return E1000_VTIVAR_MISC + vfn * 4; 95 case 0x0F04: /* PBACL */ 96 return E1000_PBACLR; 97 case 0x0F0C: /* PSRTYPE */ 98 return E1000_PSRTYPE(vfn); 99 case E1000_V2PMAILBOX(0): 100 return E1000_V2PMAILBOX(vfn); 101 case E1000_VMBMEM(0) ... E1000_VMBMEM(0) + 0x3F: 102 return addr + vfn * 0x40; 103 case E1000_RDBAL_A(0): 104 return E1000_RDBAL(vfn); 105 case E1000_RDBAL_A(1): 106 return E1000_RDBAL(vfn + IGB_MAX_VF_FUNCTIONS); 107 case E1000_RDBAH_A(0): 108 return E1000_RDBAH(vfn); 109 case E1000_RDBAH_A(1): 110 return E1000_RDBAH(vfn + IGB_MAX_VF_FUNCTIONS); 111 case E1000_RDLEN_A(0): 112 return E1000_RDLEN(vfn); 113 case E1000_RDLEN_A(1): 114 return E1000_RDLEN(vfn + IGB_MAX_VF_FUNCTIONS); 115 case E1000_SRRCTL_A(0): 116 return E1000_SRRCTL(vfn); 117 case E1000_SRRCTL_A(1): 118 return E1000_SRRCTL(vfn + IGB_MAX_VF_FUNCTIONS); 119 case E1000_RDH_A(0): 120 return E1000_RDH(vfn); 121 case E1000_RDH_A(1): 122 return E1000_RDH(vfn + IGB_MAX_VF_FUNCTIONS); 123 case E1000_RXCTL_A(0): 124 return E1000_RXCTL(vfn); 125 case E1000_RXCTL_A(1): 126 return E1000_RXCTL(vfn + IGB_MAX_VF_FUNCTIONS); 127 case E1000_RDT_A(0): 128 return E1000_RDT(vfn); 129 case E1000_RDT_A(1): 130 return E1000_RDT(vfn + IGB_MAX_VF_FUNCTIONS); 131 case E1000_RXDCTL_A(0): 132 return E1000_RXDCTL(vfn); 133 case E1000_RXDCTL_A(1): 134 return E1000_RXDCTL(vfn + IGB_MAX_VF_FUNCTIONS); 135 case E1000_RQDPC_A(0): 136 return E1000_RQDPC(vfn); 137 case E1000_RQDPC_A(1): 138 return E1000_RQDPC(vfn + IGB_MAX_VF_FUNCTIONS); 139 case E1000_TDBAL_A(0): 140 return E1000_TDBAL(vfn); 141 case E1000_TDBAL_A(1): 142 return E1000_TDBAL(vfn + IGB_MAX_VF_FUNCTIONS); 143 case E1000_TDBAH_A(0): 144 return E1000_TDBAH(vfn); 145 case E1000_TDBAH_A(1): 146 return E1000_TDBAH(vfn + IGB_MAX_VF_FUNCTIONS); 147 case E1000_TDLEN_A(0): 148 return E1000_TDLEN(vfn); 149 case E1000_TDLEN_A(1): 150 return E1000_TDLEN(vfn + IGB_MAX_VF_FUNCTIONS); 151 case E1000_TDH_A(0): 152 return E1000_TDH(vfn); 153 case E1000_TDH_A(1): 154 return E1000_TDH(vfn + IGB_MAX_VF_FUNCTIONS); 155 case E1000_TXCTL_A(0): 156 return E1000_TXCTL(vfn); 157 case E1000_TXCTL_A(1): 158 return E1000_TXCTL(vfn + IGB_MAX_VF_FUNCTIONS); 159 case E1000_TDT_A(0): 160 return E1000_TDT(vfn); 161 case E1000_TDT_A(1): 162 return E1000_TDT(vfn + IGB_MAX_VF_FUNCTIONS); 163 case E1000_TXDCTL_A(0): 164 return E1000_TXDCTL(vfn); 165 case E1000_TXDCTL_A(1): 166 return E1000_TXDCTL(vfn + IGB_MAX_VF_FUNCTIONS); 167 case E1000_TDWBAL_A(0): 168 return E1000_TDWBAL(vfn); 169 case E1000_TDWBAL_A(1): 170 return E1000_TDWBAL(vfn + IGB_MAX_VF_FUNCTIONS); 171 case E1000_TDWBAH_A(0): 172 return E1000_TDWBAH(vfn); 173 case E1000_TDWBAH_A(1): 174 return E1000_TDWBAH(vfn + IGB_MAX_VF_FUNCTIONS); 175 case E1000_VFGPRC: 176 return E1000_PVFGPRC(vfn); 177 case E1000_VFGPTC: 178 return E1000_PVFGPTC(vfn); 179 case E1000_VFGORC: 180 return E1000_PVFGORC(vfn); 181 case E1000_VFGOTC: 182 return E1000_PVFGOTC(vfn); 183 case E1000_VFMPRC: 184 return E1000_PVFMPRC(vfn); 185 case E1000_VFGPRLBC: 186 return E1000_PVFGPRLBC(vfn); 187 case E1000_VFGPTLBC: 188 return E1000_PVFGPTLBC(vfn); 189 case E1000_VFGORLBC: 190 return E1000_PVFGORLBC(vfn); 191 case E1000_VFGOTLBC: 192 return E1000_PVFGOTLBC(vfn); 193 case E1000_STATUS: 194 case E1000_FRTIMER: 195 if (write) { 196 return HWADDR_MAX; 197 } 198 /* fallthrough */ 199 case 0x34E8: /* PBTWAC */ 200 case 0x24E8: /* PBRWAC */ 201 return addr; 202 } 203 204 trace_igbvf_wrn_io_addr_unknown(addr); 205 206 return HWADDR_MAX; 207 } 208 209 static void igbvf_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, 210 int len) 211 { 212 trace_igbvf_write_config(addr, val, len); 213 pci_default_write_config(dev, addr, val, len); 214 } 215 216 static uint64_t igbvf_mmio_read(void *opaque, hwaddr addr, unsigned size) 217 { 218 PCIDevice *vf = PCI_DEVICE(opaque); 219 PCIDevice *pf = pcie_sriov_get_pf(vf); 220 221 addr = vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), false); 222 return addr == HWADDR_MAX ? 0 : igb_mmio_read(pf, addr, size); 223 } 224 225 static void igbvf_mmio_write(void *opaque, hwaddr addr, uint64_t val, 226 unsigned size) 227 { 228 PCIDevice *vf = PCI_DEVICE(opaque); 229 PCIDevice *pf = pcie_sriov_get_pf(vf); 230 231 addr = vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), true); 232 if (addr != HWADDR_MAX) { 233 igb_mmio_write(pf, addr, val, size); 234 } 235 } 236 237 static const MemoryRegionOps mmio_ops = { 238 .read = igbvf_mmio_read, 239 .write = igbvf_mmio_write, 240 .endianness = DEVICE_LITTLE_ENDIAN, 241 .impl = { 242 .min_access_size = 4, 243 .max_access_size = 4, 244 }, 245 }; 246 247 static void igbvf_pci_realize(PCIDevice *dev, Error **errp) 248 { 249 IgbVfState *s = IGBVF(dev); 250 int ret; 251 int i; 252 253 dev->config_write = igbvf_write_config; 254 255 memory_region_init_io(&s->mmio, OBJECT(dev), &mmio_ops, s, "igbvf-mmio", 256 IGBVF_MMIO_SIZE); 257 pcie_sriov_vf_register_bar(dev, IGBVF_MMIO_BAR_IDX, &s->mmio); 258 259 memory_region_init(&s->msix, OBJECT(dev), "igbvf-msix", IGBVF_MSIX_SIZE); 260 pcie_sriov_vf_register_bar(dev, IGBVF_MSIX_BAR_IDX, &s->msix); 261 262 ret = msix_init(dev, IGBVF_MSIX_VEC_NUM, &s->msix, IGBVF_MSIX_BAR_IDX, 0, 263 &s->msix, IGBVF_MSIX_BAR_IDX, 0x2000, 0x70, errp); 264 if (ret) { 265 return; 266 } 267 268 for (i = 0; i < IGBVF_MSIX_VEC_NUM; i++) { 269 msix_vector_use(dev, i); 270 } 271 272 if (pcie_endpoint_cap_init(dev, 0xa0) < 0) { 273 hw_error("Failed to initialize PCIe capability"); 274 } 275 276 if (pcie_aer_init(dev, 1, 0x100, 0x40, errp) < 0) { 277 hw_error("Failed to initialize AER capability"); 278 } 279 280 pcie_ari_init(dev, 0x150, 1); 281 } 282 283 static void igbvf_pci_uninit(PCIDevice *dev) 284 { 285 IgbVfState *s = IGBVF(dev); 286 287 pcie_aer_exit(dev); 288 pcie_cap_exit(dev); 289 msix_unuse_all_vectors(dev); 290 msix_uninit(dev, &s->msix, &s->msix); 291 } 292 293 static void igbvf_class_init(ObjectClass *class, void *data) 294 { 295 DeviceClass *dc = DEVICE_CLASS(class); 296 PCIDeviceClass *c = PCI_DEVICE_CLASS(class); 297 298 c->realize = igbvf_pci_realize; 299 c->exit = igbvf_pci_uninit; 300 c->vendor_id = PCI_VENDOR_ID_INTEL; 301 c->device_id = E1000_DEV_ID_82576_VF; 302 c->revision = 1; 303 c->class_id = PCI_CLASS_NETWORK_ETHERNET; 304 305 dc->desc = "Intel 82576 Virtual Function"; 306 dc->user_creatable = false; 307 308 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); 309 } 310 311 static const TypeInfo igbvf_info = { 312 .name = TYPE_IGBVF, 313 .parent = TYPE_PCI_DEVICE, 314 .instance_size = sizeof(IgbVfState), 315 .class_init = igbvf_class_init, 316 .interfaces = (InterfaceInfo[]) { 317 { INTERFACE_PCIE_DEVICE }, 318 { } 319 }, 320 }; 321 322 static void igb_register_types(void) 323 { 324 type_register_static(&igbvf_info); 325 } 326 327 type_init(igb_register_types) 328