net/ixgbe/base: add X550em_a FW ALEF support
authorXiao Wang <xiao.w.wang@intel.com>
Sun, 25 Sep 2016 09:00:10 +0000 (17:00 +0800)
committerBruce Richardson <bruce.richardson@intel.com>
Fri, 30 Sep 2016 10:27:18 +0000 (12:27 +0200)
This patch adds X550em_a FW ALEF support. ALEF is the new unified FW.
The driver uses the KRM_PMD_RX_FLEX_PORT/FLX_MASK_ST20 registers to
configure the lane mode.

Signed-off-by: Xiao Wang <xiao.w.wang@intel.com>
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
drivers/net/ixgbe/base/ixgbe_type.h
drivers/net/ixgbe/base/ixgbe_x550.c

index a3cc5e2..92c3e24 100644 (file)
@@ -4162,9 +4162,25 @@ struct ixgbe_hw {
 #define IXGBE_KRM_DSP_TXFFE_STATE_5(P) ((P) ? 0x8638 : 0x4638)
 #define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P)        ((P) ? 0x8B00 : 0x4B00)
 #define IXGBE_KRM_PMD_DFX_BURNIN(P)    ((P) ? 0x8E00 : 0x4E00)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20(P) ((P) ? 0x9054 : 0x5054)
 #define IXGBE_KRM_TX_COEFF_CTRL_1(P)   ((P) ? 0x9520 : 0x5520)
 #define IXGBE_KRM_RX_ANA_CTL(P)                ((P) ? 0x9A00 : 0x5A00)
 
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA         ~(0x3 << 20)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR         (1u << 20)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_LR         (0x2 << 20)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN           (1u << 25)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN            (1u << 26)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN              (1u << 27)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10M          ~(0x7 << 28)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_100M         (1u << 28)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G           (0x2 << 28)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G          (0x3 << 28)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN           (0x4 << 28)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_2_5G         (0x7 << 28)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK         (0x7 << 28)
+#define IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART      (1u << 31)
+
 #define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_32B           (1 << 9)
 #define IXGBE_KRM_PORT_CAR_GEN_CTRL_NELB_KRPCS         (1 << 11)
 
index 19a554d..0cc7a3f 100644 (file)
@@ -1606,6 +1606,53 @@ s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
        return IXGBE_SUCCESS;
 }
 
+/**
+*  ixgbe_restart_an_internal_phy_x550em - restart autonegotiation for the
+*  internal PHY
+*  @hw: pointer to hardware structure
+**/
+STATIC s32 ixgbe_restart_an_internal_phy_x550em(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u32 link_ctrl;
+
+       /* Restart auto-negotiation. */
+       status = hw->mac.ops.read_iosf_sb_reg(hw,
+                                      IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+                                      IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
+
+       if (status) {
+               DEBUGOUT("Auto-negotiation did not complete\n");
+               return status;
+       }
+
+       link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
+       status = hw->mac.ops.write_iosf_sb_reg(hw,
+                                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
+                                       IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
+
+       if (hw->mac.type == ixgbe_mac_X550EM_a) {
+               u32 flx_mask_st20;
+
+               /* Indicate to FW that AN restart has been asserted */
+               status = hw->mac.ops.read_iosf_sb_reg(hw,
+                               IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_mask_st20);
+
+               if (status) {
+                       DEBUGOUT("Auto-negotiation did not complete\n");
+                       return status;
+               }
+
+               flx_mask_st20 |= IXGBE_KRM_PMD_FLX_MASK_ST20_FW_AN_RESTART;
+               status = hw->mac.ops.write_iosf_sb_reg(hw,
+                               IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, flx_mask_st20);
+       }
+
+       return status;
+}
+
 /**
  * ixgbe_setup_sgmii - Set up link for sgmii
  * @hw: pointer to hardware structure
@@ -1614,7 +1661,7 @@ STATIC s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
                             bool autoneg_wait)
 {
        struct ixgbe_mac_info *mac = &hw->mac;
-       u32 lval, sval;
+       u32 lval, sval, flx_val;
        s32 rc;
 
        rc = mac->ops.read_iosf_sb_reg(hw,
@@ -1648,10 +1695,25 @@ STATIC s32 ixgbe_setup_sgmii(struct ixgbe_hw *hw, ixgbe_link_speed speed,
        if (rc)
                return rc;
 
-       lval |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
+       rc = mac->ops.read_iosf_sb_reg(hw,
+                                   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                                   IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
+       if (rc)
+               return rc;
+
+       flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
+       flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
+       flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
+       flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
+       flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
+
        rc = mac->ops.write_iosf_sb_reg(hw,
-                                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-                                       IXGBE_SB_IOSF_TARGET_KR_PHY, lval);
+                                   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                                   IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
+       if (rc)
+               return rc;
+
+       rc = ixgbe_restart_an_internal_phy_x550em(hw);
        if (rc)
                return rc;
 
@@ -1666,7 +1728,7 @@ STATIC s32 ixgbe_setup_sgmii_m88(struct ixgbe_hw *hw, ixgbe_link_speed speed,
                                 bool autoneg_wait)
 {
        struct ixgbe_mac_info *mac = &hw->mac;
-       u32 lval, sval;
+       u32 lval, sval, flx_val;
        s32 rc;
 
        rc = mac->ops.read_iosf_sb_reg(hw,
@@ -1700,13 +1762,32 @@ STATIC s32 ixgbe_setup_sgmii_m88(struct ixgbe_hw *hw, ixgbe_link_speed speed,
        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);
        if (rc)
                return rc;
 
+       rc = mac->ops.read_iosf_sb_reg(hw,
+                                   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                                   IXGBE_SB_IOSF_TARGET_KR_PHY, &flx_val);
+       if (rc)
+               return rc;
+
+       flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
+       flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
+       flx_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
+       flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
+       flx_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
+
+       rc = mac->ops.write_iosf_sb_reg(hw,
+                                   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                                   IXGBE_SB_IOSF_TARGET_KR_PHY, flx_val);
+       if (rc)
+               return rc;
+
+       rc = ixgbe_restart_an_internal_phy_x550em(hw);
+
        return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
 }
 
@@ -2024,13 +2105,24 @@ STATIC s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *hw,
        if (speed & IXGBE_LINK_SPEED_1GB_FULL)
                reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_CAP_KX;
 
-       /* Restart auto-negotiation. */
-       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
        status = hw->mac.ops.write_iosf_sb_reg(hw,
                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
                       IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 
-       return status;
+       if (status)
+               return status;
+
+       reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
+       reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_AN;
+       reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
+       reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
+       reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
+
+       status = hw->mac.ops.write_iosf_sb_reg(hw,
+                                   IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                                   IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+       return ixgbe_restart_an_internal_phy_x550em(hw);
 }
 
 /**
@@ -2661,6 +2753,55 @@ s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
        return ret_val;
 }
 
+/**
+ *  ixgbe_setup_sfi_x550a - Configure the internal PHY for native SFI mode
+ *  @hw: pointer to hardware structure
+ *  @speed: the link speed to force
+ *
+ *  Configures the integrated PHY for native SFI mode. Used to connect the
+ *  internal PHY directly to an SFP cage, without autonegotiation.
+ **/
+STATIC s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+       s32 status;
+       u32 reg_val;
+
+       /* Disable all AN and force speed to 10G Serial. */
+       status = mac->ops.read_iosf_sb_reg(hw,
+                               IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
+       if (status != IXGBE_SUCCESS)
+               return status;
+
+       reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN_EN;
+       reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_AN37_EN;
+       reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SGMII_EN;
+       reg_val &= ~IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_MASK;
+
+       /* Select forced link speed for internal PHY. */
+       switch (*speed) {
+       case IXGBE_LINK_SPEED_10GB_FULL:
+               reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_10G;
+               break;
+       case IXGBE_LINK_SPEED_1GB_FULL:
+               reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
+               break;
+       default:
+               /* Other link speeds are not supported by internal PHY. */
+               return IXGBE_ERR_LINK_SETUP;
+       }
+
+       status = mac->ops.write_iosf_sb_reg(hw,
+                               IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+
+       /* Toggle port SW reset by AN reset. */
+       status = ixgbe_restart_an_internal_phy_x550em(hw);
+
+       return status;
+}
+
 /**
  *  ixgbe_setup_mac_link_sfp_x550a - Setup internal PHY for SFP
  *  @hw: pointer to hardware structure
@@ -2691,31 +2832,27 @@ s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
                return ret_val;
 
        if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
-               /* Configure internal PHY for native SFI */
+               /* Configure internal PHY for native SFI based on module type */
                ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
-                              IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
-                              IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_phy_int);
+                                  IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                                  IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_phy_int);
 
                if (ret_val != IXGBE_SUCCESS)
                        return ret_val;
 
-               if (setup_linear) {
-                       reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LIMITING;
-                       reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LINEAR;
-               } else {
-                       reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LIMITING;
-                       reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LINEAR;
-               }
+               reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
+               if (!setup_linear)
+                       reg_phy_int |= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR;
 
                ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
-                               IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
-                               IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
+                                  IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+                                  IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
 
                if (ret_val != IXGBE_SUCCESS)
                        return ret_val;
 
-               /* Setup XFI/SFI internal link. */
-               ret_val = ixgbe_setup_ixfi_x550em(hw, &speed);
+               /* Setup SFI internal link. */
+               ret_val = ixgbe_setup_sfi_x550a(hw, &speed);
        } else {
                /* Configure internal PHY for KR/KX. */
                ixgbe_setup_kr_speed_x550em(hw, speed);
@@ -2874,15 +3011,7 @@ STATIC s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
        }
 
        /* Toggle port SW reset by AN reset. */
-       status = mac->ops.read_iosf_sb_reg(hw,
-                                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-                                       IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
-       if (status != IXGBE_SUCCESS)
-               return status;
-       reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
-       status = mac->ops.write_iosf_sb_reg(hw,
-                                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-                                       IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+       status = ixgbe_restart_an_internal_phy_x550em(hw);
 
        return status;
 }
@@ -4225,7 +4354,7 @@ out:
 s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_SUCCESS;
-       u32 an_cntl, link_ctrl = 0;
+       u32 an_cntl = 0;
 
        DEBUGFUNC("ixgbe_setup_fc_backplane_x550em_a");
 
@@ -4299,19 +4428,7 @@ s32 ixgbe_setup_fc_backplane_x550em_a(struct ixgbe_hw *hw)
                                       IXGBE_SB_IOSF_TARGET_KR_PHY, an_cntl);
 
        /* Restart auto-negotiation. */
-       status = hw->mac.ops.read_iosf_sb_reg(hw,
-                                     IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-                                     IXGBE_SB_IOSF_TARGET_KR_PHY, &link_ctrl);
-
-       if (status != IXGBE_SUCCESS) {
-               DEBUGOUT("Auto-Negotiation did not complete\n");
-               return status;
-       }
-
-       link_ctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
-       status = hw->mac.ops.write_iosf_sb_reg(hw,
-                                      IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-                                      IXGBE_SB_IOSF_TARGET_KR_PHY, link_ctrl);
+       status = ixgbe_restart_an_internal_phy_x550em(hw);
 
        return status;
 }
@@ -4425,19 +4542,7 @@ s32 ixgbe_setup_fc_fiber_x550em_a(struct ixgbe_hw *hw)
                                           IXGBE_SB_IOSF_TARGET_KR_PHY, pcs_an);
 
        /* Restart auto-negotiation. */
-       rc = hw->mac.ops.read_iosf_sb_reg(hw,
-                                         IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-                                         IXGBE_SB_IOSF_TARGET_KR_PHY, &lctrl);
-
-       if (rc) {
-               DEBUGOUT("Auto-Negotiation did not complete\n");
-               return rc;
-       }
-
-       lctrl |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
-       rc = hw->mac.ops.write_iosf_sb_reg(hw,
-                                       IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-                                       IXGBE_SB_IOSF_TARGET_KR_PHY, lctrl);
+       rc = ixgbe_restart_an_internal_phy_x550em(hw);
 
        return rc;
 }