aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2012-01-16 21:33:25 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-17 10:44:42 -0500
commit11b2ec6b739ee90211dc6f6942e2ba3a141434a8 (patch)
treecd3fcf9d89db4d87bd0ac1ec4bf17205c99d22cd /drivers/net/ethernet
parent747465ef7a082033e086dedc8189febfda43b015 (diff)
bnx2x: Fix Super-Isolate mode for BCM84833
The Super-Isolate mode comes to isolate the BCM84833 PHY from the outside world. Not doing it correctly, made link partner see the link before the driver was loaded. This patch also involves SPIROM version fixes since it is used to determine whether the common init of the PHY was already executed, and the common init of this PHY is partially responsible for setting the Super-Isolate mode. 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')
-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,