[PATCH v2 2/7] net/ixgbe: Add ixgbe_check_sfp_cage() for testing state of PRSNT# signal
From: Stephen Douthit <hidden>
Date: 2021-12-06 22:20:02
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Refactor the SFP check code from ixgbe_check_mac_link_generic into its own
function.
Note that the SFP present status was inverted for the X550EM family of
devices, where SDP0 represents the active low PRSNT# signal from the cage.
Call the new function in ixgbe_identify_module_generic() to short circuit
the I2C polling and greatly speed things up for devices we know are
absent.
Fixes: dd3a93cf5a2 ("net/ixgbe/base: bypass checking link for crosstalk")
Cc: stable@dpdk.org
Signed-off-by: Stephen Douthit <redacted>
---
drivers/net/ixgbe/base/ixgbe_common.c | 60 +++++++++++++++++++--------
drivers/net/ixgbe/base/ixgbe_common.h | 8 ++++
drivers/net/ixgbe/base/ixgbe_phy.c | 8 ++++
3 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ixgbe/base/ixgbe_common.c b/drivers/net/ixgbe/base/ixgbe_common.c
index aa843bd5c4..2764cf7cf1 100644
--- a/drivers/net/ixgbe/base/ixgbe_common.c
+++ b/drivers/net/ixgbe/base/ixgbe_common.c@@ -4124,6 +4124,45 @@ static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw) return true; } +/** + * ixgbe_check_sfp_cage - Find present status of SFP module + * @hw: pointer to hardware structure + * + * Find if a SFP module is present and if this device supports SFPs + **/ +enum ixgbe_sfp_cage_status ixgbe_check_sfp_cage(struct ixgbe_hw *hw) +{ + enum ixgbe_sfp_cage_status status; + + /* If we're not a fiber/fiber_qsfp, no cage to check */ + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + case ixgbe_media_type_fiber_qsfp: + break; + default: + return IXGBE_SFP_CAGE_NOCAGE; + } + + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + status = !!(IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP2); + break; + case ixgbe_mac_X550EM_x: + case ixgbe_mac_X550EM_a: + /* SDP0 is the active low signal PRSNT#, so invert this */ + status = !(IXGBE_READ_REG(hw, IXGBE_ESDP) & + IXGBE_ESDP_SDP0); + break; + default: + /* Don't know how to check this device type yet */ + status = IXGBE_SFP_CAGE_UNKNOWN; + break; + } + + return status; +} + /** * ixgbe_check_mac_link_generic - Determine link and speed status * @hw: pointer to hardware structure
@@ -4145,25 +4184,10 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, * the SFP+ cage is full. */ if (ixgbe_need_crosstalk_fix(hw)) { - u32 sfp_cage_full; - - switch (hw->mac.type) { - case ixgbe_mac_82599EB: - sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & - IXGBE_ESDP_SDP2; - break; - case ixgbe_mac_X550EM_x: - case ixgbe_mac_X550EM_a: - sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & - IXGBE_ESDP_SDP0; - break; - default: - /* sanity check - No SFP+ devices here */ - sfp_cage_full = false; - break; - } + enum ixgbe_sfp_cage_status sfp_cage_status; - if (!sfp_cage_full) { + sfp_cage_status = ixgbe_check_sfp_cage(hw); + if (sfp_cage_status != IXGBE_SFP_CAGE_FULL) { *link_up = false; *speed = IXGBE_LINK_SPEED_UNKNOWN; return IXGBE_SUCCESS;
diff --git a/drivers/net/ixgbe/base/ixgbe_common.h b/drivers/net/ixgbe/base/ixgbe_common.h
index 5bdb484407..30db9a08c4 100644
--- a/drivers/net/ixgbe/base/ixgbe_common.h
+++ b/drivers/net/ixgbe/base/ixgbe_common.h@@ -112,6 +112,14 @@ s32 ixgbe_set_vlvf_generic(struct ixgbe_hw *hw, u32 vlan, u32 vind, s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw); s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan, bool vlvf_bypass); +enum ixgbe_sfp_cage_status { + IXGBE_SFP_CAGE_EMPTY = 0, + IXGBE_SFP_CAGE_FULL, + IXGBE_SFP_CAGE_UNKNOWN = -1, + IXGBE_SFP_CAGE_NOCAGE = -2, +}; +enum ixgbe_sfp_cage_status ixgbe_check_sfp_cage(struct ixgbe_hw *hw); + s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *link_up, bool link_up_wait_to_complete);
diff --git a/drivers/net/ixgbe/base/ixgbe_phy.c b/drivers/net/ixgbe/base/ixgbe_phy.c
index 8d4d9bbfef..d8d51d2c3f 100644
--- a/drivers/net/ixgbe/base/ixgbe_phy.c
+++ b/drivers/net/ixgbe/base/ixgbe_phy.c@@ -1228,9 +1228,17 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) s32 ixgbe_identify_module_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_SFP_NOT_PRESENT; + enum ixgbe_sfp_cage_status sfp_cage_status; DEBUGFUNC("ixgbe_identify_module_generic"); + sfp_cage_status = ixgbe_check_sfp_cage(hw); + if (sfp_cage_status == IXGBE_SFP_CAGE_EMPTY || + sfp_cage_status == IXGBE_SFP_CAGE_NOCAGE) { + hw->phy.sfp_type = ixgbe_sfp_type_not_present; + return status; + } + switch (hw->mac.ops.get_media_type(hw)) { case ixgbe_media_type_fiber: status = ixgbe_identify_sfp_module_generic(hw);
--
2.31.1