* [Intel-wired-lan] [PATCH iwl-net] ixgbevf: fix link speed reporting for Hyper-V E610 VFs
@ 2026-07-23 14:51 Tomasz Lichwala
2026-07-30 21:19 ` Tony Nguyen
0 siblings, 1 reply; 3+ messages in thread
From: Tomasz Lichwala @ 2026-07-23 14:51 UTC (permalink / raw)
To: intel-wired-lan; +Cc: Tomasz Lichwala, Marcin Szycik
On Hyper-V E610 VFs the VFLINKS register does not carry valid link speed.
Instead, link status is exposed through emulated PCI config space at offset
0x209 in VFLINKS register format. Read and decode it when checking link on
E610 VFs.
Fixes: 4c44b450c69b ("ixgbevf: Add support for Intel(R) E610 device")
Reviewed-by: Marcin Szycik <marcin.szycik@linux.intel.com>
Signed-off-by: Tomasz Lichwala <tomasz.lichwala@linux.intel.com>
---
drivers/net/ethernet/intel/ixgbevf/vf.c | 81 ++++++++++++++++++++++---
1 file changed, 72 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c
index f6df86d124b9..61ca2cc1ecc6 100644
--- a/drivers/net/ethernet/intel/ixgbevf/vf.c
+++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
@@ -1,14 +1,17 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 1999 - 2024 Intel Corporation. */
+#include <linux/unaligned.h>
+
#include "vf.h"
#include "ixgbevf.h"
-/* On Hyper-V, to reset, we need to read from this offset
- * from the PCI config space. This is the mechanism used on
- * Hyper-V to support PF/VF communication.
+/* On Hyper-V the PF/VF communication is through emulated PCI config
+ * space. The reset and link status are exposed at the offsets below.
*/
-#define IXGBE_HV_RESET_OFFSET 0x201
+#define IXGBE_HV_RESET_OFFSET 0x201
+#define IXGBE_HV_LINK_STATUS_OFFSET 0x209
+#define IXGBE_HV_LINK_STATUS_SIZE 4
static inline s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,
u32 *retmsg, u16 size)
@@ -901,6 +904,40 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
return ret_val;
}
+/**
+ * ixgbevf_hv_read_links_e610 - read link status from PCI config space
+ * @hw: pointer to hardware structure
+ * @links_reg: pointer to store read value
+ *
+ * On Hyper-V E610 VFs the VFLINKS register does not carry valid link speed.
+ * Instead, link status is exposed through emulated PCI config space at offset
+ * 0x209 in VFLINKS register format.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static s32 ixgbevf_hv_read_links_e610(struct ixgbe_hw *hw, u32 *links_reg)
+{
+ struct ixgbevf_adapter *adapter = hw->back;
+
+#if IS_ENABLED(CONFIG_PCI_MMCONFIG)
+ u8 data[IXGBE_HV_LINK_STATUS_SIZE];
+
+ for (int i = 0; i < IXGBE_HV_LINK_STATUS_SIZE; i++) {
+ int ret = pci_read_config_byte(adapter->pdev,
+ IXGBE_HV_LINK_STATUS_OFFSET + i,
+ &data[i]);
+ if (ret)
+ return pcibios_err_to_errno(ret);
+ }
+
+ *links_reg = get_unaligned_le32(data);
+ return 0;
+#else
+ dev_err_once(&adapter->pdev->dev, "cannot read link status, PCI_MMCONFIG is required for Hyper-V\n");
+ return -EOPNOTSUPP;
+#endif
+}
+
/**
* ixgbevf_hv_check_mac_link_vf - check link
* @hw: pointer to private hardware struct
@@ -909,6 +946,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
* @autoneg_wait_to_complete: unused
*
* Hyper-V variant; there is no mailbox communication.
+ * For E610 VFs, link status is read from emulated PCI config space.
*/
static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
ixgbe_link_speed *speed,
@@ -923,13 +961,32 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
mac->get_link_status = true;
+ /* E610 VFs always read link status from emulated PCI config space
+ * because VFLINKS does not carry valid speed for these devices.
+ * Skip get_link_status caching since PCI config reads are cheap.
+ */
+ if (mac->type == ixgbe_mac_e610_vf) {
+ s32 ret = ixgbevf_hv_read_links_e610(hw, &links_reg);
+
+ if (ret) {
+ *link_up = false;
+ *speed = IXGBE_LINK_SPEED_UNKNOWN;
+ return ret;
+ }
+ goto decode;
+ }
+
if (!mac->get_link_status)
goto out;
- /* if link status is down no point in checking to see if pf is up */
links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
- if (!(links_reg & IXGBE_LINKS_UP))
- goto out;
+
+decode:
+ if (!(links_reg & IXGBE_LINKS_UP)) {
+ *link_up = false;
+ *speed = IXGBE_LINK_SPEED_UNKNOWN;
+ return 0;
+ }
/* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
* before the link status is correct
@@ -941,8 +998,11 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
udelay(100);
links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
- if (!(links_reg & IXGBE_LINKS_UP))
- goto out;
+ if (!(links_reg & IXGBE_LINKS_UP)) {
+ *link_up = false;
+ *speed = IXGBE_LINK_SPEED_UNKNOWN;
+ return 0;
+ }
}
}
@@ -956,6 +1016,9 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
case IXGBE_LINKS_SPEED_100_82599:
*speed = IXGBE_LINK_SPEED_100_FULL;
break;
+ default:
+ *speed = IXGBE_LINK_SPEED_UNKNOWN;
+ break;
}
/* if we passed all the tests above then the link is up and we no
--
2.54.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Intel-wired-lan] [PATCH iwl-net] ixgbevf: fix link speed reporting for Hyper-V E610 VFs
2026-07-23 14:51 Tomasz Lichwala
@ 2026-07-30 21:19 ` Tony Nguyen
0 siblings, 0 replies; 3+ messages in thread
From: Tony Nguyen @ 2026-07-30 21:19 UTC (permalink / raw)
To: Tomasz Lichwala, intel-wired-lan; +Cc: Marcin Szycik
On 7/23/2026 7:51 AM, Tomasz Lichwala wrote:
...
> +/**
> + * ixgbevf_hv_read_links_e610 - read link status from PCI config space
> + * @hw: pointer to hardware structure
> + * @links_reg: pointer to store read value
> + *
> + * On Hyper-V E610 VFs the VFLINKS register does not carry valid link speed.
> + * Instead, link status is exposed through emulated PCI config space at offset
> + * 0x209 in VFLINKS register format.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +static s32 ixgbevf_hv_read_links_e610(struct ixgbe_hw *hw, u32 *links_reg)
> +{
> + struct ixgbevf_adapter *adapter = hw->back;
> +
> +#if IS_ENABLED(CONFIG_PCI_MMCONFIG)
> + u8 data[IXGBE_HV_LINK_STATUS_SIZE];
> +
> + for (int i = 0; i < IXGBE_HV_LINK_STATUS_SIZE; i++) {
> + int ret = pci_read_config_byte(adapter->pdev,
> + IXGBE_HV_LINK_STATUS_OFFSET + i,
> + &data[i]);
> + if (ret)
> + return pcibios_err_to_errno(ret);
> + }
> +
> + *links_reg = get_unaligned_le32(data);
> + return 0;
> +#else
> + dev_err_once(&adapter->pdev->dev, "cannot read link status, PCI_MMCONFIG is required for Hyper-V\n");
> + return -EOPNOTSUPP;
> +#endif
> +}
I ran Sashiko locally on this and it reported the following:
Should a failed link read here return a fatal error to check_link, or
report link down and return 0?
When built without CONFIG_PCI_MMCONFIG this returns -EOPNOTSUPP on every
call, and it also returns an error on any persistent
pci_read_config_byte() failure.
> /**
> * ixgbevf_hv_check_mac_link_vf - check link
> * @hw: pointer to private hardware struct
> @@ -909,6 +946,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
> * @autoneg_wait_to_complete: unused
> *
> * Hyper-V variant; there is no mailbox communication.
> + * For E610 VFs, link status is read from emulated PCI config space.
> */
> static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
> ixgbe_link_speed *speed,
> @@ -923,13 +961,32 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
> if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
> mac->get_link_status = true;
>
> + /* E610 VFs always read link status from emulated PCI config space
> + * because VFLINKS does not carry valid speed for these devices.
> + * Skip get_link_status caching since PCI config reads are cheap.
> + */
> + if (mac->type == ixgbe_mac_e610_vf) {
> + s32 ret = ixgbevf_hv_read_links_e610(hw, &links_reg);
> +
> + if (ret) {
> + *link_up = false;
> + *speed = IXGBE_LINK_SPEED_UNKNOWN;
> + return ret;
> + }
> + goto decode;
> + }
> +
Can this cause a repeating reset loop on the degraded configuration?
The non-zero return propagates up through mac.ops.check_link() into
ixgbevf_watchdog_update_link():
err = hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
...
if (err && time_after(jiffies, adapter->last_reset + (10 * HZ))) {
set_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state);
link_up = false;
}
A device reset cannot make CONFIG_PCI_MMCONFIG appear at compile time, nor
fix a persistent config-space read failure, so wouldn't every watchdog
cycle re-arm __IXGBEVF_RESET_REQUESTED roughly every 10 seconds, leaving
the interface permanently down and continuously resetting?
Before this patch the Hyper-V check_link callback always returned 0, so no
reset request was triggered. Would returning 0 with link_up=false and
speed IXGBE_LINK_SPEED_UNKNOWN for the unsupported/degraded case avoid the
loop?
One related note: the dev_err_once() reads as a benign one-time notice,
but the underlying -EOPNOTSUPP is returned on every poll and drives the
repeating reset behavior above.
Thanks,
Tony
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Intel-wired-lan] [PATCH iwl-net] ixgbevf: fix link speed reporting for Hyper-V E610 VFs
[not found] <0de48a53-695a-4ba2-b2f3-8750334fa7a7@linux.intel.com>
@ 2026-08-04 14:53 ` Tomasz Lichwala
0 siblings, 0 replies; 3+ messages in thread
From: Tomasz Lichwala @ 2026-08-04 14:53 UTC (permalink / raw)
To: intel-wired-lan
On 30.07.2026 23:19, Tony Nguyen wrote:
>
>
> On 7/23/2026 7:51 AM, Tomasz Lichwala wrote:
>
> ...
>
>> +/**
>> + * ixgbevf_hv_read_links_e610 - read link status from PCI config space
>> + * @hw: pointer to hardware structure
>> + * @links_reg: pointer to store read value
>> + *
>> + * On Hyper-V E610 VFs the VFLINKS register does not carry valid link speed.
>> + * Instead, link status is exposed through emulated PCI config space at offset
>> + * 0x209 in VFLINKS register format.
>> + *
>> + * Return: 0 on success, negative error code on failure.
>> + */
>> +static s32 ixgbevf_hv_read_links_e610(struct ixgbe_hw *hw, u32 *links_reg)
>> +{
>> + struct ixgbevf_adapter *adapter = hw->back;
>> +
>> +#if IS_ENABLED(CONFIG_PCI_MMCONFIG)
>> + u8 data[IXGBE_HV_LINK_STATUS_SIZE];
>> +
>> + for (int i = 0; i < IXGBE_HV_LINK_STATUS_SIZE; i++) {
>> + int ret = pci_read_config_byte(adapter->pdev,
>> + IXGBE_HV_LINK_STATUS_OFFSET + i,
>> + &data[i]);
>> + if (ret)
>> + return pcibios_err_to_errno(ret);
>> + }
>> +
>> + *links_reg = get_unaligned_le32(data);
>> + return 0;
>> +#else
>> + dev_err_once(&adapter->pdev->dev, "cannot read link status, PCI_MMCONFIG is required for Hyper-V\n");
>> + return -EOPNOTSUPP;
>> +#endif
>> +}
>
> I ran Sashiko locally on this and it reported the following:
> Should a failed link read here return a fatal error to check_link, or
> report link down and return 0?
> When built without CONFIG_PCI_MMCONFIG this returns -EOPNOTSUPP on every
> call, and it also returns an error on any persistent
> pci_read_config_byte() failure.
>
Good catch, you are right. Before this patch the Hyper-V check_link
callback always returned 0, so propagating the error is a regression
in the degraded case.
v2 will return 0 with *link_up = false and *speed =
IXGBE_LINK_SPEED_UNKNOWN on read failure. The dev_err_once() still
logs the root cause for diagnostics.
Thanks,
Tomasz
>> /**
>> * ixgbevf_hv_check_mac_link_vf - check link
>> * @hw: pointer to private hardware struct
>> @@ -909,6 +946,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
>> * @autoneg_wait_to_complete: unused
>> *
>> * Hyper-V variant; there is no mailbox communication.
>> + * For E610 VFs, link status is read from emulated PCI config space.
>> */
>> static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
>> ixgbe_link_speed *speed,
>> @@ -923,13 +961,32 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
>> if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
>> mac->get_link_status = true;
>> + /* E610 VFs always read link status from emulated PCI config space
>> + * because VFLINKS does not carry valid speed for these devices.
>> + * Skip get_link_status caching since PCI config reads are cheap.
>> + */
>> + if (mac->type == ixgbe_mac_e610_vf) {
>> + s32 ret = ixgbevf_hv_read_links_e610(hw, &links_reg);
>> +
>> + if (ret) {
>> + *link_up = false;
>> + *speed = IXGBE_LINK_SPEED_UNKNOWN;
>> + return ret;
>> + }
>> + goto decode;
>> + }
>> +
> Can this cause a repeating reset loop on the degraded configuration?
> The non-zero return propagates up through mac.ops.check_link() into
> ixgbevf_watchdog_update_link():
> err = hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
> ...
> if (err && time_after(jiffies, adapter->last_reset + (10 * HZ))) {
> set_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state);
> link_up = false;
> }
> A device reset cannot make CONFIG_PCI_MMCONFIG appear at compile time, nor
> fix a persistent config-space read failure, so wouldn't every watchdog
> cycle re-arm __IXGBEVF_RESET_REQUESTED roughly every 10 seconds, leaving
> the interface permanently down and continuously resetting?
> Before this patch the Hyper-V check_link callback always returned 0, so no
> reset request was triggered. Would returning 0 with link_up=false and
> speed IXGBE_LINK_SPEED_UNKNOWN for the unsupported/degraded case avoid the
> loop?
> One related note: the dev_err_once() reads as a benign one-time notice,
> but the underlying -EOPNOTSUPP is returned on every poll and drives the
> repeating reset behavior above.
>
> Thanks,
> Tony
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-04 14:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <0de48a53-695a-4ba2-b2f3-8750334fa7a7@linux.intel.com>
2026-08-04 14:53 ` [Intel-wired-lan] [PATCH iwl-net] ixgbevf: fix link speed reporting for Hyper-V E610 VFs Tomasz Lichwala
2026-07-23 14:51 Tomasz Lichwala
2026-07-30 21:19 ` Tony Nguyen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox