diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-02-12 03:37:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 02:31:41 -0500 |
commit | c2c8b03e200bdda3ba23d27f5c33bac784dced01 (patch) | |
tree | c15811bb47f3790e106660e5919cb690f288f3af /drivers/net/bnx2x_link.c | |
parent | ed8680a7e68fc07d6b2bfa977e8f5f3d3c568d14 (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.c | 130 |
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 | } |
2899 | static 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 | ||
2895 | static void bnx2x_init_internal_phy(struct link_params *params, | 2923 | static 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: |