aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2012-11-26 22:46:32 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-28 10:59:21 -0500
commit0f6bb03dd011a1fc1e9373efe3fe6f2cdc46f7a9 (patch)
tree761cab87d1dba926ade9951096f6a81bb3eb8c72 /drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
parent5a1fbf4046ea05b20811178cb1423e27e3260051 (diff)
bnx2x: Add support for BCM84834
Add support for the 10G-baseT PHY - BCM84834, which is the quad-port version of the dual-port BCM84833. 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.c81
1 files changed, 65 insertions, 16 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index a5fe2b96bf9f..f5a310ed61c7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -9519,7 +9519,8 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
9519{ 9519{
9520 u16 val, fw_ver1, fw_ver2, cnt; 9520 u16 val, fw_ver1, fw_ver2, cnt;
9521 9521
9522 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { 9522 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
9523 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
9523 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1); 9524 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
9524 bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff, 9525 bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff,
9525 phy->ver_addr); 9526 phy->ver_addr);
@@ -9619,7 +9620,8 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp,
9619 MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH, 9620 MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
9620 MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ); 9621 MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ);
9621 9622
9622 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) 9623 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
9624 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834))
9623 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1; 9625 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
9624 else 9626 else
9625 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1; 9627 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
@@ -9643,7 +9645,8 @@ static void bnx2x_848xx_specific_func(struct bnx2x_phy *phy,
9643 struct bnx2x *bp = params->bp; 9645 struct bnx2x *bp = params->bp;
9644 switch (action) { 9646 switch (action) {
9645 case PHY_INIT: 9647 case PHY_INIT:
9646 if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { 9648 if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
9649 (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
9647 /* Save spirom version */ 9650 /* Save spirom version */
9648 bnx2x_save_848xx_spirom_version(phy, bp, params->port); 9651 bnx2x_save_848xx_spirom_version(phy, bp, params->port);
9649 } 9652 }
@@ -9763,10 +9766,11 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9763 if (phy->req_duplex == DUPLEX_FULL) 9766 if (phy->req_duplex == DUPLEX_FULL)
9764 autoneg_val |= (1<<8); 9767 autoneg_val |= (1<<8);
9765 9768
9766 /* Always write this if this is not 84833. 9769 /* Always write this if this is not 84833/4.
9767 * For 84833, write it only when it's a forced speed. 9770 * For 84833/4, write it only when it's a forced speed.
9768 */ 9771 */
9769 if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) || 9772 if (((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
9773 (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) ||
9770 ((autoneg_val & (1<<12)) == 0)) 9774 ((autoneg_val & (1<<12)) == 0))
9771 bnx2x_cl45_write(bp, phy, 9775 bnx2x_cl45_write(bp, phy,
9772 MDIO_AN_DEVAD, 9776 MDIO_AN_DEVAD,
@@ -10049,7 +10053,8 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
10049 10053
10050 /* Wait for GPHY to come out of reset */ 10054 /* Wait for GPHY to come out of reset */
10051 msleep(50); 10055 msleep(50);
10052 if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { 10056 if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
10057 (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
10053 /* BCM84823 requires that XGXS links up first @ 10G for normal 10058 /* BCM84823 requires that XGXS links up first @ 10G for normal
10054 * behavior. 10059 * behavior.
10055 */ 10060 */
@@ -10105,7 +10110,8 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
10105 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", 10110 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
10106 params->multi_phy_config, val); 10111 params->multi_phy_config, val);
10107 10112
10108 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { 10113 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
10114 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
10109 bnx2x_84833_pair_swap_cfg(phy, params, vars); 10115 bnx2x_84833_pair_swap_cfg(phy, params, vars);
10110 10116
10111 /* Keep AutogrEEEn disabled. */ 10117 /* Keep AutogrEEEn disabled. */
@@ -10169,7 +10175,8 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
10169 vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK; 10175 vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
10170 } 10176 }
10171 10177
10172 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { 10178 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
10179 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) {
10173 /* Bring PHY out of super isolate mode as the final step. */ 10180 /* Bring PHY out of super isolate mode as the final step. */
10174 bnx2x_cl45_read(bp, phy, 10181 bnx2x_cl45_read(bp, phy,
10175 MDIO_CTL_DEVAD, 10182 MDIO_CTL_DEVAD,
@@ -11607,6 +11614,40 @@ static struct bnx2x_phy phy_84833 = {
11607 .phy_specific_func = (phy_specific_func_t)bnx2x_848xx_specific_func 11614 .phy_specific_func = (phy_specific_func_t)bnx2x_848xx_specific_func
11608}; 11615};
11609 11616
11617static const struct bnx2x_phy phy_84834 = {
11618 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834,
11619 .addr = 0xff,
11620 .def_md_devad = 0,
11621 .flags = FLAGS_FAN_FAILURE_DET_REQ |
11622 FLAGS_REARM_LATCH_SIGNAL,
11623 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11624 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11625 .mdio_ctrl = 0,
11626 .supported = (SUPPORTED_100baseT_Half |
11627 SUPPORTED_100baseT_Full |
11628 SUPPORTED_1000baseT_Full |
11629 SUPPORTED_10000baseT_Full |
11630 SUPPORTED_TP |
11631 SUPPORTED_Autoneg |
11632 SUPPORTED_Pause |
11633 SUPPORTED_Asym_Pause),
11634 .media_type = ETH_PHY_BASE_T,
11635 .ver_addr = 0,
11636 .req_flow_ctrl = 0,
11637 .req_line_speed = 0,
11638 .speed_cap_mask = 0,
11639 .req_duplex = 0,
11640 .rsrv = 0,
11641 .config_init = (config_init_t)bnx2x_848x3_config_init,
11642 .read_status = (read_status_t)bnx2x_848xx_read_status,
11643 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
11644 .config_loopback = (config_loopback_t)NULL,
11645 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
11646 .hw_reset = (hw_reset_t)bnx2x_84833_hw_reset_phy,
11647 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
11648 .phy_specific_func = (phy_specific_func_t)bnx2x_848xx_specific_func
11649};
11650
11610static struct bnx2x_phy phy_54618se = { 11651static struct bnx2x_phy phy_54618se = {
11611 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE, 11652 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
11612 .addr = 0xff, 11653 .addr = 0xff,
@@ -11888,6 +11929,9 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp,
11888 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: 11929 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
11889 *phy = phy_84833; 11930 *phy = phy_84833;
11890 break; 11931 break;
11932 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834:
11933 *phy = phy_84834;
11934 break;
11891 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616: 11935 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
11892 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE: 11936 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
11893 *phy = phy_54618se; 11937 *phy = phy_54618se;
@@ -11944,9 +11988,10 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp,
11944 } 11988 }
11945 phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); 11989 phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
11946 11990
11947 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) && 11991 if (((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
11992 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834)) &&
11948 (phy->ver_addr)) { 11993 (phy->ver_addr)) {
11949 /* Remove 100Mb link supported for BCM84833 when phy fw 11994 /* Remove 100Mb link supported for BCM84833/4 when phy fw
11950 * version lower than or equal to 1.39 11995 * version lower than or equal to 1.39
11951 */ 11996 */
11952 u32 raw_ver = REG_RD(bp, phy->ver_addr); 11997 u32 raw_ver = REG_RD(bp, phy->ver_addr);
@@ -13015,7 +13060,8 @@ static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
13015} 13060}
13016 13061
13017static int bnx2x_84833_pre_init_phy(struct bnx2x *bp, 13062static int bnx2x_84833_pre_init_phy(struct bnx2x *bp,
13018 struct bnx2x_phy *phy) 13063 struct bnx2x_phy *phy,
13064 u8 port)
13019{ 13065{
13020 u16 val, cnt; 13066 u16 val, cnt;
13021 /* Wait for FW completing its initialization. */ 13067 /* Wait for FW completing its initialization. */
@@ -13042,26 +13088,28 @@ static int bnx2x_84833_pre_init_phy(struct bnx2x *bp,
13042 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); 13088 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
13043 13089
13044 /* Save spirom version */ 13090 /* Save spirom version */
13045 bnx2x_save_848xx_spirom_version(phy, bp, PORT_0); 13091 bnx2x_save_848xx_spirom_version(phy, bp, port);
13046 return 0; 13092 return 0;
13047} 13093}
13048 13094
13049int bnx2x_pre_init_phy(struct bnx2x *bp, 13095int bnx2x_pre_init_phy(struct bnx2x *bp,
13050 u32 shmem_base, 13096 u32 shmem_base,
13051 u32 shmem2_base, 13097 u32 shmem2_base,
13052 u32 chip_id) 13098 u32 chip_id,
13099 u8 port)
13053{ 13100{
13054 int rc = 0; 13101 int rc = 0;
13055 struct bnx2x_phy phy; 13102 struct bnx2x_phy phy;
13056 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base, 13103 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base,
13057 PORT_0, &phy)) { 13104 port, &phy) != 0) {
13058 DP(NETIF_MSG_LINK, "populate_phy failed\n"); 13105 DP(NETIF_MSG_LINK, "populate_phy failed\n");
13059 return -EINVAL; 13106 return -EINVAL;
13060 } 13107 }
13061 bnx2x_set_mdio_clk(bp, chip_id, phy.mdio_ctrl); 13108 bnx2x_set_mdio_clk(bp, chip_id, phy.mdio_ctrl);
13062 switch (phy.type) { 13109 switch (phy.type) {
13063 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: 13110 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
13064 rc = bnx2x_84833_pre_init_phy(bp, &phy); 13111 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834:
13112 rc = bnx2x_84833_pre_init_phy(bp, &phy, port);
13065 break; 13113 break;
13066 default: 13114 default:
13067 break; 13115 break;
@@ -13098,6 +13146,7 @@ static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
13098 phy_index, chip_id); 13146 phy_index, chip_id);
13099 break; 13147 break;
13100 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: 13148 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
13149 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834:
13101 /* GPIO3's are linked, and so both need to be toggled 13150 /* GPIO3's are linked, and so both need to be toggled
13102 * to obtain required 2us pulse. 13151 * to obtain required 2us pulse.
13103 */ 13152 */