diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2013-03-11 01:17:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-12 07:54:25 -0400 |
commit | e438c5d651e2a7b7d6d1bad23cc3a878392e6a5c (patch) | |
tree | 75f1a6b002e29cb4e7e8e2bb898216034ceeccd7 | |
parent | 31b958d755d1d124ce3a0fbc998434fe9c0ab88b (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.h | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 77 |
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 | |||
3633 | static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy, | 3643 | static 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 | ||
4120 | static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, | 4131 | static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, |