From fe73674af1e80ad7375e627563042395a1a746b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 23 Oct 2023 17:45:06 +0200 Subject: [PATCH 1/2] igb: Add a VF reset handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Export the igb_vf_reset() helper routine from the PF model to let the IGBVF model implement its own device reset. Cc: Akihiko Odaki Suggested-by: Sriram Yagnaraman Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Cédric Le Goater Signed-off-by: Jason Wang --- hw/net/igb.c | 6 ++++++ hw/net/igb_common.h | 1 + hw/net/igb_core.c | 6 ++++-- hw/net/igb_core.h | 3 +++ hw/net/igbvf.c | 10 ++++++++++ hw/net/trace-events | 1 + 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/hw/net/igb.c b/hw/net/igb.c index 8ff832acfc..e70a66ee03 100644 --- a/hw/net/igb.c +++ b/hw/net/igb.c @@ -122,6 +122,12 @@ igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) igb_core_write(&s->core, addr, val, size); } +void igb_vf_reset(void *opaque, uint16_t vfn) +{ + IGBState *s = opaque; + igb_core_vf_reset(&s->core, vfn); +} + static bool igb_io_get_reg_index(IGBState *s, uint32_t *idx) { diff --git a/hw/net/igb_common.h b/hw/net/igb_common.h index 5c261ba9d3..b316a5bcfa 100644 --- a/hw/net/igb_common.h +++ b/hw/net/igb_common.h @@ -152,5 +152,6 @@ enum { uint64_t igb_mmio_read(void *opaque, hwaddr addr, unsigned size); void igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); +void igb_vf_reset(void *opaque, uint16_t vfn); #endif diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c index f6a5e2327b..2a7a11aa9e 100644 --- a/hw/net/igb_core.c +++ b/hw/net/igb_core.c @@ -2477,11 +2477,13 @@ static void igb_set_vfmailbox(IGBCore *core, int index, uint32_t val) } } -static void igb_vf_reset(IGBCore *core, uint16_t vfn) +void igb_core_vf_reset(IGBCore *core, uint16_t vfn) { uint16_t qn0 = vfn; uint16_t qn1 = vfn + IGB_NUM_VM_POOLS; + trace_igb_core_vf_reset(vfn); + /* disable Rx and Tx for the VF*/ core->mac[RXDCTL0 + (qn0 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE; core->mac[RXDCTL0 + (qn1 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE; @@ -2560,7 +2562,7 @@ static void igb_set_vtctrl(IGBCore *core, int index, uint32_t val) if (val & E1000_CTRL_RST) { vfn = (index - PVTCTRL0) / 0x40; - igb_vf_reset(core, vfn); + igb_core_vf_reset(core, vfn); } } diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h index 9cbbfd516b..bf8c46f26b 100644 --- a/hw/net/igb_core.h +++ b/hw/net/igb_core.h @@ -130,6 +130,9 @@ igb_core_set_link_status(IGBCore *core); void igb_core_pci_uninit(IGBCore *core); +void +igb_core_vf_reset(IGBCore *core, uint16_t vfn); + bool igb_can_receive(IGBCore *core); diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c index d55e1e8a6a..07343fa14a 100644 --- a/hw/net/igbvf.c +++ b/hw/net/igbvf.c @@ -273,6 +273,13 @@ static void igbvf_pci_realize(PCIDevice *dev, Error **errp) pcie_ari_init(dev, 0x150); } +static void igbvf_qdev_reset_hold(Object *obj) +{ + PCIDevice *vf = PCI_DEVICE(obj); + + igb_vf_reset(pcie_sriov_get_pf(vf), pcie_sriov_vf_number(vf)); +} + static void igbvf_pci_uninit(PCIDevice *dev) { IgbVfState *s = IGBVF(dev); @@ -287,6 +294,7 @@ static void igbvf_class_init(ObjectClass *class, void *data) { DeviceClass *dc = DEVICE_CLASS(class); PCIDeviceClass *c = PCI_DEVICE_CLASS(class); + ResettableClass *rc = RESETTABLE_CLASS(class); c->realize = igbvf_pci_realize; c->exit = igbvf_pci_uninit; @@ -295,6 +303,8 @@ static void igbvf_class_init(ObjectClass *class, void *data) c->revision = 1; c->class_id = PCI_CLASS_NETWORK_ETHERNET; + rc->phases.hold = igbvf_qdev_reset_hold; + dc->desc = "Intel 82576 Virtual Function"; dc->user_creatable = false; diff --git a/hw/net/trace-events b/hw/net/trace-events index 3097742cc0..387e32e153 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -274,6 +274,7 @@ igb_core_mdic_read(uint32_t addr, uint32_t data) "MDIC READ: PHY[%u] = 0x%x" igb_core_mdic_read_unhandled(uint32_t addr) "MDIC READ: PHY[%u] UNHANDLED" igb_core_mdic_write(uint32_t addr, uint32_t data) "MDIC WRITE: PHY[%u] = 0x%x" igb_core_mdic_write_unhandled(uint32_t addr) "MDIC WRITE: PHY[%u] UNHANDLED" +igb_core_vf_reset(uint16_t vfn) "VF%d" igb_link_set_ext_params(bool asd_check, bool speed_select_bypass, bool pfrstd) "Set extended link params: ASD check: %d, Speed select bypass: %d, PF reset done: %d" From d90014fc337ab77f37285b1a30fd4f545056be0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Mon, 23 Oct 2023 17:45:07 +0200 Subject: [PATCH 2/2] igb: Add Function Level Reset to PF and VF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Intel 82576EB GbE Controller say that the Physical and Virtual Functions support Function Level Reset. Add the capability to the PF device model using device property "x-pcie-flr-init" which is "on" by default and "off" for machines <= 8.1 to preserve compatibility. The FLR capability of the VF model is defined according to the FLR property of the PF, this to avoid adding an extra compatibility property. Cc: Sriram Yagnaraman Fixes: 3a977deebe6b ("Intrdocue igb device emulation") Reviewed-by: Akihiko Odaki Tested-by: Akihiko Odaki Signed-off-by: Cédric Le Goater Signed-off-by: Jason Wang --- hw/core/machine.c | 3 ++- hw/net/igb.c | 9 +++++++++ hw/net/igbvf.c | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index 50edaab737..0c17398141 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -35,7 +35,8 @@ GlobalProperty hw_compat_8_1[] = { { TYPE_PCI_BRIDGE, "x-pci-express-writeable-slt-bug", "true" }, { "ramfb", "x-migrate", "off" }, - { "vfio-pci-nohotplug", "x-ramfb-migrate", "off" } + { "vfio-pci-nohotplug", "x-ramfb-migrate", "off" }, + { "igb", "x-pcie-flr-init", "off" }, }; const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1); diff --git a/hw/net/igb.c b/hw/net/igb.c index e70a66ee03..dfb722b695 100644 --- a/hw/net/igb.c +++ b/hw/net/igb.c @@ -78,6 +78,7 @@ struct IGBState { uint32_t ioaddr; IGBCore core; + bool has_flr; }; #define IGB_CAP_SRIOV_OFFSET (0x160) @@ -101,6 +102,9 @@ static void igb_write_config(PCIDevice *dev, uint32_t addr, trace_igb_write_config(addr, val, len); pci_default_write_config(dev, addr, val, len); + if (s->has_flr) { + pcie_cap_flr_write_config(dev, addr, val, len); + } if (range_covers_byte(addr, len, PCI_COMMAND) && (dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { @@ -433,6 +437,10 @@ static void igb_pci_realize(PCIDevice *pci_dev, Error **errp) } /* PCIe extended capabilities (in order) */ + if (s->has_flr) { + pcie_cap_flr_init(pci_dev); + } + if (pcie_aer_init(pci_dev, 1, 0x100, 0x40, errp) < 0) { hw_error("Failed to initialize AER capability"); } @@ -588,6 +596,7 @@ static const VMStateDescription igb_vmstate = { static Property igb_properties[] = { DEFINE_NIC_PROPERTIES(IGBState, conf), + DEFINE_PROP_BOOL("x-pcie-flr-init", IGBState, has_flr, true), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c index 07343fa14a..94a4e885f2 100644 --- a/hw/net/igbvf.c +++ b/hw/net/igbvf.c @@ -204,6 +204,10 @@ static void igbvf_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, { trace_igbvf_write_config(addr, val, len); pci_default_write_config(dev, addr, val, len); + if (object_property_get_bool(OBJECT(pcie_sriov_get_pf(dev)), + "x-pcie-flr-init", &error_abort)) { + pcie_cap_flr_write_config(dev, addr, val, len); + } } static uint64_t igbvf_mmio_read(void *opaque, hwaddr addr, unsigned size) @@ -266,6 +270,11 @@ static void igbvf_pci_realize(PCIDevice *dev, Error **errp) hw_error("Failed to initialize PCIe capability"); } + if (object_property_get_bool(OBJECT(pcie_sriov_get_pf(dev)), + "x-pcie-flr-init", &error_abort)) { + pcie_cap_flr_init(dev); + } + if (pcie_aer_init(dev, 1, 0x100, 0x40, errp) < 0) { hw_error("Failed to initialize AER capability"); }