[4/7] net/ixgbe: Run 82599 link status workaround only on affected devices

Message ID 20211203225516.571368-5-stephend@silicom-usa.com (mailing list archive)
State Superseded, archived
Delegated to: Qi Zhang
Headers
Series ixgbe SFP handling fixes |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Stephen Douthit Dec. 3, 2021, 10:55 p.m. UTC
  1ca05831b9b added a check that SDP3 (used as a TX_DISABLE output to the
SFP cage on these cards) is not asserted to avoid incorrectly reporting
link up when the SFP's laser is turned off.

ff8162cb957 limited this workaround to fiber ports

Refactor this so it's:

* Not open coded in ixgbe_dev_link_update_share()
* Runs only on fiber 82599 devices, not all fiber ixgbe devs (which don't
  all use SDP3 as TX_DISABLE)

Fixes: 1ca05831b9b ("net/ixgbe: fix link status")
Fixes: ff8162cb957 ("net/ixgbe: fix link status")
Cc: stable@dpdk.org

Signed-off-by: Stephen Douthit <stephend@silicom-usa.com>
---
 drivers/net/ixgbe/base/ixgbe_82599.c | 41 ++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.c     |  7 -----
 2 files changed, 41 insertions(+), 7 deletions(-)
  

Patch

diff --git a/drivers/net/ixgbe/base/ixgbe_82599.c b/drivers/net/ixgbe/base/ixgbe_82599.c
index 69fd4cd3fb..5786114b0a 100644
--- a/drivers/net/ixgbe/base/ixgbe_82599.c
+++ b/drivers/net/ixgbe/base/ixgbe_82599.c
@@ -28,6 +28,39 @@  STATIC s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
 STATIC s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
 					u8 dev_addr, u8 data);
 
+/**
+ * ixgbe_check_mac_link_82599_fiber - Determine link and speed status
+ *
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: true when link is up
+ * @link_up_wait_to_complete: bool used to wait for link up or not
+ *
+ * Call the generic MAC check_link function, but also take into account the
+ * state of SDP3, which is a GPIO configured as an output driving the TX_DISABLE
+ * pin on the SFP cage.  This prevents reporting a false positive link up in the
+ * case where the link partner is transmitting, but we are not.
+ **/
+STATIC s32 ixgbe_check_mac_link_82599_fiber(struct ixgbe_hw *hw,
+					    ixgbe_link_speed *speed,
+					    bool *link_up,
+					    bool link_up_wait_to_complete)
+{
+	u32 esdp_reg;
+	s32 err;
+
+	DEBUGFUNC("ixgbe_check_mac_link_82599_fiber");
+
+	err = ixgbe_check_mac_link_generic(hw, speed, link_up,
+					   link_up_wait_to_complete);
+
+	esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+	if ((esdp_reg & IXGBE_ESDP_SDP3))
+		*link_up = 0;
+
+	return err;
+}
+
 void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
 {
 	struct ixgbe_mac_info *mac = &hw->mac;
@@ -52,6 +85,14 @@  void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
 		mac->ops.flap_tx_laser = NULL;
 	}
 
+	/*
+	 * For 82599 SFP+ fiber, make sure that SDP3 (TX_DISABLE to SFP cage)
+	 * isn't asserted.  Either by mac->ops.disable_tx_laser(), or possibly
+	 * management firmware
+	 */
+	if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber)
+		mac->ops.check_link = ixgbe_check_mac_link_82599_fiber;
+
 	if (hw->phy.multispeed_fiber) {
 		/* Set up dual speed SFP+ support */
 		mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 66f7af95de..34b7cb2d4e 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -4216,7 +4216,6 @@  ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 	bool link_up;
 	int diag;
 	int wait = 1;
-	u32 esdp_reg;
 
 	memset(&link, 0, sizeof(link));
 	link.link_status = RTE_ETH_LINK_DOWN;
@@ -4250,12 +4249,6 @@  ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
 		return rte_eth_linkstatus_set(dev, &link);
 	}
 
-	if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
-		esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
-		if ((esdp_reg & IXGBE_ESDP_SDP3))
-			link_up = 0;
-	}
-
 	if (link_up == 0) {
 		if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
 			ixgbe_dev_wait_setup_link_complete(dev, 0);