tx) { device_t dev = iflib_get_dev(ctx); struct igc_softc *sc = iflib_get_softc(ctx); int cap; - uint32_t ctl1; + uint32_t ctl1, mask; - if (!igc_is_device_id_i226(&sc->hw)) + if (igc_is_device_id_i225(&sc->hw)) + mask = PCIM_L1PM_CTL1_ASPM_L1_2 | + PCIM_L1PM_CTL1_PCIPM_L1_2; + else if (igc_is_device_id_i226(&sc->hw)) + mask = PCIM_L1PM_CTL1_ASPM_L1_2; + else return; if (pci_find_extcap(dev, PCIZ_L1PM, &cap) != 0) return; ctl1 = pci_read_config(dev, cap + PCIR_L1PM_CTL1, 4); - ctl1 &= ~PCIM_L1PM_CTL1_ASPM_L1_2; + ctl1 &= ~mask; pci_write_config(dev, cap + PCIR_L1PM_CTL1, ctl1, 4); } diff --git a/sys/dev/igc/igc_base.c b/sys/dev/igc/igc_base.c index e3ab9733009f..510f4c132b9a 100644 --- a/sys/dev/igc/igc_base.c +++ b/sys/dev/igc/igc_base.c @@ -185,6 +185,35 @@ void igc_rx_fifo_flush_base(struct igc_hw *hw) IGC_READ_REG(hw, IGC_MPC); } +/** + * igc_is_device_id_i225 - Check whether the device is I225 silicon + * @hw: pointer to the HW structure + * + * I225 and I226 share the same mac.type, so this checks the PCI + * device ID directly to distinguish I225 parts, e.g. for erratum + * workarounds that apply only to that silicon. + * + * I225_BLANK_NVM is absent from the equivalent Linux helper. I220 is + * kept separate because Intel's I225 specification update does not + * identify it as affected. + **/ +bool igc_is_device_id_i225(struct igc_hw *hw) +{ + switch (hw->device_id) { + case IGC_DEV_ID_I225_LM: + case IGC_DEV_ID_I225_V: + case IGC_DEV_ID_I225_K: + case IGC_DEV_ID_I225_I: + case IGC_DEV_ID_I225_K2: + case IGC_DEV_ID_I225_LMVP: + case IGC_DEV_ID_I225_IT: + case IGC_DEV_ID_I225_BLANK_NVM: + return true; + default: + return false; + } +} + /** * igc_is_device_id_i226 - Check whether the device is I226 silicon * @hw: pointer to the HW structure diff --git a/sys/dev/igc/igc_base.h b/sys/dev/igc/igc_base.h index 91cb602f809d..26344330ffed 100644 --- a/sys/dev/igc/igc_base.h +++ b/sys/dev/igc/igc_base.h @@ -13,6 +13,7 @@ void igc_power_down_phy_copper_base(struct igc_hw *hw); extern void igc_rx_fifo_flush_base(struct igc_hw *hw); s32 igc_acquire_phy_base(struct igc_hw *hw); void igc_release_phy_base(struct igc_hw *hw); +bool igc_is_device_id_i225(struct igc_hw *hw); bool igc_is_device_id_i226(struct igc_hw *hw); /* Transmit Descriptor - Advanced */