aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_link.c
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-02-12 03:37:14 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-16 02:31:41 -0500
commitc2c8b03e200bdda3ba23d27f5c33bac784dced01 (patch)
treec15811bb47f3790e106660e5919cb690f288f3af /drivers/net/bnx2x_link.c
parented8680a7e68fc07d6b2bfa977e8f5f3d3c568d14 (diff)
bnx2x: Pre emphasis configuration
Supporting non-default pre-emphasis settings for the internal and some external PHYs Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x_link.c130
1 files changed, 98 insertions, 32 deletions
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index b61a7a24ecc..4a594b84ba2 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -1758,33 +1758,39 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1758 struct bnx2x *bp = params->bp; 1758 struct bnx2x *bp = params->bp;
1759 u16 lp_up2; 1759 u16 lp_up2;
1760 u16 tx_driver; 1760 u16 tx_driver;
1761 u16 bank;
1761 1762
1762 /* read precomp */ 1763 /* read precomp */
1763
1764 CL45_RD_OVER_CL22(bp, params->port, 1764 CL45_RD_OVER_CL22(bp, params->port,
1765 params->phy_addr, 1765 params->phy_addr,
1766 MDIO_REG_BANK_OVER_1G, 1766 MDIO_REG_BANK_OVER_1G,
1767 MDIO_OVER_1G_LP_UP2, &lp_up2); 1767 MDIO_OVER_1G_LP_UP2, &lp_up2);
1768 1768
1769 CL45_RD_OVER_CL22(bp, params->port,
1770 params->phy_addr,
1771 MDIO_REG_BANK_TX0,
1772 MDIO_TX0_TX_DRIVER, &tx_driver);
1773
1774 /* bits [10:7] at lp_up2, positioned at [15:12] */ 1769 /* bits [10:7] at lp_up2, positioned at [15:12] */
1775 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >> 1770 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1776 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) << 1771 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1777 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT); 1772 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1778 1773
1779 if ((lp_up2 != 0) && 1774 if (lp_up2 == 0)
1780 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) { 1775 return;
1781 /* replace tx_driver bits [15:12] */ 1776
1782 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; 1777 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
1783 tx_driver |= lp_up2; 1778 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
1784 CL45_WR_OVER_CL22(bp, params->port, 1779 CL45_RD_OVER_CL22(bp, params->port,
1785 params->phy_addr, 1780 params->phy_addr,
1786 MDIO_REG_BANK_TX0, 1781 bank,
1787 MDIO_TX0_TX_DRIVER, tx_driver); 1782 MDIO_TX0_TX_DRIVER, &tx_driver);
1783
1784 /* replace tx_driver bits [15:12] */
1785 if (lp_up2 !=
1786 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
1787 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1788 tx_driver |= lp_up2;
1789 CL45_WR_OVER_CL22(bp, params->port,
1790 params->phy_addr,
1791 bank,
1792 MDIO_TX0_TX_DRIVER, tx_driver);
1793 }
1788 } 1794 }
1789} 1795}
1790 1796
@@ -2890,31 +2896,40 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
2890 MDIO_AN_DEVAD, 2896 MDIO_AN_DEVAD,
2891 MDIO_AN_REG_ADV_PAUSE, val); 2897 MDIO_AN_REG_ADV_PAUSE, val);
2892} 2898}
2899static void bnx2x_set_preemphasis(struct link_params *params)
2900{
2901 u16 bank, i = 0;
2902 struct bnx2x *bp = params->bp;
2893 2903
2904 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
2905 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
2906 CL45_WR_OVER_CL22(bp, params->port,
2907 params->phy_addr,
2908 bank,
2909 MDIO_RX0_RX_EQ_BOOST,
2910 params->xgxs_config_rx[i]);
2911 }
2912
2913 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
2914 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
2915 CL45_WR_OVER_CL22(bp, params->port,
2916 params->phy_addr,
2917 bank,
2918 MDIO_TX0_TX_DRIVER,
2919 params->xgxs_config_tx[i]);
2920 }
2921}
2894 2922
2895static void bnx2x_init_internal_phy(struct link_params *params, 2923static void bnx2x_init_internal_phy(struct link_params *params,
2896 struct link_vars *vars) 2924 struct link_vars *vars)
2897{ 2925{
2898 struct bnx2x *bp = params->bp; 2926 struct bnx2x *bp = params->bp;
2899 u8 port = params->port;
2900 if (!(vars->phy_flags & PHY_SGMII_FLAG)) { 2927 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2901 u16 bank, rx_eq; 2928 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
2902 2929 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2903 rx_eq = ((params->serdes_config & 2930 (params->feature_config_flags &
2904 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >> 2931 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2905 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT); 2932 bnx2x_set_preemphasis(params);
2906
2907 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2908 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2909 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2910 CL45_WR_OVER_CL22(bp, port,
2911 params->phy_addr,
2912 bank ,
2913 MDIO_RX0_RX_EQ_BOOST,
2914 ((rx_eq &
2915 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2916 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2917 }
2918 2933
2919 /* forced speed requested? */ 2934 /* forced speed requested? */
2920 if (vars->line_speed != SPEED_AUTO_NEG) { 2935 if (vars->line_speed != SPEED_AUTO_NEG) {
@@ -3038,6 +3053,35 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3038 } 3053 }
3039 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized " 3054 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3040 "after %d ms\n", cnt); 3055 "after %d ms\n", cnt);
3056 if ((params->feature_config_flags &
3057 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3058 u8 i;
3059 u16 reg;
3060 for (i = 0; i < 4; i++) {
3061 reg = MDIO_XS_8706_REG_BANK_RX0 +
3062 i*(MDIO_XS_8706_REG_BANK_RX1 -
3063 MDIO_XS_8706_REG_BANK_RX0);
3064 bnx2x_cl45_read(bp, params->port,
3065 ext_phy_type,
3066 ext_phy_addr,
3067 MDIO_XS_DEVAD,
3068 reg, &val);
3069 /* Clear first 3 bits of the control */
3070 val &= ~0x7;
3071 /* Set control bits according to
3072 configuation */
3073 val |= (params->xgxs_config_rx[i] &
3074 0x7);
3075 DP(NETIF_MSG_LINK, "Setting RX"
3076 "Equalizer to BCM8706 reg 0x%x"
3077 " <-- val 0x%x\n", reg, val);
3078 bnx2x_cl45_write(bp, params->port,
3079 ext_phy_type,
3080 ext_phy_addr,
3081 MDIO_XS_DEVAD,
3082 reg, val);
3083 }
3084 }
3041 /* Force speed */ 3085 /* Force speed */
3042 /* First enable LASI */ 3086 /* First enable LASI */
3043 bnx2x_cl45_write(bp, params->port, 3087 bnx2x_cl45_write(bp, params->port,
@@ -3170,6 +3214,28 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3170 ext_phy_addr, MDIO_PMA_DEVAD, 3214 ext_phy_addr, MDIO_PMA_DEVAD,
3171 MDIO_PMA_REG_LASI_CTRL, 1); 3215 MDIO_PMA_REG_LASI_CTRL, 1);
3172 } 3216 }
3217
3218 /* Set TX PreEmphasis if needed */
3219 if ((params->feature_config_flags &
3220 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3221 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3222 "TX_CTRL2 0x%x\n",
3223 params->xgxs_config_tx[0],
3224 params->xgxs_config_tx[1]);
3225 bnx2x_cl45_write(bp, params->port,
3226 ext_phy_type,
3227 ext_phy_addr,
3228 MDIO_PMA_DEVAD,
3229 MDIO_PMA_REG_8726_TX_CTRL1,
3230 params->xgxs_config_tx[0]);
3231
3232 bnx2x_cl45_write(bp, params->port,
3233 ext_phy_type,
3234 ext_phy_addr,
3235 MDIO_PMA_DEVAD,
3236 MDIO_PMA_REG_8726_TX_CTRL2,
3237 params->xgxs_config_tx[1]);
3238 }
3173 break; 3239 break;
3174 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 3240 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3175 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 3241 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: