[2/7] net/ixgbe: Add ixgbe_check_sfp_cage() for testing state of PRSNT# signal
Checks
Commit Message
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 <stephend@silicom-usa.com>
---
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(-)
@@ -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;
@@ -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);
@@ -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);