diff options
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 173 |
1 files changed, 139 insertions, 34 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 43b0de24f391..7160ec51093e 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
@@ -1573,7 +1573,7 @@ static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, | |||
1573 | 1573 | ||
1574 | offset = phy->addr + ser_lane; | 1574 | offset = phy->addr + ser_lane; |
1575 | if (CHIP_IS_E2(bp)) | 1575 | if (CHIP_IS_E2(bp)) |
1576 | aer_val = 0x2800 + offset - 1; | 1576 | aer_val = 0x3800 + offset - 1; |
1577 | else | 1577 | else |
1578 | aer_val = 0x3800 + offset; | 1578 | aer_val = 0x3800 + offset; |
1579 | CL45_WR_OVER_CL22(bp, phy, | 1579 | CL45_WR_OVER_CL22(bp, phy, |
@@ -3166,7 +3166,23 @@ u8 bnx2x_set_led(struct link_params *params, | |||
3166 | if (!vars->link_up) | 3166 | if (!vars->link_up) |
3167 | break; | 3167 | break; |
3168 | case LED_MODE_ON: | 3168 | case LED_MODE_ON: |
3169 | if (SINGLE_MEDIA_DIRECT(params)) { | 3169 | if (params->phy[EXT_PHY1].type == |
3170 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 && | ||
3171 | CHIP_IS_E2(bp) && params->num_phys == 2) { | ||
3172 | /** | ||
3173 | * This is a work-around for E2+8727 Configurations | ||
3174 | */ | ||
3175 | if (mode == LED_MODE_ON || | ||
3176 | speed == SPEED_10000){ | ||
3177 | REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); | ||
3178 | REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); | ||
3179 | |||
3180 | tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); | ||
3181 | EMAC_WR(bp, EMAC_REG_EMAC_LED, | ||
3182 | (tmp | EMAC_LED_OVERRIDE)); | ||
3183 | return rc; | ||
3184 | } | ||
3185 | } else if (SINGLE_MEDIA_DIRECT(params)) { | ||
3170 | /** | 3186 | /** |
3171 | * This is a work-around for HW issue found when link | 3187 | * This is a work-around for HW issue found when link |
3172 | * is up in CL73 | 3188 | * is up in CL73 |
@@ -3854,11 +3870,14 @@ static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, | |||
3854 | pause_result); | 3870 | pause_result); |
3855 | } | 3871 | } |
3856 | } | 3872 | } |
3857 | 3873 | static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, | |
3858 | static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, | ||
3859 | struct bnx2x_phy *phy, | 3874 | struct bnx2x_phy *phy, |
3860 | u8 port) | 3875 | u8 port) |
3861 | { | 3876 | { |
3877 | u32 count = 0; | ||
3878 | u16 fw_ver1, fw_msgout; | ||
3879 | u8 rc = 0; | ||
3880 | |||
3862 | /* Boot port from external ROM */ | 3881 | /* Boot port from external ROM */ |
3863 | /* EDC grst */ | 3882 | /* EDC grst */ |
3864 | bnx2x_cl45_write(bp, phy, | 3883 | bnx2x_cl45_write(bp, phy, |
@@ -3888,14 +3907,45 @@ static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, | |||
3888 | MDIO_PMA_REG_GEN_CTRL, | 3907 | MDIO_PMA_REG_GEN_CTRL, |
3889 | MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); | 3908 | MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); |
3890 | 3909 | ||
3891 | /* wait for 120ms for code download via SPI port */ | 3910 | /* Delay 100ms per the PHY specifications */ |
3892 | msleep(120); | 3911 | msleep(100); |
3912 | |||
3913 | /* 8073 sometimes taking longer to download */ | ||
3914 | do { | ||
3915 | count++; | ||
3916 | if (count > 300) { | ||
3917 | DP(NETIF_MSG_LINK, | ||
3918 | "bnx2x_8073_8727_external_rom_boot port %x:" | ||
3919 | "Download failed. fw version = 0x%x\n", | ||
3920 | port, fw_ver1); | ||
3921 | rc = -EINVAL; | ||
3922 | break; | ||
3923 | } | ||
3924 | |||
3925 | bnx2x_cl45_read(bp, phy, | ||
3926 | MDIO_PMA_DEVAD, | ||
3927 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | ||
3928 | bnx2x_cl45_read(bp, phy, | ||
3929 | MDIO_PMA_DEVAD, | ||
3930 | MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout); | ||
3931 | |||
3932 | msleep(1); | ||
3933 | } while (fw_ver1 == 0 || fw_ver1 == 0x4321 || | ||
3934 | ((fw_msgout & 0xff) != 0x03 && (phy->type == | ||
3935 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))); | ||
3893 | 3936 | ||
3894 | /* Clear ser_boot_ctl bit */ | 3937 | /* Clear ser_boot_ctl bit */ |
3895 | bnx2x_cl45_write(bp, phy, | 3938 | bnx2x_cl45_write(bp, phy, |
3896 | MDIO_PMA_DEVAD, | 3939 | MDIO_PMA_DEVAD, |
3897 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 3940 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
3898 | bnx2x_save_bcm_spirom_ver(bp, phy, port); | 3941 | bnx2x_save_bcm_spirom_ver(bp, phy, port); |
3942 | |||
3943 | DP(NETIF_MSG_LINK, | ||
3944 | "bnx2x_8073_8727_external_rom_boot port %x:" | ||
3945 | "Download complete. fw version = 0x%x\n", | ||
3946 | port, fw_ver1); | ||
3947 | |||
3948 | return rc; | ||
3899 | } | 3949 | } |
3900 | 3950 | ||
3901 | static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, | 3951 | static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, |
@@ -4108,6 +4158,25 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, | |||
4108 | 4158 | ||
4109 | DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); | 4159 | DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); |
4110 | 4160 | ||
4161 | /** | ||
4162 | * If this is forced speed, set to KR or KX (all other are not | ||
4163 | * supported) | ||
4164 | */ | ||
4165 | /* Swap polarity if required - Must be done only in non-1G mode */ | ||
4166 | if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) { | ||
4167 | /* Configure the 8073 to swap _P and _N of the KR lines */ | ||
4168 | DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n"); | ||
4169 | /* 10G Rx/Tx and 1G Tx signal polarity swap */ | ||
4170 | bnx2x_cl45_read(bp, phy, | ||
4171 | MDIO_PMA_DEVAD, | ||
4172 | MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val); | ||
4173 | bnx2x_cl45_write(bp, phy, | ||
4174 | MDIO_PMA_DEVAD, | ||
4175 | MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, | ||
4176 | (val | (3<<9))); | ||
4177 | } | ||
4178 | |||
4179 | |||
4111 | /* Enable CL37 BAM */ | 4180 | /* Enable CL37 BAM */ |
4112 | if (REG_RD(bp, params->shmem_base + | 4181 | if (REG_RD(bp, params->shmem_base + |
4113 | offsetof(struct shmem_region, dev_info. | 4182 | offsetof(struct shmem_region, dev_info. |
@@ -4314,8 +4383,32 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, | |||
4314 | } | 4383 | } |
4315 | 4384 | ||
4316 | if (link_up) { | 4385 | if (link_up) { |
4386 | /* Swap polarity if required */ | ||
4387 | if (params->lane_config & | ||
4388 | PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) { | ||
4389 | /* Configure the 8073 to swap P and N of the KR lines */ | ||
4390 | bnx2x_cl45_read(bp, phy, | ||
4391 | MDIO_XS_DEVAD, | ||
4392 | MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1); | ||
4393 | /** | ||
4394 | * Set bit 3 to invert Rx in 1G mode and clear this bit | ||
4395 | * when it`s in 10G mode. | ||
4396 | */ | ||
4397 | if (vars->line_speed == SPEED_1000) { | ||
4398 | DP(NETIF_MSG_LINK, "Swapping 1G polarity for" | ||
4399 | "the 8073\n"); | ||
4400 | val1 |= (1<<3); | ||
4401 | } else | ||
4402 | val1 &= ~(1<<3); | ||
4403 | |||
4404 | bnx2x_cl45_write(bp, phy, | ||
4405 | MDIO_XS_DEVAD, | ||
4406 | MDIO_XS_REG_8073_RX_CTRL_PCIE, | ||
4407 | val1); | ||
4408 | } | ||
4317 | bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); | 4409 | bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); |
4318 | bnx2x_8073_resolve_fc(phy, params, vars); | 4410 | bnx2x_8073_resolve_fc(phy, params, vars); |
4411 | vars->duplex = DUPLEX_FULL; | ||
4319 | } | 4412 | } |
4320 | return link_up; | 4413 | return link_up; |
4321 | } | 4414 | } |
@@ -5062,6 +5155,7 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, | |||
5062 | else | 5155 | else |
5063 | vars->line_speed = SPEED_10000; | 5156 | vars->line_speed = SPEED_10000; |
5064 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5157 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5158 | vars->duplex = DUPLEX_FULL; | ||
5065 | } | 5159 | } |
5066 | return link_up; | 5160 | return link_up; |
5067 | } | 5161 | } |
@@ -5758,8 +5852,11 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, | |||
5758 | DP(NETIF_MSG_LINK, "port %x: External link is down\n", | 5852 | DP(NETIF_MSG_LINK, "port %x: External link is down\n", |
5759 | params->port); | 5853 | params->port); |
5760 | } | 5854 | } |
5761 | if (link_up) | 5855 | if (link_up) { |
5762 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5856 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5857 | vars->duplex = DUPLEX_FULL; | ||
5858 | DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex); | ||
5859 | } | ||
5763 | 5860 | ||
5764 | if ((DUAL_MEDIA(params)) && | 5861 | if ((DUAL_MEDIA(params)) && |
5765 | (phy->req_line_speed == SPEED_1000)) { | 5862 | (phy->req_line_speed == SPEED_1000)) { |
@@ -5875,10 +5972,26 @@ static void bnx2x_848xx_set_led(struct bnx2x *bp, | |||
5875 | MDIO_PMA_REG_8481_LED2_MASK, | 5972 | MDIO_PMA_REG_8481_LED2_MASK, |
5876 | 0x18); | 5973 | 0x18); |
5877 | 5974 | ||
5975 | /* Select activity source by Tx and Rx, as suggested by PHY AE */ | ||
5878 | bnx2x_cl45_write(bp, phy, | 5976 | bnx2x_cl45_write(bp, phy, |
5879 | MDIO_PMA_DEVAD, | 5977 | MDIO_PMA_DEVAD, |
5880 | MDIO_PMA_REG_8481_LED3_MASK, | 5978 | MDIO_PMA_REG_8481_LED3_MASK, |
5881 | 0x0040); | 5979 | 0x0006); |
5980 | |||
5981 | /* Select the closest activity blink rate to that in 10/100/1000 */ | ||
5982 | bnx2x_cl45_write(bp, phy, | ||
5983 | MDIO_PMA_DEVAD, | ||
5984 | MDIO_PMA_REG_8481_LED3_BLINK, | ||
5985 | 0); | ||
5986 | |||
5987 | bnx2x_cl45_read(bp, phy, | ||
5988 | MDIO_PMA_DEVAD, | ||
5989 | MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val); | ||
5990 | val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/ | ||
5991 | |||
5992 | bnx2x_cl45_write(bp, phy, | ||
5993 | MDIO_PMA_DEVAD, | ||
5994 | MDIO_PMA_REG_84823_CTL_LED_CTL_1, val); | ||
5882 | 5995 | ||
5883 | /* 'Interrupt Mask' */ | 5996 | /* 'Interrupt Mask' */ |
5884 | bnx2x_cl45_write(bp, phy, | 5997 | bnx2x_cl45_write(bp, phy, |
@@ -6126,6 +6239,7 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, | |||
6126 | /* Check link 10G */ | 6239 | /* Check link 10G */ |
6127 | if (val2 & (1<<11)) { | 6240 | if (val2 & (1<<11)) { |
6128 | vars->line_speed = SPEED_10000; | 6241 | vars->line_speed = SPEED_10000; |
6242 | vars->duplex = DUPLEX_FULL; | ||
6129 | link_up = 1; | 6243 | link_up = 1; |
6130 | bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); | 6244 | bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); |
6131 | } else { /* Check Legacy speed link */ | 6245 | } else { /* Check Legacy speed link */ |
@@ -6489,6 +6603,7 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, | |||
6489 | MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, | 6603 | MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, |
6490 | &val2); | 6604 | &val2); |
6491 | vars->line_speed = SPEED_10000; | 6605 | vars->line_speed = SPEED_10000; |
6606 | vars->duplex = DUPLEX_FULL; | ||
6492 | DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", | 6607 | DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", |
6493 | val2, (val2 & (1<<14))); | 6608 | val2, (val2 & (1<<14))); |
6494 | bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); | 6609 | bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); |
@@ -7663,7 +7778,6 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
7663 | 7778 | ||
7664 | /* PART2 - Download firmware to both phys */ | 7779 | /* PART2 - Download firmware to both phys */ |
7665 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 7780 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
7666 | u16 fw_ver1; | ||
7667 | if (CHIP_IS_E2(bp)) | 7781 | if (CHIP_IS_E2(bp)) |
7668 | port_of_path = 0; | 7782 | port_of_path = 0; |
7669 | else | 7783 | else |
@@ -7671,19 +7785,9 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
7671 | 7785 | ||
7672 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", | 7786 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", |
7673 | phy_blk[port]->addr); | 7787 | phy_blk[port]->addr); |
7674 | bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], | 7788 | if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], |
7675 | port_of_path); | 7789 | port_of_path)) |
7676 | |||
7677 | bnx2x_cl45_read(bp, phy_blk[port], | ||
7678 | MDIO_PMA_DEVAD, | ||
7679 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | ||
7680 | if (fw_ver1 == 0 || fw_ver1 == 0x4321) { | ||
7681 | DP(NETIF_MSG_LINK, | ||
7682 | "bnx2x_8073_common_init_phy port %x:" | ||
7683 | "Download failed. fw version = 0x%x\n", | ||
7684 | port, fw_ver1); | ||
7685 | return -EINVAL; | 7790 | return -EINVAL; |
7686 | } | ||
7687 | 7791 | ||
7688 | /* Only set bit 10 = 1 (Tx power down) */ | 7792 | /* Only set bit 10 = 1 (Tx power down) */ |
7689 | bnx2x_cl45_read(bp, phy_blk[port], | 7793 | bnx2x_cl45_read(bp, phy_blk[port], |
@@ -7848,27 +7952,17 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, | |||
7848 | } | 7952 | } |
7849 | /* PART2 - Download firmware to both phys */ | 7953 | /* PART2 - Download firmware to both phys */ |
7850 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 7954 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
7851 | u16 fw_ver1; | ||
7852 | if (CHIP_IS_E2(bp)) | 7955 | if (CHIP_IS_E2(bp)) |
7853 | port_of_path = 0; | 7956 | port_of_path = 0; |
7854 | else | 7957 | else |
7855 | port_of_path = port; | 7958 | port_of_path = port; |
7856 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", | 7959 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", |
7857 | phy_blk[port]->addr); | 7960 | phy_blk[port]->addr); |
7858 | bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], | 7961 | if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], |
7859 | port_of_path); | 7962 | port_of_path)) |
7860 | bnx2x_cl45_read(bp, phy_blk[port], | ||
7861 | MDIO_PMA_DEVAD, | ||
7862 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | ||
7863 | if (fw_ver1 == 0 || fw_ver1 == 0x4321) { | ||
7864 | DP(NETIF_MSG_LINK, | ||
7865 | "bnx2x_8727_common_init_phy port %x:" | ||
7866 | "Download failed. fw version = 0x%x\n", | ||
7867 | port, fw_ver1); | ||
7868 | return -EINVAL; | 7963 | return -EINVAL; |
7869 | } | ||
7870 | } | ||
7871 | 7964 | ||
7965 | } | ||
7872 | return 0; | 7966 | return 0; |
7873 | } | 7967 | } |
7874 | 7968 | ||
@@ -7916,6 +8010,7 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], | |||
7916 | u32 shmem2_base_path[], u32 chip_id) | 8010 | u32 shmem2_base_path[], u32 chip_id) |
7917 | { | 8011 | { |
7918 | u8 rc = 0; | 8012 | u8 rc = 0; |
8013 | u32 phy_ver; | ||
7919 | u8 phy_index; | 8014 | u8 phy_index; |
7920 | u32 ext_phy_type, ext_phy_config; | 8015 | u32 ext_phy_type, ext_phy_config; |
7921 | DP(NETIF_MSG_LINK, "Begin common phy init\n"); | 8016 | DP(NETIF_MSG_LINK, "Begin common phy init\n"); |
@@ -7923,6 +8018,16 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], | |||
7923 | if (CHIP_REV_IS_EMUL(bp)) | 8018 | if (CHIP_REV_IS_EMUL(bp)) |
7924 | return 0; | 8019 | return 0; |
7925 | 8020 | ||
8021 | /* Check if common init was already done */ | ||
8022 | phy_ver = REG_RD(bp, shmem_base_path[0] + | ||
8023 | offsetof(struct shmem_region, | ||
8024 | port_mb[PORT_0].ext_phy_fw_version)); | ||
8025 | if (phy_ver) { | ||
8026 | DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n", | ||
8027 | phy_ver); | ||
8028 | return 0; | ||
8029 | } | ||
8030 | |||
7926 | /* Read the ext_phy_type for arbitrary port(0) */ | 8031 | /* Read the ext_phy_type for arbitrary port(0) */ |
7927 | for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; | 8032 | for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; |
7928 | phy_index++) { | 8033 | phy_index++) { |