diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2012-11-26 22:46:32 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-28 10:59:21 -0500 |
commit | 0f6bb03dd011a1fc1e9373efe3fe6f2cdc46f7a9 (patch) | |
tree | 761cab87d1dba926ade9951096f6a81bb3eb8c72 /drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |
parent | 5a1fbf4046ea05b20811178cb1423e27e3260051 (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.c | 81 |
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 | ||
11617 | static 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 | |||
11610 | static struct bnx2x_phy phy_54618se = { | 11651 | static 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 | ||
13017 | static int bnx2x_84833_pre_init_phy(struct bnx2x *bp, | 13062 | static 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 | ||
13049 | int bnx2x_pre_init_phy(struct bnx2x *bp, | 13095 | int 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 | */ |