aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_link.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c173
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 3873static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
3858static 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
3901static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, 3951static 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++) {