svn commit: r293334 - head/sys/dev/ixgbe

Sean Bruno sbruno at FreeBSD.org
Thu Jan 7 17:02:35 UTC 2016


Author: sbruno
Date: Thu Jan  7 17:02:34 2016
New Revision: 293334
URL: https://svnweb.freebsd.org/changeset/base/293334

Log:
  Fixup SFP module insertion on the 82599 when insertion happens after
  the system is booted and running.
  
  Add PHY detection logic to ixgbe_handle_mod() and add locking to
  ixgbe_handle_msf() as well.
  
  PR:		150251
  Submitted by:	aboyer at averesystems.com
  MFC after:	2 weeks
  Differential Revision:	https://reviews.freebsd.org/D3188

Modified:
  head/sys/dev/ixgbe/if_ix.c

Modified: head/sys/dev/ixgbe/if_ix.c
==============================================================================
--- head/sys/dev/ixgbe/if_ix.c	Thu Jan  7 17:00:35 2016	(r293333)
+++ head/sys/dev/ixgbe/if_ix.c	Thu Jan  7 17:02:34 2016	(r293334)
@@ -2947,12 +2947,7 @@ ixgbe_config_link(struct adapter *adapte
 	sfp = ixgbe_is_sfp(hw);
 
 	if (sfp) { 
-		if (hw->phy.multispeed_fiber) {
-			hw->mac.ops.setup_sfp(hw);
-			ixgbe_enable_tx_laser(hw);
-			taskqueue_enqueue(adapter->tq, &adapter->msf_task);
-		} else
-			taskqueue_enqueue(adapter->tq, &adapter->mod_task);
+		taskqueue_enqueue(adapter->tq, &adapter->mod_task);
 	} else {
 		if (hw->mac.ops.check_link)
 			err = ixgbe_check_link(hw, &adapter->link_speed,
@@ -3758,23 +3753,66 @@ ixgbe_handle_mod(void *context, int pend
 {
 	struct adapter  *adapter = context;
 	struct ixgbe_hw *hw = &adapter->hw;
+	enum ixgbe_phy_type orig_type = hw->phy.type;
 	device_t	dev = adapter->dev;
 	u32 err;
 
+	IXGBE_CORE_LOCK(adapter);
+
+	/* Check to see if the PHY type changed */
+	if (hw->phy.ops.identify) {
+		hw->phy.type = ixgbe_phy_unknown;
+		hw->phy.ops.identify(hw);
+	}
+
+	if (hw->phy.type != orig_type) {
+		device_printf(dev, "Detected phy_type %d\n", hw->phy.type);
+
+		if (hw->phy.type == ixgbe_phy_none) {
+			hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+			goto out;
+		}
+
+		/* Try to do the initialization that was skipped before */
+		if (hw->phy.ops.init)
+			hw->phy.ops.init(hw);
+		if (hw->phy.ops.reset)
+			hw->phy.ops.reset(hw);
+	}
+
 	err = hw->phy.ops.identify_sfp(hw);
 	if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
 		device_printf(dev,
 		    "Unsupported SFP+ module type was detected.\n");
-		return;
+		goto out;
 	}
 
 	err = hw->mac.ops.setup_sfp(hw);
 	if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
 		device_printf(dev,
 		    "Setup failure - unsupported SFP+ module type.\n");
-		return;
+		goto out;
+	}
+	if (hw->phy.multispeed_fiber)
+		taskqueue_enqueue(adapter->tq, &adapter->msf_task);
+out:
+	/* Update media type */
+	switch (hw->mac.ops.get_media_type(hw)) {
+		case ixgbe_media_type_fiber:
+			adapter->optics = IFM_10G_SR;
+			break;
+		case ixgbe_media_type_copper:
+			adapter->optics = IFM_10G_TWINAX;
+			break;
+		case ixgbe_media_type_cx4:
+			adapter->optics = IFM_10G_CX4;
+			break;
+		default:
+			adapter->optics = 0;
+			break;
 	}
-	taskqueue_enqueue(adapter->tq, &adapter->msf_task);
+
+	IXGBE_CORE_UNLOCK(adapter);
 	return;
 }
 
@@ -3790,6 +3828,7 @@ ixgbe_handle_msf(void *context, int pend
 	u32 autoneg;
 	bool negotiate;
 
+	IXGBE_CORE_LOCK(adapter);
 	/* get_supported_phy_layer will call hw->phy.ops.identify_sfp() */
 	adapter->phy_layer = ixgbe_get_supported_physical_layer(hw);
 
@@ -3802,6 +3841,7 @@ ixgbe_handle_msf(void *context, int pend
 	/* Adjust media types shown in ifconfig */
 	ifmedia_removeall(&adapter->media);
 	ixgbe_add_media_types(adapter);
+	IXGBE_CORE_UNLOCK(adapter);
 	return;
 }
 


More information about the svn-src-head mailing list