diff options
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 250 |
1 files changed, 137 insertions, 113 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 4df9505b67b..3b184c2a855 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -9266,62 +9266,68 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, | |||
9266 | /* BCM8481/BCM84823/BCM84833 PHY SECTION */ | 9266 | /* BCM8481/BCM84823/BCM84833 PHY SECTION */ |
9267 | /******************************************************************/ | 9267 | /******************************************************************/ |
9268 | static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, | 9268 | static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, |
9269 | struct link_params *params) | 9269 | struct bnx2x *bp, |
9270 | u8 port) | ||
9270 | { | 9271 | { |
9271 | u16 val, fw_ver1, fw_ver2, cnt; | 9272 | u16 val, fw_ver1, fw_ver2, cnt; |
9272 | u8 port; | ||
9273 | struct bnx2x *bp = params->bp; | ||
9274 | 9273 | ||
9275 | port = params->port; | 9274 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { |
9275 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1); | ||
9276 | bnx2x_save_spirom_version(bp, port, | ||
9277 | ((fw_ver1 & 0xf000)>>5) | (fw_ver1 & 0x7f), | ||
9278 | phy->ver_addr); | ||
9279 | } else { | ||
9280 | /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */ | ||
9281 | /* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ | ||
9282 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); | ||
9283 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); | ||
9284 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); | ||
9285 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); | ||
9286 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); | ||
9287 | |||
9288 | for (cnt = 0; cnt < 100; cnt++) { | ||
9289 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); | ||
9290 | if (val & 1) | ||
9291 | break; | ||
9292 | udelay(5); | ||
9293 | } | ||
9294 | if (cnt == 100) { | ||
9295 | DP(NETIF_MSG_LINK, "Unable to read 848xx " | ||
9296 | "phy fw version(1)\n"); | ||
9297 | bnx2x_save_spirom_version(bp, port, 0, | ||
9298 | phy->ver_addr); | ||
9299 | return; | ||
9300 | } | ||
9276 | 9301 | ||
9277 | /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ | ||
9278 | /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ | ||
9279 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); | ||
9280 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); | ||
9281 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); | ||
9282 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); | ||
9283 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); | ||
9284 | 9302 | ||
9285 | for (cnt = 0; cnt < 100; cnt++) { | 9303 | /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ |
9286 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); | 9304 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); |
9287 | if (val & 1) | 9305 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); |
9288 | break; | 9306 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); |
9289 | udelay(5); | 9307 | for (cnt = 0; cnt < 100; cnt++) { |
9290 | } | 9308 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); |
9291 | if (cnt == 100) { | 9309 | if (val & 1) |
9292 | DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); | 9310 | break; |
9293 | bnx2x_save_spirom_version(bp, port, 0, | 9311 | udelay(5); |
9294 | phy->ver_addr); | 9312 | } |
9295 | return; | 9313 | if (cnt == 100) { |
9296 | } | 9314 | DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw " |
9315 | "version(2)\n"); | ||
9316 | bnx2x_save_spirom_version(bp, port, 0, | ||
9317 | phy->ver_addr); | ||
9318 | return; | ||
9319 | } | ||
9297 | 9320 | ||
9321 | /* lower 16 bits of the register SPI_FW_STATUS */ | ||
9322 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); | ||
9323 | /* upper 16 bits of register SPI_FW_STATUS */ | ||
9324 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); | ||
9298 | 9325 | ||
9299 | /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ | 9326 | bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1, |
9300 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); | ||
9301 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); | ||
9302 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); | ||
9303 | for (cnt = 0; cnt < 100; cnt++) { | ||
9304 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); | ||
9305 | if (val & 1) | ||
9306 | break; | ||
9307 | udelay(5); | ||
9308 | } | ||
9309 | if (cnt == 100) { | ||
9310 | DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); | ||
9311 | bnx2x_save_spirom_version(bp, port, 0, | ||
9312 | phy->ver_addr); | 9327 | phy->ver_addr); |
9313 | return; | ||
9314 | } | 9328 | } |
9315 | 9329 | ||
9316 | /* lower 16 bits of the register SPI_FW_STATUS */ | ||
9317 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); | ||
9318 | /* upper 16 bits of register SPI_FW_STATUS */ | ||
9319 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); | ||
9320 | |||
9321 | bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1, | ||
9322 | phy->ver_addr); | ||
9323 | } | 9330 | } |
9324 | |||
9325 | static void bnx2x_848xx_set_led(struct bnx2x *bp, | 9331 | static void bnx2x_848xx_set_led(struct bnx2x *bp, |
9326 | struct bnx2x_phy *phy) | 9332 | struct bnx2x_phy *phy) |
9327 | { | 9333 | { |
@@ -9392,10 +9398,13 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, | |||
9392 | u16 tmp_req_line_speed; | 9398 | u16 tmp_req_line_speed; |
9393 | 9399 | ||
9394 | tmp_req_line_speed = phy->req_line_speed; | 9400 | tmp_req_line_speed = phy->req_line_speed; |
9395 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) | 9401 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { |
9396 | if (phy->req_line_speed == SPEED_10000) | 9402 | if (phy->req_line_speed == SPEED_10000) |
9397 | phy->req_line_speed = SPEED_AUTO_NEG; | 9403 | phy->req_line_speed = SPEED_AUTO_NEG; |
9398 | 9404 | } else { | |
9405 | /* Save spirom version */ | ||
9406 | bnx2x_save_848xx_spirom_version(phy, bp, params->port); | ||
9407 | } | ||
9399 | /* | 9408 | /* |
9400 | * This phy uses the NIG latch mechanism since link indication | 9409 | * This phy uses the NIG latch mechanism since link indication |
9401 | * arrives through its LED4 and not via its LASI signal, so we | 9410 | * arrives through its LED4 and not via its LASI signal, so we |
@@ -9539,9 +9548,6 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, | |||
9539 | MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, | 9548 | MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, |
9540 | 1); | 9549 | 1); |
9541 | 9550 | ||
9542 | /* Save spirom version */ | ||
9543 | bnx2x_save_848xx_spirom_version(phy, params); | ||
9544 | |||
9545 | phy->req_line_speed = tmp_req_line_speed; | 9551 | phy->req_line_speed = tmp_req_line_speed; |
9546 | 9552 | ||
9547 | return 0; | 9553 | return 0; |
@@ -9749,17 +9755,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
9749 | 9755 | ||
9750 | /* Wait for GPHY to come out of reset */ | 9756 | /* Wait for GPHY to come out of reset */ |
9751 | msleep(50); | 9757 | msleep(50); |
9752 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { | 9758 | if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { |
9753 | /* Bring PHY out of super isolate mode */ | ||
9754 | bnx2x_cl45_read(bp, phy, | ||
9755 | MDIO_CTL_DEVAD, | ||
9756 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); | ||
9757 | val &= ~MDIO_84833_SUPER_ISOLATE; | ||
9758 | bnx2x_cl45_write(bp, phy, | ||
9759 | MDIO_CTL_DEVAD, | ||
9760 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); | ||
9761 | bnx2x_84833_pair_swap_cfg(phy, params, vars); | ||
9762 | } else { | ||
9763 | /* | 9759 | /* |
9764 | * BCM84823 requires that XGXS links up first @ 10G for normal | 9760 | * BCM84823 requires that XGXS links up first @ 10G for normal |
9765 | * behavior. | 9761 | * behavior. |
@@ -9816,24 +9812,27 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
9816 | DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", | 9812 | DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", |
9817 | params->multi_phy_config, val); | 9813 | params->multi_phy_config, val); |
9818 | 9814 | ||
9819 | /* AutogrEEEn */ | 9815 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { |
9820 | if (params->feature_config_flags & | 9816 | bnx2x_84833_pair_swap_cfg(phy, params, vars); |
9821 | FEATURE_CONFIG_AUTOGREEEN_ENABLED) | ||
9822 | cmd_args[0] = 0x2; | ||
9823 | else | ||
9824 | cmd_args[0] = 0x0; | ||
9825 | 9817 | ||
9826 | cmd_args[1] = 0x0; | 9818 | /* AutogrEEEn */ |
9827 | cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1; | 9819 | if (params->feature_config_flags & |
9828 | cmd_args[3] = PHY84833_CONSTANT_LATENCY; | 9820 | FEATURE_CONFIG_AUTOGREEEN_ENABLED) |
9829 | rc = bnx2x_84833_cmd_hdlr(phy, params, | 9821 | cmd_args[0] = 0x2; |
9830 | PHY84833_CMD_SET_EEE_MODE, cmd_args); | 9822 | else |
9831 | if (rc != 0) | 9823 | cmd_args[0] = 0x0; |
9832 | DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); | 9824 | cmd_args[1] = 0x0; |
9825 | cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1; | ||
9826 | cmd_args[3] = PHY84833_CONSTANT_LATENCY; | ||
9827 | rc = bnx2x_84833_cmd_hdlr(phy, params, | ||
9828 | PHY84833_CMD_SET_EEE_MODE, cmd_args); | ||
9829 | if (rc != 0) | ||
9830 | DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); | ||
9831 | } | ||
9833 | if (initialize) | 9832 | if (initialize) |
9834 | rc = bnx2x_848xx_cmn_config_init(phy, params, vars); | 9833 | rc = bnx2x_848xx_cmn_config_init(phy, params, vars); |
9835 | else | 9834 | else |
9836 | bnx2x_save_848xx_spirom_version(phy, params); | 9835 | bnx2x_save_848xx_spirom_version(phy, bp, params->port); |
9837 | /* 84833 PHY has a better feature and doesn't need to support this. */ | 9836 | /* 84833 PHY has a better feature and doesn't need to support this. */ |
9838 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { | 9837 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) { |
9839 | cms_enable = REG_RD(bp, params->shmem_base + | 9838 | cms_enable = REG_RD(bp, params->shmem_base + |
@@ -9851,6 +9850,16 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
9851 | MDIO_CTL_REG_84823_USER_CTRL_REG, val); | 9850 | MDIO_CTL_REG_84823_USER_CTRL_REG, val); |
9852 | } | 9851 | } |
9853 | 9852 | ||
9853 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { | ||
9854 | /* Bring PHY out of super isolate mode as the final step. */ | ||
9855 | bnx2x_cl45_read(bp, phy, | ||
9856 | MDIO_CTL_DEVAD, | ||
9857 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); | ||
9858 | val &= ~MDIO_84833_SUPER_ISOLATE; | ||
9859 | bnx2x_cl45_write(bp, phy, | ||
9860 | MDIO_CTL_DEVAD, | ||
9861 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); | ||
9862 | } | ||
9854 | return rc; | 9863 | return rc; |
9855 | } | 9864 | } |
9856 | 9865 | ||
@@ -9988,10 +9997,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, | |||
9988 | } else { | 9997 | } else { |
9989 | bnx2x_cl45_read(bp, phy, | 9998 | bnx2x_cl45_read(bp, phy, |
9990 | MDIO_CTL_DEVAD, | 9999 | MDIO_CTL_DEVAD, |
9991 | 0x400f, &val16); | 10000 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16); |
10001 | val16 |= MDIO_84833_SUPER_ISOLATE; | ||
9992 | bnx2x_cl45_write(bp, phy, | 10002 | bnx2x_cl45_write(bp, phy, |
9993 | MDIO_PMA_DEVAD, | 10003 | MDIO_CTL_DEVAD, |
9994 | MDIO_PMA_REG_CTRL, 0x800); | 10004 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16); |
9995 | } | 10005 | } |
9996 | } | 10006 | } |
9997 | 10007 | ||
@@ -12333,55 +12343,69 @@ static int bnx2x_84833_common_init_phy(struct bnx2x *bp, | |||
12333 | u32 chip_id) | 12343 | u32 chip_id) |
12334 | { | 12344 | { |
12335 | u8 reset_gpios; | 12345 | u8 reset_gpios; |
12336 | struct bnx2x_phy phy; | ||
12337 | u32 shmem_base, shmem2_base, cnt; | ||
12338 | s8 port = 0; | ||
12339 | u16 val; | ||
12340 | |||
12341 | reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id); | 12346 | reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id); |
12342 | bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW); | 12347 | bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW); |
12343 | udelay(10); | 12348 | udelay(10); |
12344 | bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH); | 12349 | bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH); |
12345 | DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n", | 12350 | DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n", |
12346 | reset_gpios); | 12351 | reset_gpios); |
12347 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 12352 | return 0; |
12348 | /* This PHY is for E2 and E3. */ | 12353 | } |
12349 | shmem_base = shmem_base_path[port]; | ||
12350 | shmem2_base = shmem2_base_path[port]; | ||
12351 | /* Extract the ext phy address for the port */ | ||
12352 | if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, | ||
12353 | 0, &phy) != | ||
12354 | 0) { | ||
12355 | DP(NETIF_MSG_LINK, "populate_phy failed\n"); | ||
12356 | return -EINVAL; | ||
12357 | } | ||
12358 | 12354 | ||
12359 | /* Wait for FW completing its initialization. */ | 12355 | static int bnx2x_84833_pre_init_phy(struct bnx2x *bp, |
12360 | for (cnt = 0; cnt < 1000; cnt++) { | 12356 | struct bnx2x_phy *phy) |
12361 | bnx2x_cl45_read(bp, &phy, | 12357 | { |
12358 | u16 val, cnt; | ||
12359 | /* Wait for FW completing its initialization. */ | ||
12360 | for (cnt = 0; cnt < 1500; cnt++) { | ||
12361 | bnx2x_cl45_read(bp, phy, | ||
12362 | MDIO_PMA_DEVAD, | 12362 | MDIO_PMA_DEVAD, |
12363 | MDIO_PMA_REG_CTRL, &val); | 12363 | MDIO_PMA_REG_CTRL, &val); |
12364 | if (!(val & (1<<15))) | 12364 | if (!(val & (1<<15))) |
12365 | break; | 12365 | break; |
12366 | msleep(1); | 12366 | msleep(1); |
12367 | } | 12367 | } |
12368 | if (cnt >= 1000) | 12368 | if (cnt >= 1500) { |
12369 | DP(NETIF_MSG_LINK, | 12369 | DP(NETIF_MSG_LINK, "84833 reset timeout\n"); |
12370 | "84833 Cmn reset timeout (%d)\n", port); | 12370 | return -EINVAL; |
12371 | |||
12372 | /* Put the port in super isolate mode. */ | ||
12373 | bnx2x_cl45_read(bp, &phy, | ||
12374 | MDIO_CTL_DEVAD, | ||
12375 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); | ||
12376 | val |= MDIO_84833_SUPER_ISOLATE; | ||
12377 | bnx2x_cl45_write(bp, &phy, | ||
12378 | MDIO_CTL_DEVAD, | ||
12379 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); | ||
12380 | } | 12371 | } |
12381 | 12372 | ||
12373 | /* Put the port in super isolate mode. */ | ||
12374 | bnx2x_cl45_read(bp, phy, | ||
12375 | MDIO_CTL_DEVAD, | ||
12376 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val); | ||
12377 | val |= MDIO_84833_SUPER_ISOLATE; | ||
12378 | bnx2x_cl45_write(bp, phy, | ||
12379 | MDIO_CTL_DEVAD, | ||
12380 | MDIO_84833_TOP_CFG_XGPHY_STRAP1, val); | ||
12381 | |||
12382 | /* Save spirom version */ | ||
12383 | bnx2x_save_848xx_spirom_version(phy, bp, PORT_0); | ||
12382 | return 0; | 12384 | return 0; |
12383 | } | 12385 | } |
12384 | 12386 | ||
12387 | int bnx2x_pre_init_phy(struct bnx2x *bp, | ||
12388 | u32 shmem_base, | ||
12389 | u32 shmem2_base, | ||
12390 | u32 chip_id) | ||
12391 | { | ||
12392 | int rc = 0; | ||
12393 | struct bnx2x_phy phy; | ||
12394 | bnx2x_set_mdio_clk(bp, chip_id, PORT_0); | ||
12395 | if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base, | ||
12396 | PORT_0, &phy)) { | ||
12397 | DP(NETIF_MSG_LINK, "populate_phy failed\n"); | ||
12398 | return -EINVAL; | ||
12399 | } | ||
12400 | switch (phy.type) { | ||
12401 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: | ||
12402 | rc = bnx2x_84833_pre_init_phy(bp, &phy); | ||
12403 | break; | ||
12404 | default: | ||
12405 | break; | ||
12406 | } | ||
12407 | return rc; | ||
12408 | } | ||
12385 | 12409 | ||
12386 | static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], | 12410 | static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], |
12387 | u32 shmem2_base_path[], u8 phy_index, | 12411 | u32 shmem2_base_path[], u8 phy_index, |