Module Name:    src
Committed By:   msaitoh
Date:           Mon Aug 17 07:26:55 UTC 2020

Modified Files:
        src/sys/dev/pci/ixgbe: ixgbe.c ixgbe.h

Log Message:
Fix a bug that the driver sometimes missed module insertion.

 The ixgbe_sfp_probe() function was only for 82598 and other chips had no
way to poll SFP+ cage. The ixgbe_handle_mod() already has function to treat
module insertion/removal for all chips, so enqueue the work if the cage
status changed. All of ixgbe chips' SFP+ module interrupt is only on the
inserstion. This change also detect the removal by the timer.


To generate a diff of this commit:
cvs rdiff -u -r1.236 -r1.237 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.67 -r1.68 src/sys/dev/pci/ixgbe/ixgbe.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.236 src/sys/dev/pci/ixgbe/ixgbe.c:1.237
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.236	Mon Aug 17 06:30:25 2020
+++ src/sys/dev/pci/ixgbe/ixgbe.c	Mon Aug 17 07:26:55 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.236 2020/08/17 06:30:25 msaitoh Exp $ */
+/* $NetBSD: ixgbe.c,v 1.237 2020/08/17 07:26:55 msaitoh Exp $ */
 
 /******************************************************************************
 
@@ -257,7 +257,7 @@ static int	ixgbe_sysctl_wol_enable(SYSCT
 static int	ixgbe_sysctl_wufc(SYSCTLFN_PROTO);
 
 /* Support for pluggable optic modules */
-static bool	ixgbe_sfp_probe(struct adapter *);
+static bool	ixgbe_sfp_cage_full(struct ixgbe_hw *);
 
 /* Legacy (single vector) interrupt handler */
 static int	ixgbe_legacy_irq(void *);
@@ -962,15 +962,9 @@ ixgbe_attach(device_t parent, device_t d
 	hw->phy.reset_if_overtemp = TRUE;
 	error = ixgbe_reset_hw(hw);
 	hw->phy.reset_if_overtemp = FALSE;
-	if (error == IXGBE_ERR_SFP_NOT_PRESENT) {
-		/*
-		 * No optics in this port, set up
-		 * so the timer routine will probe
-		 * for later insertion.
-		 */
-		adapter->sfp_probe = TRUE;
+	if (error == IXGBE_ERR_SFP_NOT_PRESENT)
 		error = IXGBE_SUCCESS;
-	} else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+	else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) {
 		aprint_error_dev(dev, "Unsupported SFP+ module detected!\n");
 		unsupported_sfp = true;
 		error = IXGBE_SUCCESS;
@@ -4463,19 +4457,30 @@ static void
 ixgbe_handle_timer(struct work *wk, void *context)
 {
 	struct adapter	*adapter = context;
+	struct ixgbe_hw *hw = &adapter->hw;
 	device_t	dev = adapter->dev;
 	struct ix_queue	*que = adapter->queues;
 	u64		queues = 0;
 	u64		v0, v1, v2, v3, v4, v5, v6, v7;
 	int		hung = 0;
 	int		i;
+	bool		do_probe = false;
 
 	IXGBE_CORE_LOCK(adapter);
 
 	/* Check for pluggable optics */
-	if (adapter->sfp_probe)
-		if (!ixgbe_sfp_probe(adapter))
-			goto out; /* Nothing to do */
+	if (ixgbe_is_sfp(hw)) {
+		bool was_full = hw->phy.sfp_type != ixgbe_sfp_type_not_present;
+		bool is_full = ixgbe_sfp_cage_full(hw);
+
+		/* do probe if cage state changed */
+		if (was_full ^ is_full)
+			do_probe = true;
+	}
+	if (do_probe) {
+		atomic_or_32(&adapter->task_requests, IXGBE_REQUEST_TASK_MOD);
+		ixgbe_schedule_admin_tasklet(adapter);
+	}
 
 	ixgbe_update_link_status(adapter);
 	ixgbe_update_stats_counters(adapter);
@@ -4553,7 +4558,6 @@ ixgbe_handle_timer(struct work *wk, void
 	}
 #endif
 
-out:
 	atomic_store_relaxed(&adapter->timer_pending, 0);
 	IXGBE_CORE_UNLOCK(adapter);
 	callout_reset(&adapter->timer, hz, ixgbe_local_timer, adapter);
@@ -4607,38 +4611,22 @@ ixgbe_handle_recovery_mode_timer(struct 
 } /* ixgbe_handle_recovery_mode_timer */
 
 /************************************************************************
- * ixgbe_sfp_probe
+ * ixgbe_sfp_cage_full
  *
  *   Determine if a port had optics inserted.
  ************************************************************************/
 static bool
-ixgbe_sfp_probe(struct adapter *adapter)
+ixgbe_sfp_cage_full(struct ixgbe_hw *hw)
 {
-	struct ixgbe_hw	*hw = &adapter->hw;
-	device_t	dev = adapter->dev;
-	bool		result = FALSE;
+	uint32_t mask;
 
-	if ((hw->phy.type == ixgbe_phy_nl) &&
-	    (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
-		s32 ret = hw->phy.ops.identify_sfp(hw);
-		if (ret)
-			goto out;
-		ret = hw->phy.ops.reset(hw);
-		adapter->sfp_probe = FALSE;
-		if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-			device_printf(dev,"Unsupported SFP+ module detected!");
-			device_printf(dev,
-			    "Reload driver with supported module.\n");
-			goto out;
-		} else
-			device_printf(dev, "SFP+ module detected!\n");
-		/* We now have supported optics */
-		result = TRUE;
-	}
-out:
+	if (hw->mac.type >= ixgbe_mac_X540)
+		mask = IXGBE_ESDP_SDP0;
+	else
+		mask = IXGBE_ESDP_SDP2;
 
-	return (result);
-} /* ixgbe_sfp_probe */
+	return IXGBE_READ_REG(hw, IXGBE_ESDP) & mask;
+} /* ixgbe_sfp_cage_full */
 
 /************************************************************************
  * ixgbe_handle_mod - Tasklet for SFP module interrupts

Index: src/sys/dev/pci/ixgbe/ixgbe.h
diff -u src/sys/dev/pci/ixgbe/ixgbe.h:1.67 src/sys/dev/pci/ixgbe/ixgbe.h:1.68
--- src/sys/dev/pci/ixgbe/ixgbe.h:1.67	Thu Jun 25 07:53:01 2020
+++ src/sys/dev/pci/ixgbe/ixgbe.h	Mon Aug 17 07:26:55 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.67 2020/06/25 07:53:01 msaitoh Exp $ */
+/* $NetBSD: ixgbe.h,v 1.68 2020/08/17 07:26:55 msaitoh Exp $ */
 
 /******************************************************************************
   SPDX-License-Identifier: BSD-3-Clause
@@ -515,9 +515,6 @@ struct adapter {
 
 	bool			schedule_wqs_ok;
 
-	/* Support for pluggable optics */
-	bool			sfp_probe;
-
 	/* Flow Director */
 	int			fdir_reinit;
 

Reply via email to