Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci/ixgbe Fix 82598 SFP+ problems.
details: https://anonhg.NetBSD.org/src/rev/1ccb101576fe
branches: trunk
changeset: 943317:1ccb101576fe
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Mon Aug 31 06:20:06 2020 +0000
description:
Fix 82598 SFP+ problems.
On 82598, SFP+'s MOD_ABS isn't connected to the MAC's GPIO pin, so we can't
call ixgbe_sfp_cage_full(). Always issue TASK_MOD from ixgbe_handle_timer()
on 82598.
Fix ixgbe_identify_sfp_module_generic() for ixgbe_phy_nl. In the driver,
hw->phy.type sometimes be compared with ixgbe_phy_nl.
In ixgbe_identify_sfp_module_generic(), hw->phy.type may be overridden with
another value. For ixgbe_phy_nl, some code don't override phy.type but others
were not. Make it consistently keep ixgbe_phy_nl. This change fixes a problem
that ixgbe_is_sfp() change the return value true to false when any SFP+
devices are connected to the cage on 82598 and never recover from it.
Don't schedule MSF(multi speed fiber) task from ixgbe_handle_mod() on 82598.
This task is only for devices which support multi speed fiber and 82598
doesn't support it. Before ixgbe.c rev. 1.237, ixgbe_handle_mod() isn't
called on 82598 because 82598 has no SFP+ module insertion/removal interrupt.
ixgbe.c rev. 1.237 changed to call the function via timer on 82598.
This change fixes a bug that 82598 DA interface's link flaps.
diffstat:
sys/dev/pci/ixgbe/ixgbe.c | 52 +++++++++++++++++++++++++++++++++---------
sys/dev/pci/ixgbe/ixgbe_phy.c | 24 +++++++++++++------
2 files changed, 57 insertions(+), 19 deletions(-)
diffs (165 lines):
diff -r e5eaed8a2478 -r 1ccb101576fe sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Mon Aug 31 05:56:02 2020 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Mon Aug 31 06:20:06 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.248 2020/08/27 04:54:43 msaitoh Exp $ */
+/* $NetBSD: ixgbe.c,v 1.249 2020/08/31 06:20:06 msaitoh Exp $ */
/******************************************************************************
@@ -4506,11 +4506,26 @@
/* Check for pluggable optics */
if (ixgbe_is_sfp(hw)) {
- bool was_full = hw->phy.sfp_type != ixgbe_sfp_type_not_present;
- bool is_full = ixgbe_sfp_cage_full(adapter);
-
- /* do probe if cage state changed */
- if (was_full ^ is_full) {
+ bool sched_mod_task = false;
+
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ /*
+ * On 82598EB, SFP+'s MOD_ABS pin is not connected to
+ * any GPIP(SDP). So just schedule TASK_MOD.
+ */
+ sched_mod_task = true;
+ } else {
+ bool was_full, is_full;
+
+ was_full =
+ hw->phy.sfp_type != ixgbe_sfp_type_not_present;
+ is_full = ixgbe_sfp_cage_full(adapter);
+
+ /* Do probe if cage state changed */
+ if (was_full ^ is_full)
+ sched_mod_task = true;
+ }
+ if (sched_mod_task) {
atomic_or_32(&adapter->task_requests,
IXGBE_REQUEST_TASK_MOD);
ixgbe_schedule_admin_tasklet(adapter);
@@ -4683,8 +4698,12 @@
struct adapter *adapter = context;
struct ixgbe_hw *hw = &adapter->hw;
device_t dev = adapter->dev;
+ enum ixgbe_sfp_type last_sfp_type;
u32 err, cage_full = 0;
-
+ bool last_unsupported_sfp_recovery;
+
+ last_sfp_type = hw->phy.sfp_type;
+ last_unsupported_sfp_recovery = hw->need_unsupported_sfp_recovery;
++adapter->mod_workev.ev_count;
if (adapter->hw.need_crosstalk_fix) {
switch (hw->mac.type) {
@@ -4711,8 +4730,9 @@
err = hw->phy.ops.identify_sfp(hw);
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- device_printf(dev,
- "Unsupported SFP+ module type was detected.\n");
+ if (last_unsupported_sfp_recovery == false)
+ device_printf(dev,
+ "Unsupported SFP+ module type was detected.\n");
goto out;
}
@@ -4726,7 +4746,10 @@
* approach.
*/
ixgbe_init_locked(adapter);
- } else {
+ } else if ((hw->phy.sfp_type != ixgbe_sfp_type_not_present) &&
+ (hw->phy.sfp_type != last_sfp_type)) {
+ /* A module is inserted and changed. */
+
if (hw->mac.type == ixgbe_mac_82598EB)
err = hw->phy.ops.reset(hw);
else {
@@ -4751,7 +4774,14 @@
ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO);
IXGBE_CORE_LOCK(adapter);
- atomic_or_32(&adapter->task_requests, IXGBE_REQUEST_TASK_MSF);
+ /*
+ * Don't shedule MSF event if the chip is 82598. 82598 doesn't support
+ * MSF. At least, calling ixgbe_handle_msf on 82598 DA makes the link
+ * flap because the function call setup_link().
+ */
+ if (hw->mac.type != ixgbe_mac_82598EB)
+ atomic_or_32(&adapter->task_requests, IXGBE_REQUEST_TASK_MSF);
+
/*
* Don't call ixgbe_schedule_admin_tasklet() because we are on
* the workqueue now.
diff -r e5eaed8a2478 -r 1ccb101576fe sys/dev/pci/ixgbe/ixgbe_phy.c
--- a/sys/dev/pci/ixgbe/ixgbe_phy.c Mon Aug 31 05:56:02 2020 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe_phy.c Mon Aug 31 06:20:06 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_phy.c,v 1.21 2020/04/17 02:21:25 msaitoh Exp $ */
+/* $NetBSD: ixgbe_phy.c,v 1.22 2020/08/31 06:20:06 msaitoh Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -1356,7 +1356,8 @@
goto err_read_i2c_eeprom;
if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
- hw->phy.type = ixgbe_phy_sfp_unsupported;
+ if (hw->phy.type != ixgbe_phy_nl)
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
} else {
status = hw->phy.ops.read_i2c_eeprom(hw,
@@ -1529,12 +1530,17 @@
/* Allow any DA cable vendor */
if (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE |
- IXGBE_SFF_DA_ACTIVE_CABLE)) {
+ IXGBE_SFF_DA_ACTIVE_CABLE)) {
+ status = IXGBE_SUCCESS;
+
+ /* Keep phy.type for ixgbe_phy_nl */
+ if (hw->phy.type == ixgbe_phy_nl)
+ goto out;
+
if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
hw->phy.type = ixgbe_phy_sfp_passive_unknown;
else if (cable_tech & IXGBE_SFF_DA_ACTIVE_CABLE)
hw->phy.type = ixgbe_phy_sfp_active_unknown;
- status = IXGBE_SUCCESS;
goto out;
}
@@ -1546,7 +1552,8 @@
hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) {
- hw->phy.type = ixgbe_phy_sfp_unsupported;
+ if (hw->phy.type != ixgbe_phy_nl)
+ hw->phy.type = ixgbe_phy_sfp_unsupported;
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
goto out;
}
@@ -1574,8 +1581,9 @@
status = IXGBE_SUCCESS;
} else {
DEBUGOUT("SFP+ module not supported\n");
- hw->phy.type =
- ixgbe_phy_sfp_unsupported;
+ if (hw->phy.type != ixgbe_phy_nl)
+ hw->phy.type =
+ ixgbe_phy_sfp_unsupported;
status = IXGBE_ERR_SFP_NOT_SUPPORTED;
}
}
@@ -1585,7 +1593,7 @@
}
out:
- if (hw->phy.type == ixgbe_phy_sfp_unsupported)
+ if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
hw->need_unsupported_sfp_recovery = true;
return status;
Home |
Main Index |
Thread Index |
Old Index