diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2012-11-26 22:46:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-28 10:59:20 -0500 |
commit | 4e7b4997886e1dcbb0024308fb474c5994e8af2b (patch) | |
tree | dd28ceb8a19f14a52ee3d4d085a472a9c1ff249a /drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |
parent | b884d95b8222a50144e3d84fe9becedae836e56d (diff) |
bnx2x: Add support for 20G-KR2
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/ethernet/broadcom/bnx2x/bnx2x_link.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 366 |
1 files changed, 334 insertions, 32 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index c98da25f22eb..eb44b230676e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -121,6 +121,7 @@ | |||
121 | #define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI | 121 | #define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI |
122 | #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS | 122 | #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS |
123 | #define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI | 123 | #define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI |
124 | #define GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2 | ||
124 | #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD | 125 | #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD |
125 | #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD | 126 | #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD |
126 | #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD | 127 | #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD |
@@ -1664,7 +1665,10 @@ static void bnx2x_xmac_init(struct link_params *params, u32 max_speed) | |||
1664 | * ports of the path | 1665 | * ports of the path |
1665 | */ | 1666 | */ |
1666 | 1667 | ||
1667 | if ((CHIP_NUM(bp) == CHIP_NUM_57840_4_10) && | 1668 | if (((CHIP_NUM(bp) == CHIP_NUM_57840_4_10) || |
1669 | (CHIP_NUM(bp) == CHIP_NUM_57840_2_20) || | ||
1670 | (CHIP_NUM(bp) == CHIP_NUM_57840_OBSOLETE)) && | ||
1671 | is_port4mode && | ||
1668 | (REG_RD(bp, MISC_REG_RESET_REG_2) & | 1672 | (REG_RD(bp, MISC_REG_RESET_REG_2) & |
1669 | MISC_REGISTERS_RESET_REG_2_XMAC)) { | 1673 | MISC_REGISTERS_RESET_REG_2_XMAC)) { |
1670 | DP(NETIF_MSG_LINK, | 1674 | DP(NETIF_MSG_LINK, |
@@ -1760,6 +1764,18 @@ static int bnx2x_xmac_enable(struct link_params *params, | |||
1760 | */ | 1764 | */ |
1761 | REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0); | 1765 | REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0); |
1762 | 1766 | ||
1767 | /* When XMAC is in XLGMII mode, disable sending idles for fault | ||
1768 | * detection. | ||
1769 | */ | ||
1770 | if (!(params->phy[INT_PHY].flags & FLAGS_TX_ERROR_CHECK)) { | ||
1771 | REG_WR(bp, xmac_base + XMAC_REG_RX_LSS_CTRL, | ||
1772 | (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE | | ||
1773 | XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE)); | ||
1774 | REG_WR(bp, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0); | ||
1775 | REG_WR(bp, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, | ||
1776 | XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS | | ||
1777 | XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS); | ||
1778 | } | ||
1763 | /* Set Max packet size */ | 1779 | /* Set Max packet size */ |
1764 | REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710); | 1780 | REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710); |
1765 | 1781 | ||
@@ -1780,6 +1796,12 @@ static int bnx2x_xmac_enable(struct link_params *params, | |||
1780 | /* Enable TX and RX */ | 1796 | /* Enable TX and RX */ |
1781 | val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN; | 1797 | val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN; |
1782 | 1798 | ||
1799 | /* Set MAC in XLGMII mode for dual-mode */ | ||
1800 | if ((vars->line_speed == SPEED_20000) && | ||
1801 | (params->phy[INT_PHY].supported & | ||
1802 | SUPPORTED_20000baseKR2_Full)) | ||
1803 | val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB; | ||
1804 | |||
1783 | /* Check loopback mode */ | 1805 | /* Check loopback mode */ |
1784 | if (lb) | 1806 | if (lb) |
1785 | val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK; | 1807 | val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK; |
@@ -2096,6 +2118,16 @@ static void bnx2x_update_mng(struct link_params *params, u32 link_status) | |||
2096 | port_mb[params->port].link_status), link_status); | 2118 | port_mb[params->port].link_status), link_status); |
2097 | } | 2119 | } |
2098 | 2120 | ||
2121 | static void bnx2x_update_link_attr(struct link_params *params, u32 link_attr) | ||
2122 | { | ||
2123 | struct bnx2x *bp = params->bp; | ||
2124 | |||
2125 | if (SHMEM2_HAS(bp, link_attr_sync)) | ||
2126 | REG_WR(bp, params->shmem2_base + | ||
2127 | offsetof(struct shmem2_region, | ||
2128 | link_attr_sync[params->port]), link_attr); | ||
2129 | } | ||
2130 | |||
2099 | static void bnx2x_update_pfc_nig(struct link_params *params, | 2131 | static void bnx2x_update_pfc_nig(struct link_params *params, |
2100 | struct link_vars *vars, | 2132 | struct link_vars *vars, |
2101 | struct bnx2x_nig_brb_pfc_port_params *nig_params) | 2133 | struct bnx2x_nig_brb_pfc_port_params *nig_params) |
@@ -3147,6 +3179,15 @@ static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy, | |||
3147 | bnx2x_cl45_write(bp, phy, devad, reg, val | or_val); | 3179 | bnx2x_cl45_write(bp, phy, devad, reg, val | or_val); |
3148 | } | 3180 | } |
3149 | 3181 | ||
3182 | static void bnx2x_cl45_read_and_write(struct bnx2x *bp, | ||
3183 | struct bnx2x_phy *phy, | ||
3184 | u8 devad, u16 reg, u16 and_val) | ||
3185 | { | ||
3186 | u16 val; | ||
3187 | bnx2x_cl45_read(bp, phy, devad, reg, &val); | ||
3188 | bnx2x_cl45_write(bp, phy, devad, reg, val & and_val); | ||
3189 | } | ||
3190 | |||
3150 | int bnx2x_phy_read(struct link_params *params, u8 phy_addr, | 3191 | int bnx2x_phy_read(struct link_params *params, u8 phy_addr, |
3151 | u8 devad, u16 reg, u16 *ret_val) | 3192 | u8 devad, u16 reg, u16 *ret_val) |
3152 | { | 3193 | { |
@@ -3551,6 +3592,44 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, | |||
3551 | * init configuration, and set/clear SGMII flag. Internal | 3592 | * init configuration, and set/clear SGMII flag. Internal |
3552 | * phy init is done purely in phy_init stage. | 3593 | * phy init is done purely in phy_init stage. |
3553 | */ | 3594 | */ |
3595 | static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy, | ||
3596 | struct link_params *params, | ||
3597 | struct link_vars *vars) | ||
3598 | { | ||
3599 | struct bnx2x *bp = params->bp; | ||
3600 | u16 i; | ||
3601 | static struct bnx2x_reg_set reg_set[] = { | ||
3602 | /* Step 1 - Program the TX/RX alignment markers */ | ||
3603 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0xa157}, | ||
3604 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xcbe2}, | ||
3605 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0x7537}, | ||
3606 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0xa157}, | ||
3607 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xcbe2}, | ||
3608 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0x7537}, | ||
3609 | /* Step 2 - Configure the NP registers */ | ||
3610 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000a}, | ||
3611 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6400}, | ||
3612 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0620}, | ||
3613 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0157}, | ||
3614 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x6464}, | ||
3615 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x3150}, | ||
3616 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x3150}, | ||
3617 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0157}, | ||
3618 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0620} | ||
3619 | }; | ||
3620 | DP(NETIF_MSG_LINK, "Enabling 20G-KR2\n"); | ||
3621 | |||
3622 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | ||
3623 | MDIO_WC_REG_CL49_USERB0_CTRL, (3<<6)); | ||
3624 | |||
3625 | for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++) | ||
3626 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, | ||
3627 | reg_set[i].val); | ||
3628 | |||
3629 | /* Start KR2 work-around timer which handles BCM8073 link-parner */ | ||
3630 | vars->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE; | ||
3631 | bnx2x_update_link_attr(params, vars->link_attr_sync); | ||
3632 | } | ||
3554 | 3633 | ||
3555 | static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, | 3634 | static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, |
3556 | struct link_params *params) | 3635 | struct link_params *params) |
@@ -3564,6 +3643,21 @@ static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, | |||
3564 | MDIO_WC_REG_DIGITAL4_MISC5, 0xc000); | 3643 | MDIO_WC_REG_DIGITAL4_MISC5, 0xc000); |
3565 | } | 3644 | } |
3566 | 3645 | ||
3646 | static void bnx2x_warpcore_restart_AN_KR(struct bnx2x_phy *phy, | ||
3647 | struct link_params *params) | ||
3648 | { | ||
3649 | /* Restart autoneg on the leading lane only */ | ||
3650 | struct bnx2x *bp = params->bp; | ||
3651 | u16 lane = bnx2x_get_warpcore_lane(phy, params); | ||
3652 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
3653 | MDIO_AER_BLOCK_AER_REG, lane); | ||
3654 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
3655 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200); | ||
3656 | |||
3657 | /* Restore AER */ | ||
3658 | bnx2x_set_aer_mmd(params, phy); | ||
3659 | } | ||
3660 | |||
3567 | static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | 3661 | static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, |
3568 | struct link_params *params, | 3662 | struct link_params *params, |
3569 | struct link_vars *vars) { | 3663 | struct link_vars *vars) { |
@@ -3576,7 +3670,9 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
3576 | {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, | 3670 | {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, |
3577 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, | 3671 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, |
3578 | /* Disable Autoneg: re-enable it after adv is done. */ | 3672 | /* Disable Autoneg: re-enable it after adv is done. */ |
3579 | {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0} | 3673 | {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0}, |
3674 | {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2}, | ||
3675 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0}, | ||
3580 | }; | 3676 | }; |
3581 | DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); | 3677 | DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); |
3582 | /* Set to default registers that may be overriden by 10G force */ | 3678 | /* Set to default registers that may be overriden by 10G force */ |
@@ -3586,7 +3682,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
3586 | 3682 | ||
3587 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | 3683 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, |
3588 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl); | 3684 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl); |
3589 | cl72_ctrl &= 0xf8ff; | 3685 | cl72_ctrl &= 0x08ff; |
3590 | cl72_ctrl |= 0x3800; | 3686 | cl72_ctrl |= 0x3800; |
3591 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 3687 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3592 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl); | 3688 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl); |
@@ -3624,6 +3720,16 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
3624 | ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | | 3720 | ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | |
3625 | (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | | 3721 | (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | |
3626 | (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); | 3722 | (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); |
3723 | /* Configure the next lane if dual mode */ | ||
3724 | if (phy->flags & FLAGS_WC_DUAL_MODE) | ||
3725 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3726 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), | ||
3727 | ((0x02 << | ||
3728 | MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | | ||
3729 | (0x06 << | ||
3730 | MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | | ||
3731 | (0x09 << | ||
3732 | MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); | ||
3627 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 3733 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3628 | MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, | 3734 | MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, |
3629 | 0x03f0); | 3735 | 0x03f0); |
@@ -3670,10 +3776,26 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
3670 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 3776 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3671 | MDIO_WC_REG_DIGITAL3_UP1, 0x1f); | 3777 | MDIO_WC_REG_DIGITAL3_UP1, 0x1f); |
3672 | 3778 | ||
3673 | /* Enable Autoneg */ | 3779 | if (((phy->req_line_speed == SPEED_AUTO_NEG) && |
3674 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | 3780 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) || |
3675 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200); | 3781 | (phy->req_line_speed == SPEED_20000)) { |
3782 | |||
3783 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
3784 | MDIO_AER_BLOCK_AER_REG, lane); | ||
3785 | |||
3786 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | ||
3787 | MDIO_WC_REG_RX1_PCI_CTRL + (0x10*lane), | ||
3788 | (1<<11)); | ||
3789 | |||
3790 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3791 | MDIO_WC_REG_XGXS_X2_CONTROL3, 0x7); | ||
3792 | bnx2x_set_aer_mmd(params, phy); | ||
3676 | 3793 | ||
3794 | bnx2x_warpcore_enable_AN_KR2(phy, params, vars); | ||
3795 | } | ||
3796 | |||
3797 | /* Enable Autoneg: only on the main lane */ | ||
3798 | bnx2x_warpcore_restart_AN_KR(phy, params); | ||
3677 | } | 3799 | } |
3678 | 3800 | ||
3679 | static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, | 3801 | static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, |
@@ -3692,9 +3814,7 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, | |||
3692 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, | 3814 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, |
3693 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, | 3815 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, |
3694 | /* Leave cl72 training enable, needed for KR */ | 3816 | /* Leave cl72 training enable, needed for KR */ |
3695 | {MDIO_PMA_DEVAD, | 3817 | {MDIO_PMA_DEVAD, MDIO_WC_REG_PMD_KR_CONTROL, 0x2} |
3696 | MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, | ||
3697 | 0x2} | ||
3698 | }; | 3818 | }; |
3699 | 3819 | ||
3700 | for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++) | 3820 | for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++) |
@@ -3858,10 +3978,57 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, | |||
3858 | MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF)); | 3978 | MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF)); |
3859 | } | 3979 | } |
3860 | 3980 | ||
3861 | static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp, | 3981 | static void bnx2x_warpcore_set_20G_force_KR2(struct bnx2x_phy *phy, |
3862 | struct bnx2x_phy *phy) | 3982 | struct link_params *params) |
3863 | { | 3983 | { |
3864 | DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n"); | 3984 | u16 val; |
3985 | struct bnx2x *bp = params->bp; | ||
3986 | /* Set global registers, so set AER lane to 0 */ | ||
3987 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
3988 | MDIO_AER_BLOCK_AER_REG, 0); | ||
3989 | |||
3990 | /* Disable sequencer */ | ||
3991 | bnx2x_cl45_read_and_write(bp, phy, MDIO_WC_DEVAD, | ||
3992 | MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, ~(1<<13)); | ||
3993 | |||
3994 | bnx2x_set_aer_mmd(params, phy); | ||
3995 | |||
3996 | bnx2x_cl45_read_and_write(bp, phy, MDIO_PMA_DEVAD, | ||
3997 | MDIO_WC_REG_PMD_KR_CONTROL, ~(1<<1)); | ||
3998 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
3999 | MDIO_AN_REG_CTRL, 0); | ||
4000 | /* Turn off CL73 */ | ||
4001 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4002 | MDIO_WC_REG_CL73_USERB0_CTRL, &val); | ||
4003 | val &= ~(1<<5); | ||
4004 | val |= (1<<6); | ||
4005 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
4006 | MDIO_WC_REG_CL73_USERB0_CTRL, val); | ||
4007 | |||
4008 | /* Set 20G KR2 force speed */ | ||
4009 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | ||
4010 | MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x1f); | ||
4011 | |||
4012 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | ||
4013 | MDIO_WC_REG_DIGITAL4_MISC3, (1<<7)); | ||
4014 | |||
4015 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4016 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &val); | ||
4017 | val &= ~(3<<14); | ||
4018 | val |= (1<<15); | ||
4019 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
4020 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, val); | ||
4021 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
4022 | MDIO_WC_REG_CL72_USERB0_CL72_TX_FIR_TAP, 0x835A); | ||
4023 | |||
4024 | /* Enable sequencer (over lane 0) */ | ||
4025 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
4026 | MDIO_AER_BLOCK_AER_REG, 0); | ||
4027 | |||
4028 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | ||
4029 | MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, (1<<13)); | ||
4030 | |||
4031 | bnx2x_set_aer_mmd(params, phy); | ||
3865 | } | 4032 | } |
3866 | 4033 | ||
3867 | static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, | 4034 | static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, |
@@ -4293,16 +4460,14 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, | |||
4293 | 4460 | ||
4294 | bnx2x_sfp_module_detection(phy, params); | 4461 | bnx2x_sfp_module_detection(phy, params); |
4295 | break; | 4462 | break; |
4296 | |||
4297 | case PORT_HW_CFG_NET_SERDES_IF_KR2: | 4463 | case PORT_HW_CFG_NET_SERDES_IF_KR2: |
4298 | if (vars->line_speed != SPEED_20000) { | 4464 | if (!params->loopback_mode) { |
4299 | DP(NETIF_MSG_LINK, "Speed not supported yet\n"); | 4465 | bnx2x_warpcore_enable_AN_KR(phy, params, vars); |
4300 | return; | 4466 | } else { |
4467 | DP(NETIF_MSG_LINK, "Setting KR 20G-Force\n"); | ||
4468 | bnx2x_warpcore_set_20G_force_KR2(phy, params); | ||
4301 | } | 4469 | } |
4302 | DP(NETIF_MSG_LINK, "Setting 20G KR2\n"); | ||
4303 | bnx2x_warpcore_set_20G_KR2(bp, phy); | ||
4304 | break; | 4470 | break; |
4305 | |||
4306 | default: | 4471 | default: |
4307 | DP(NETIF_MSG_LINK, | 4472 | DP(NETIF_MSG_LINK, |
4308 | "Unsupported Serdes Net Interface 0x%x\n", | 4473 | "Unsupported Serdes Net Interface 0x%x\n", |
@@ -4413,8 +4578,9 @@ static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, | |||
4413 | DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n", | 4578 | DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n", |
4414 | params->loopback_mode, phy->req_line_speed); | 4579 | params->loopback_mode, phy->req_line_speed); |
4415 | 4580 | ||
4416 | if (phy->req_line_speed < SPEED_10000) { | 4581 | if (phy->req_line_speed < SPEED_10000 || |
4417 | /* 10/100/1000 */ | 4582 | phy->supported & SUPPORTED_20000baseKR2_Full) { |
4583 | /* 10/100/1000/20G-KR2 */ | ||
4418 | 4584 | ||
4419 | /* Update those 1-copy registers */ | 4585 | /* Update those 1-copy registers */ |
4420 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | 4586 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, |
@@ -4427,18 +4593,20 @@ static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, | |||
4427 | lane = bnx2x_get_warpcore_lane(phy, params); | 4593 | lane = bnx2x_get_warpcore_lane(phy, params); |
4428 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | 4594 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, |
4429 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); | 4595 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); |
4596 | val16 |= (1<<lane); | ||
4597 | if (phy->flags & FLAGS_WC_DUAL_MODE) | ||
4598 | val16 |= (2<<lane); | ||
4430 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 4599 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
4431 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, | 4600 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, |
4432 | val16 | (1<<lane)); | 4601 | val16); |
4433 | 4602 | ||
4434 | /* Switch back to 4-copy registers */ | 4603 | /* Switch back to 4-copy registers */ |
4435 | bnx2x_set_aer_mmd(params, phy); | 4604 | bnx2x_set_aer_mmd(params, phy); |
4436 | } else { | 4605 | } else { |
4437 | /* 10G & 20G */ | 4606 | /* 10G / 20G-DXGXS */ |
4438 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | 4607 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, |
4439 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, | 4608 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, |
4440 | 0x4000); | 4609 | 0x4000); |
4441 | |||
4442 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | 4610 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, |
4443 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1); | 4611 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1); |
4444 | } | 4612 | } |
@@ -4603,6 +4771,10 @@ void bnx2x_link_status_update(struct link_params *params, | |||
4603 | params->feature_config_flags &= | 4771 | params->feature_config_flags &= |
4604 | ~FEATURE_CONFIG_PFC_ENABLED; | 4772 | ~FEATURE_CONFIG_PFC_ENABLED; |
4605 | 4773 | ||
4774 | if (SHMEM2_HAS(bp, link_attr_sync)) | ||
4775 | vars->link_attr_sync = SHMEM2_RD(bp, | ||
4776 | link_attr_sync[params->port]); | ||
4777 | |||
4606 | DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", | 4778 | DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x int_mask 0x%x\n", |
4607 | vars->link_status, vars->phy_link_up, vars->aeu_int_mask); | 4779 | vars->link_status, vars->phy_link_up, vars->aeu_int_mask); |
4608 | DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", | 4780 | DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", |
@@ -5332,6 +5504,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5332 | vars->link_status |= LINK_10GTFD; | 5504 | vars->link_status |= LINK_10GTFD; |
5333 | break; | 5505 | break; |
5334 | case GP_STATUS_20G_DXGXS: | 5506 | case GP_STATUS_20G_DXGXS: |
5507 | case GP_STATUS_20G_KR2: | ||
5335 | vars->line_speed = SPEED_20000; | 5508 | vars->line_speed = SPEED_20000; |
5336 | vars->link_status |= LINK_20GTFD; | 5509 | vars->link_status |= LINK_20GTFD; |
5337 | break; | 5510 | break; |
@@ -5439,7 +5612,15 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | |||
5439 | int rc = 0; | 5612 | int rc = 0; |
5440 | lane = bnx2x_get_warpcore_lane(phy, params); | 5613 | lane = bnx2x_get_warpcore_lane(phy, params); |
5441 | /* Read gp_status */ | 5614 | /* Read gp_status */ |
5442 | if (phy->req_line_speed > SPEED_10000) { | 5615 | if ((params->loopback_mode) && |
5616 | (phy->flags & FLAGS_WC_DUAL_MODE)) { | ||
5617 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
5618 | MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up); | ||
5619 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
5620 | MDIO_WC_REG_DIGITAL5_LINK_STATUS, &link_up); | ||
5621 | link_up &= 0x1; | ||
5622 | } else if ((phy->req_line_speed > SPEED_10000) && | ||
5623 | (phy->supported & SUPPORTED_20000baseMLD2_Full)) { | ||
5443 | u16 temp_link_up; | 5624 | u16 temp_link_up; |
5444 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | 5625 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, |
5445 | 1, &temp_link_up); | 5626 | 1, &temp_link_up); |
@@ -5452,12 +5633,22 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | |||
5452 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5633 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5453 | } else { | 5634 | } else { |
5454 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | 5635 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, |
5455 | MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1); | 5636 | MDIO_WC_REG_GP2_STATUS_GP_2_1, |
5637 | &gp_status1); | ||
5456 | DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1); | 5638 | DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1); |
5457 | /* Check for either KR or generic link up. */ | 5639 | /* Check for either KR, 1G, or AN up. */ |
5458 | gp_status1 = ((gp_status1 >> 8) & 0xf) | | 5640 | link_up = ((gp_status1 >> 8) | |
5459 | ((gp_status1 >> 12) & 0xf); | 5641 | (gp_status1 >> 12) | |
5460 | link_up = gp_status1 & (1 << lane); | 5642 | (gp_status1)) & |
5643 | (1 << lane); | ||
5644 | if (phy->supported & SUPPORTED_20000baseKR2_Full) { | ||
5645 | u16 an_link; | ||
5646 | bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, | ||
5647 | MDIO_AN_REG_STATUS, &an_link); | ||
5648 | bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, | ||
5649 | MDIO_AN_REG_STATUS, &an_link); | ||
5650 | link_up |= (an_link & (1<<2)); | ||
5651 | } | ||
5461 | if (link_up && SINGLE_MEDIA_DIRECT(params)) { | 5652 | if (link_up && SINGLE_MEDIA_DIRECT(params)) { |
5462 | u16 pd, gp_status4; | 5653 | u16 pd, gp_status4; |
5463 | if (phy->req_line_speed == SPEED_AUTO_NEG) { | 5654 | if (phy->req_line_speed == SPEED_AUTO_NEG) { |
@@ -5522,7 +5713,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | |||
5522 | if ((lane & 1) == 0) | 5713 | if ((lane & 1) == 0) |
5523 | gp_speed <<= 8; | 5714 | gp_speed <<= 8; |
5524 | gp_speed &= 0x3f00; | 5715 | gp_speed &= 0x3f00; |
5525 | 5716 | link_up = !!link_up; | |
5526 | 5717 | ||
5527 | rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed, | 5718 | rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed, |
5528 | duplex); | 5719 | duplex); |
@@ -11564,9 +11755,11 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, | |||
11564 | phy->media_type = ETH_PHY_KR; | 11755 | phy->media_type = ETH_PHY_KR; |
11565 | phy->flags |= FLAGS_WC_DUAL_MODE; | 11756 | phy->flags |= FLAGS_WC_DUAL_MODE; |
11566 | phy->supported &= (SUPPORTED_20000baseKR2_Full | | 11757 | phy->supported &= (SUPPORTED_20000baseKR2_Full | |
11758 | SUPPORTED_Autoneg | | ||
11567 | SUPPORTED_FIBRE | | 11759 | SUPPORTED_FIBRE | |
11568 | SUPPORTED_Pause | | 11760 | SUPPORTED_Pause | |
11569 | SUPPORTED_Asym_Pause); | 11761 | SUPPORTED_Asym_Pause); |
11762 | phy->flags &= ~FLAGS_TX_ERROR_CHECK; | ||
11570 | break; | 11763 | break; |
11571 | default: | 11764 | default: |
11572 | DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n", | 11765 | DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n", |
@@ -12018,13 +12211,17 @@ static void bnx2x_init_xgxs_loopback(struct link_params *params, | |||
12018 | struct link_vars *vars) | 12211 | struct link_vars *vars) |
12019 | { | 12212 | { |
12020 | struct bnx2x *bp = params->bp; | 12213 | struct bnx2x *bp = params->bp; |
12214 | struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; | ||
12021 | vars->link_up = 1; | 12215 | vars->link_up = 1; |
12022 | vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; | 12216 | vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; |
12023 | vars->duplex = DUPLEX_FULL; | 12217 | vars->duplex = DUPLEX_FULL; |
12024 | if (params->req_line_speed[0] == SPEED_1000) | 12218 | if (params->req_line_speed[0] == SPEED_1000) |
12025 | vars->line_speed = SPEED_1000; | 12219 | vars->line_speed = SPEED_1000; |
12220 | else if ((params->req_line_speed[0] == SPEED_20000) || | ||
12221 | (int_phy->flags & FLAGS_WC_DUAL_MODE)) | ||
12222 | vars->line_speed = SPEED_20000; | ||
12026 | else | 12223 | else |
12027 | vars->line_speed = SPEED_10000; | 12224 | vars->line_speed = SPEED_10000; |
12028 | 12225 | ||
12029 | if (!USES_WARPCORE(bp)) | 12226 | if (!USES_WARPCORE(bp)) |
12030 | bnx2x_xgxs_deassert(params); | 12227 | bnx2x_xgxs_deassert(params); |
@@ -13139,6 +13336,108 @@ static void bnx2x_sfp_tx_fault_detection(struct bnx2x_phy *phy, | |||
13139 | } | 13336 | } |
13140 | } | 13337 | } |
13141 | } | 13338 | } |
13339 | static void bnx2x_disable_kr2(struct link_params *params, | ||
13340 | struct link_vars *vars, | ||
13341 | struct bnx2x_phy *phy) | ||
13342 | { | ||
13343 | struct bnx2x *bp = params->bp; | ||
13344 | int i; | ||
13345 | static struct bnx2x_reg_set reg_set[] = { | ||
13346 | /* Step 1 - Program the TX/RX alignment markers */ | ||
13347 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL5, 0x7690}, | ||
13348 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL7, 0xe647}, | ||
13349 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL6, 0xc4f0}, | ||
13350 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_TX_CTRL9, 0x7690}, | ||
13351 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL11, 0xe647}, | ||
13352 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL82_USERB1_RX_CTRL10, 0xc4f0}, | ||
13353 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_USERB0_CTRL, 0x000c}, | ||
13354 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL1, 0x6000}, | ||
13355 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CTRL3, 0x0000}, | ||
13356 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL73_BAM_CODE_FIELD, 0x0002}, | ||
13357 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI1, 0x0000}, | ||
13358 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI2, 0x0af7}, | ||
13359 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_OUI3, 0x0af7}, | ||
13360 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_BAM_CODE, 0x0002}, | ||
13361 | {MDIO_WC_DEVAD, MDIO_WC_REG_ETA_CL73_LD_UD_CODE, 0x0000} | ||
13362 | }; | ||
13363 | DP(NETIF_MSG_LINK, "Disabling 20G-KR2\n"); | ||
13364 | |||
13365 | for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++) | ||
13366 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, | ||
13367 | reg_set[i].val); | ||
13368 | vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; | ||
13369 | bnx2x_update_link_attr(params, vars->link_attr_sync); | ||
13370 | |||
13371 | /* Restart AN on leading lane */ | ||
13372 | bnx2x_warpcore_restart_AN_KR(phy, params); | ||
13373 | } | ||
13374 | |||
13375 | static void bnx2x_kr2_recovery(struct link_params *params, | ||
13376 | struct link_vars *vars, | ||
13377 | struct bnx2x_phy *phy) | ||
13378 | { | ||
13379 | struct bnx2x *bp = params->bp; | ||
13380 | DP(NETIF_MSG_LINK, "KR2 recovery\n"); | ||
13381 | bnx2x_warpcore_enable_AN_KR2(phy, params, vars); | ||
13382 | bnx2x_warpcore_restart_AN_KR(phy, params); | ||
13383 | } | ||
13384 | |||
13385 | static void bnx2x_check_kr2_wa(struct link_params *params, | ||
13386 | struct link_vars *vars, | ||
13387 | struct bnx2x_phy *phy) | ||
13388 | { | ||
13389 | struct bnx2x *bp = params->bp; | ||
13390 | u16 base_page, next_page, not_kr2_device, lane; | ||
13391 | int sigdet = bnx2x_warpcore_get_sigdet(phy, params); | ||
13392 | |||
13393 | if (!sigdet) { | ||
13394 | if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) | ||
13395 | bnx2x_kr2_recovery(params, vars, phy); | ||
13396 | return; | ||
13397 | } | ||
13398 | |||
13399 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
13400 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
13401 | MDIO_AER_BLOCK_AER_REG, lane); | ||
13402 | bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, | ||
13403 | MDIO_AN_REG_LP_AUTO_NEG, &base_page); | ||
13404 | bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, | ||
13405 | MDIO_AN_REG_LP_AUTO_NEG2, &next_page); | ||
13406 | bnx2x_set_aer_mmd(params, phy); | ||
13407 | |||
13408 | /* CL73 has not begun yet */ | ||
13409 | if (base_page == 0) { | ||
13410 | if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) | ||
13411 | bnx2x_kr2_recovery(params, vars, phy); | ||
13412 | return; | ||
13413 | } | ||
13414 | |||
13415 | /* In case NP bit is not set in the BasePage, or it is set, | ||
13416 | * but only KX is advertised, declare this link partner as non-KR2 | ||
13417 | * device. | ||
13418 | */ | ||
13419 | not_kr2_device = (((base_page & 0x8000) == 0) || | ||
13420 | (((base_page & 0x8000) && | ||
13421 | ((next_page & 0xe0) == 0x2)))); | ||
13422 | |||
13423 | /* In case KR2 is already disabled, check if we need to re-enable it */ | ||
13424 | if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) { | ||
13425 | if (!not_kr2_device) { | ||
13426 | DP(NETIF_MSG_LINK, "BP=0x%x, NP=0x%x\n", base_page, | ||
13427 | next_page); | ||
13428 | bnx2x_kr2_recovery(params, vars, phy); | ||
13429 | } | ||
13430 | return; | ||
13431 | } | ||
13432 | /* KR2 is enabled, but not KR2 device */ | ||
13433 | if (not_kr2_device) { | ||
13434 | /* Disable KR2 on both lanes */ | ||
13435 | DP(NETIF_MSG_LINK, "BP=0x%x, NP=0x%x\n", base_page, next_page); | ||
13436 | bnx2x_disable_kr2(params, vars, phy); | ||
13437 | return; | ||
13438 | } | ||
13439 | } | ||
13440 | |||
13142 | void bnx2x_period_func(struct link_params *params, struct link_vars *vars) | 13441 | void bnx2x_period_func(struct link_params *params, struct link_vars *vars) |
13143 | { | 13442 | { |
13144 | u16 phy_idx; | 13443 | u16 phy_idx; |
@@ -13156,6 +13455,9 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars) | |||
13156 | if (CHIP_IS_E3(bp)) { | 13455 | if (CHIP_IS_E3(bp)) { |
13157 | struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; | 13456 | struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; |
13158 | bnx2x_set_aer_mmd(params, phy); | 13457 | bnx2x_set_aer_mmd(params, phy); |
13458 | if ((phy->supported & SUPPORTED_20000baseKR2_Full) && | ||
13459 | (phy->speed_cap_mask & SPEED_20000)) | ||
13460 | bnx2x_check_kr2_wa(params, vars, phy); | ||
13159 | bnx2x_check_over_curr(params, vars); | 13461 | bnx2x_check_over_curr(params, vars); |
13160 | if (vars->rx_tx_asic_rst) | 13462 | if (vars->rx_tx_asic_rst) |
13161 | bnx2x_warpcore_config_runtime(phy, params, vars); | 13463 | bnx2x_warpcore_config_runtime(phy, params, vars); |