aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c250
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/******************************************************************/
9268static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, 9268static 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
9325static void bnx2x_848xx_set_led(struct bnx2x *bp, 9331static 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. */ 12355static 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
12387int 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
12386static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[], 12410static 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,