aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2013-03-11 01:17:50 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-12 07:54:25 -0400
commite438c5d651e2a7b7d6d1bad23cc3a878392e6a5c (patch)
tree75f1a6b002e29cb4e7e8e2bb898216034ceeccd7
parent31b958d755d1d124ce3a0fbc998434fe9c0ab88b (diff)
bnx2x: Control SFP+ tap values via nvm config
Configure SFP+ tap values to optimize link signal according to NVRAM setup. Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h17
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c77
2 files changed, 60 insertions, 34 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index 037860ecc343..a7a3504e1bd5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -508,7 +508,22 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
508 #define PORT_HW_CFG_PAUSE_ON_HOST_RING_DISABLED 0x00000000 508 #define PORT_HW_CFG_PAUSE_ON_HOST_RING_DISABLED 0x00000000
509 #define PORT_HW_CFG_PAUSE_ON_HOST_RING_ENABLED 0x00000001 509 #define PORT_HW_CFG_PAUSE_ON_HOST_RING_ENABLED 0x00000001
510 510
511 u32 reserved0[6]; /* 0x178 */ 511 /* SFP+ Tx Equalization: NIC recommended and tested value is 0xBEB2
512 * LOM recommended and tested value is 0xBEB2. Using a different
513 * value means using a value not tested by BRCM
514 */
515 u32 sfi_tap_values; /* 0x178 */
516 #define PORT_HW_CFG_TX_EQUALIZATION_MASK 0x0000FFFF
517 #define PORT_HW_CFG_TX_EQUALIZATION_SHIFT 0
518
519 /* SFP+ Tx driver broadcast IDRIVER: NIC recommended and tested
520 * value is 0x2. LOM recommended and tested value is 0x2. Using a
521 * different value means using a value not tested by BRCM
522 */
523 #define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000
524 #define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16
525
526 u32 reserved0[5]; /* 0x17c */
512 527
513 u32 aeu_int_mask; /* 0x190 */ 528 u32 aeu_int_mask; /* 0x190 */
514 529
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 5fc205fba8c0..e3fa80807394 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -3630,6 +3630,16 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3630 * init configuration, and set/clear SGMII flag. Internal 3630 * init configuration, and set/clear SGMII flag. Internal
3631 * phy init is done purely in phy_init stage. 3631 * phy init is done purely in phy_init stage.
3632 */ 3632 */
3633#define WC_TX_DRIVER(post2, idriver, ipre) \
3634 ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
3635 (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
3636 (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))
3637
3638#define WC_TX_FIR(post, main, pre) \
3639 ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
3640 (main << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | \
3641 (pre << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET))
3642
3633static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy, 3643static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy,
3634 struct link_params *params, 3644 struct link_params *params,
3635 struct link_vars *vars) 3645 struct link_vars *vars)
@@ -3754,20 +3764,13 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3754 /* Set Transmit PMD settings */ 3764 /* Set Transmit PMD settings */
3755 lane = bnx2x_get_warpcore_lane(phy, params); 3765 lane = bnx2x_get_warpcore_lane(phy, params);
3756 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3766 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3757 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 3767 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3758 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | 3768 WC_TX_DRIVER(0x02, 0x06, 0x09));
3759 (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3760 (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3761 /* Configure the next lane if dual mode */ 3769 /* Configure the next lane if dual mode */
3762 if (phy->flags & FLAGS_WC_DUAL_MODE) 3770 if (phy->flags & FLAGS_WC_DUAL_MODE)
3763 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3771 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3764 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), 3772 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1),
3765 ((0x02 << 3773 WC_TX_DRIVER(0x02, 0x06, 0x09));
3766 MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3767 (0x06 <<
3768 MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3769 (0x09 <<
3770 MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3771 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3774 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3772 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, 3775 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3773 0x03f0); 3776 0x03f0);
@@ -3910,6 +3913,8 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3910{ 3913{
3911 struct bnx2x *bp = params->bp; 3914 struct bnx2x *bp = params->bp;
3912 u16 misc1_val, tap_val, tx_driver_val, lane, val; 3915 u16 misc1_val, tap_val, tx_driver_val, lane, val;
3916 u32 cfg_tap_val, tx_drv_brdct, tx_equal;
3917
3913 /* Hold rxSeqStart */ 3918 /* Hold rxSeqStart */
3914 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, 3919 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3915 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000); 3920 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
@@ -3953,23 +3958,33 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3953 3958
3954 if (is_xfi) { 3959 if (is_xfi) {
3955 misc1_val |= 0x5; 3960 misc1_val |= 0x5;
3956 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | 3961 tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
3957 (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | 3962 tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03);
3958 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3959 tx_driver_val =
3960 ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3961 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3962 (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3963
3964 } else { 3963 } else {
3964 cfg_tap_val = REG_RD(bp, params->shmem_base +
3965 offsetof(struct shmem_region, dev_info.
3966 port_hw_config[params->port].
3967 sfi_tap_values));
3968
3969 tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
3970
3971 tx_drv_brdct = (cfg_tap_val &
3972 PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
3973 PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
3974
3965 misc1_val |= 0x9; 3975 misc1_val |= 0x9;
3966 tap_val = ((0x0f << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | 3976
3967 (0x2b << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | 3977 /* TAP values are controlled by nvram, if value there isn't 0 */
3968 (0x02 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); 3978 if (tx_equal)
3969 tx_driver_val = 3979 tap_val = (u16)tx_equal;
3970 ((0x03 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | 3980 else
3971 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | 3981 tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
3972 (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); 3982
3983 if (tx_drv_brdct)
3984 tx_driver_val = WC_TX_DRIVER(0x03, (u16)tx_drv_brdct,
3985 0x06);
3986 else
3987 tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06);
3973 } 3988 }
3974 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 3989 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3975 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); 3990 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
@@ -4106,15 +4121,11 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
4106 /* Set Transmit PMD settings */ 4121 /* Set Transmit PMD settings */
4107 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4122 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4108 MDIO_WC_REG_TX_FIR_TAP, 4123 MDIO_WC_REG_TX_FIR_TAP,
4109 ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | 4124 (WC_TX_FIR(0x12, 0x2d, 0x00) |
4110 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | 4125 MDIO_WC_REG_TX_FIR_TAP_ENABLE));
4111 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
4112 MDIO_WC_REG_TX_FIR_TAP_ENABLE));
4113 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, 4126 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4114 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 4127 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4115 ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | 4128 WC_TX_DRIVER(0x02, 0x02, 0x02));
4116 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
4117 (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
4118} 4129}
4119 4130
4120static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, 4131static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,