[dpdk-dev,02/29] ixgbe/base: add sgmii link for X550

Message ID 1462514861-29419-3-git-send-email-beilei.xing@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Bruce Richardson
Headers

Commit Message

Xing, Beilei May 6, 2016, 6:07 a.m. UTC
  It adds sgmii link for X550.

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
---
 drivers/net/ixgbe/base/ixgbe_type.h |   9 +++
 drivers/net/ixgbe/base/ixgbe_x550.c | 131 +++++++++++++++++++++++++++++++++---
 2 files changed, 129 insertions(+), 11 deletions(-)
  

Comments

Ferruh Yigit June 13, 2016, 4:27 p.m. UTC | #1
On 5/6/2016 7:07 AM, Beilei Xing wrote:
> It adds sgmii link for X550.
> 
> Signed-off-by: Beilei Xing <beilei.xing@intel.com>
> ---
>  drivers/net/ixgbe/base/ixgbe_type.h |   9 +++
>  drivers/net/ixgbe/base/ixgbe_x550.c | 131 +++++++++++++++++++++++++++++++++---
>  2 files changed, 129 insertions(+), 11 deletions(-)
> 
...

>  	}
> @@ -512,8 +546,8 @@ s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
>  		link->addr = IXGBE_CS4227;
>  	}
>  	if (hw->mac.type == ixgbe_mac_X550EM_a) {
> -		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
> -		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
> +		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
> +		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
Is it possible that these lines related to the patch 7:
[PATCH 07/29] ixgbe/base: change access method

It looks like first changes ops from ..x550a to ...x550 here and in
patch 7, using ops function instead fixed one.

Also if there is more details about ..x550a to ...x550 change it can be
good to add patch 7 comment.

>  		mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
>  		mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
>  	}
...
  

Patch

diff --git a/drivers/net/ixgbe/base/ixgbe_type.h b/drivers/net/ixgbe/base/ixgbe_type.h
index 4dce2ac..493bd46 100644
--- a/drivers/net/ixgbe/base/ixgbe_type.h
+++ b/drivers/net/ixgbe/base/ixgbe_type.h
@@ -3511,6 +3511,8 @@  enum ixgbe_phy_type {
 	ixgbe_phy_qsfp_intel,
 	ixgbe_phy_qsfp_unknown,
 	ixgbe_phy_sfp_unsupported, /*Enforce bit set with unsupported module*/
+	ixgbe_phy_sgmii,
+	ixgbe_phy_m88,
 	ixgbe_phy_generic
 };
 
@@ -3554,6 +3556,7 @@  enum ixgbe_media_type {
 	ixgbe_media_type_fiber_lco,
 	ixgbe_media_type_copper,
 	ixgbe_media_type_backplane,
+	ixgbe_media_type_sgmii,
 	ixgbe_media_type_cx4,
 	ixgbe_media_type_virtual
 };
@@ -4059,6 +4062,7 @@  struct ixgbe_hw {
 #define IXGBE_KRM_PORT_CAR_GEN_CTRL(P)	((P) ? 0x8010 : 0x4010)
 #define IXGBE_KRM_LINK_CTRL_1(P)	((P) ? 0x820C : 0x420C)
 #define IXGBE_KRM_AN_CNTL_1(P)		((P) ? 0x822C : 0x422C)
+#define IXGBE_KRM_SGMII_CTRL(P)		((P) ? 0x82A0 : 0x42A0)
 #define IXGBE_KRM_DSP_TXFFE_STATE_4(P)	((P) ? 0x8634 : 0x4634)
 #define IXGBE_KRM_DSP_TXFFE_STATE_5(P)	((P) ? 0x8638 : 0x4638)
 #define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P)	((P) ? 0x8B00 : 0x4B00)
@@ -4072,6 +4076,8 @@  struct ixgbe_hw {
 #define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK	(0x7 << 8)
 #define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G	(2 << 8)
 #define IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_10G	(4 << 8)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN		(1 << 12)
+#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN	(1 << 13)
 #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_FEC_REQ		(1 << 14)
 #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_FEC		(1 << 15)
 #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX		(1 << 16)
@@ -4084,6 +4090,9 @@  struct ixgbe_hw {
 #define IXGBE_KRM_AN_CNTL_1_SYM_PAUSE			(1 << 28)
 #define IXGBE_KRM_AN_CNTL_1_ASM_PAUSE			(1 << 29)
 
+#define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D	(1 << 12)
+#define IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D		(1 << 19)
+
 #define IXGBE_KRM_DSP_TXFFE_STATE_C0_EN			(1 << 6)
 #define IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN		(1 << 15)
 #define IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN		(1 << 16)
diff --git a/drivers/net/ixgbe/base/ixgbe_x550.c b/drivers/net/ixgbe/base/ixgbe_x550.c
index 0bbaa55..c1db233 100644
--- a/drivers/net/ixgbe/base/ixgbe_x550.c
+++ b/drivers/net/ixgbe/base/ixgbe_x550.c
@@ -329,6 +329,39 @@  STATIC void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
 }
 
 /**
+ * ixgbe_identify_phy_1g - Get 1g PHY type based on device id
+ * @hw: pointer to hardware structure
+ *
+ * Returns error code
+ */
+static s32 ixgbe_identify_phy_1g(struct ixgbe_hw *hw)
+{
+	u16 phy_id_high;
+	u16 phy_id_low;
+	u32 val = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
+
+	hw->phy.addr = (val >> 3) & 0x1F;
+	val = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
+				   hw->phy.addr, &phy_id_high);
+	if (val || phy_id_high == 0xFFFF) {
+		hw->phy.type = ixgbe_phy_sgmii;
+		return 0;
+	}
+
+	val = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
+				   hw->phy.addr, &phy_id_low);
+	if (val)
+		return val;
+
+	hw->phy.id = (u32)phy_id_high << 16;
+	hw->phy.id |= phy_id_low & IXGBE_PHY_REVISION_MASK;
+	hw->phy.revision = (u32)phy_id_low & ~IXGBE_PHY_REVISION_MASK;
+	hw->phy.type = ixgbe_phy_m88;
+
+	return 0;
+}
+
+/**
  * ixgbe_identify_phy_x550em - Get PHY type based on device id
  * @hw: pointer to hardware structure
  *
@@ -364,10 +397,11 @@  STATIC s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
 		break;
 	case IXGBE_DEV_ID_X550EM_X_1G_T:
 	case IXGBE_DEV_ID_X550EM_X_10G_T:
-	case IXGBE_DEV_ID_X550EM_A_1G_T:
-	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
 	case IXGBE_DEV_ID_X550EM_A_10G_T:
 		return ixgbe_identify_phy_generic(hw);
+	case IXGBE_DEV_ID_X550EM_A_1G_T:
+	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
+		return ixgbe_identify_phy_1g(hw);
 	default:
 		break;
 	}
@@ -512,8 +546,8 @@  s32 ixgbe_init_ops_X550EM(struct ixgbe_hw *hw)
 		link->addr = IXGBE_CS4227;
 	}
 	if (hw->mac.type == ixgbe_mac_X550EM_a) {
-		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a;
-		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a;
+		mac->ops.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550;
+		mac->ops.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550;
 		mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X550a;
 		mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X550a;
 	}
@@ -1286,11 +1320,14 @@  enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
 		break;
 	case IXGBE_DEV_ID_X550EM_X_1G_T:
 	case IXGBE_DEV_ID_X550EM_X_10G_T:
-	case IXGBE_DEV_ID_X550EM_A_1G_T:
-	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
 	case IXGBE_DEV_ID_X550EM_A_10G_T:
 		media_type = ixgbe_media_type_copper;
 		break;
+	case IXGBE_DEV_ID_X550EM_A_1G_T:
+	case IXGBE_DEV_ID_X550EM_A_1G_T_L:
+		media_type = ixgbe_media_type_sgmii;
+		hw->phy.type = ixgbe_phy_sgmii;
+		break;
 	default:
 		media_type = ixgbe_media_type_unknown;
 		break;
@@ -1382,6 +1419,57 @@  s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
 }
 
 /**
+ * ixgbe_setup_sgmii - Set up link for sgmii
+ * @hw: pointer to hardware structure
+ */
+static s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
+			     bool autoneg_wait_to_complete)
+{
+	struct ixgbe_mac_info *mac = &hw->mac;
+	u32 lval, sval;
+	s32 rc;
+	UNREFERENCED_2PARAMETER(speed, autoneg_wait_to_complete);
+
+	rc = mac->ops.read_iosf_sb_reg(hw,
+				       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+				       IXGBE_SB_IOSF_TARGET_KR_PHY, &lval);
+	if (rc)
+		return rc;
+
+	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE;
+	lval &= ~IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_MASK;
+	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_SGMII_EN;
+	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CLAUSE_37_EN;
+	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_FORCE_SPEED_1G;
+	rc = mac->ops.write_iosf_sb_reg(hw,
+					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
+	if (rc)
+		return rc;
+
+	rc = mac->ops.read_iosf_sb_reg(hw,
+				       IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
+				       IXGBE_SB_IOSF_TARGET_KR_PHY, &sval);
+	if (rc)
+		return rc;
+
+	sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_10_D;
+	sval |= IXGBE_KRM_SGMII_CTRL_MAC_TAR_FORCE_100_D;
+	rc = mac->ops.write_iosf_sb_reg(hw,
+					IXGBE_KRM_SGMII_CTRL(hw->bus.lan_id),
+					IXGBE_SB_IOSF_TARGET_KR_PHY, sval);
+	if (rc)
+		return rc;
+
+	lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
+	rc = mac->ops.write_iosf_sb_reg(hw,
+					IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+					IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
+
+	return rc;
+}
+
+/**
  *  ixgbe_init_mac_link_ops_X550em - init mac link function pointers
  *  @hw: pointer to hardware structure
  */
@@ -1391,8 +1479,8 @@  void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
 
 	DEBUGFUNC("ixgbe_init_mac_link_ops_X550em");
 
-	 switch (hw->mac.ops.get_media_type(hw)) {
-	 case ixgbe_media_type_fiber:
+	switch (hw->mac.ops.get_media_type(hw)) {
+	case ixgbe_media_type_fiber:
 		/* CS4227 does not support autoneg, so disable the laser control
 		 * functions for SFP+ fiber
 		 */
@@ -1408,9 +1496,14 @@  void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
 		mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
 		mac->ops.check_link = ixgbe_check_link_t_X550em;
 		break;
+	case ixgbe_media_type_backplane:
+		break;
+	case ixgbe_media_type_sgmii:
+		mac->ops.setup_link = ixgbe_setup_sgmii;
+		break;
 	default:
 		break;
-	 }
+	}
 }
 
 /**
@@ -1447,8 +1540,19 @@  s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
 		else
 			*speed = IXGBE_LINK_SPEED_10GB_FULL;
 	} else {
-		*speed = IXGBE_LINK_SPEED_10GB_FULL |
-			 IXGBE_LINK_SPEED_1GB_FULL;
+		switch (hw->phy.type) {
+		case ixgbe_phy_m88:
+			*speed = IXGBE_LINK_SPEED_100_FULL |
+				 IXGBE_LINK_SPEED_1GB_FULL;
+			break;
+		case ixgbe_phy_sgmii:
+			*speed = IXGBE_LINK_SPEED_1GB_FULL;
+			break;
+		default:
+			*speed = IXGBE_LINK_SPEED_10GB_FULL |
+				 IXGBE_LINK_SPEED_1GB_FULL;
+			break;
+		}
 		*autoneg = true;
 	}
 
@@ -1742,6 +1846,11 @@  s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
 		phy->ops.handle_lasi = ixgbe_handle_lasi_ext_t_x550em;
 		phy->ops.reset = ixgbe_reset_phy_t_X550em;
 		break;
+	case ixgbe_phy_sgmii:
+		phy->ops.setup_link = NULL;
+		break;
+	case ixgbe_phy_m88:
+		break;
 	default:
 		break;
 	}