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