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.c218
1 files changed, 147 insertions, 71 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index bcd8f0038628..d45b1555a602 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -1546,6 +1546,12 @@ static void bnx2x_umac_enable(struct link_params *params,
1546 vars->line_speed); 1546 vars->line_speed);
1547 break; 1547 break;
1548 } 1548 }
1549 if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1550 val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1551
1552 if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1553 val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1554
1549 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); 1555 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1550 udelay(50); 1556 udelay(50);
1551 1557
@@ -1661,10 +1667,20 @@ static void bnx2x_xmac_disable(struct link_params *params)
1661{ 1667{
1662 u8 port = params->port; 1668 u8 port = params->port;
1663 struct bnx2x *bp = params->bp; 1669 struct bnx2x *bp = params->bp;
1664 u32 xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; 1670 u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1665 1671
1666 if (REG_RD(bp, MISC_REG_RESET_REG_2) & 1672 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1667 MISC_REGISTERS_RESET_REG_2_XMAC) { 1673 MISC_REGISTERS_RESET_REG_2_XMAC) {
1674 /*
1675 * Send an indication to change the state in the NIG back to XON
1676 * Clearing this bit enables the next set of this bit to get
1677 * rising edge
1678 */
1679 pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI);
1680 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1681 (pfc_ctrl & ~(1<<1)));
1682 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1683 (pfc_ctrl | (1<<1)));
1668 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port); 1684 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1669 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0); 1685 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
1670 usleep_range(1000, 1000); 1686 usleep_range(1000, 1000);
@@ -1729,6 +1745,10 @@ static int bnx2x_emac_enable(struct link_params *params,
1729 1745
1730 DP(NETIF_MSG_LINK, "enabling EMAC\n"); 1746 DP(NETIF_MSG_LINK, "enabling EMAC\n");
1731 1747
1748 /* Disable BMAC */
1749 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1750 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1751
1732 /* enable emac and not bmac */ 1752 /* enable emac and not bmac */
1733 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1); 1753 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1734 1754
@@ -2583,12 +2603,6 @@ static int bnx2x_bmac1_enable(struct link_params *params,
2583 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, 2603 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2584 wb_data, 2); 2604 wb_data, 2);
2585 2605
2586 if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) {
2587 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LSS_STATUS,
2588 wb_data, 2);
2589 if (wb_data[0] > 0)
2590 return -ESRCH;
2591 }
2592 return 0; 2606 return 0;
2593} 2607}
2594 2608
@@ -2654,16 +2668,6 @@ static int bnx2x_bmac2_enable(struct link_params *params,
2654 udelay(30); 2668 udelay(30);
2655 bnx2x_update_pfc_bmac2(params, vars, is_lb); 2669 bnx2x_update_pfc_bmac2(params, vars, is_lb);
2656 2670
2657 if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) {
2658 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LSS_STAT,
2659 wb_data, 2);
2660 if (wb_data[0] > 0) {
2661 DP(NETIF_MSG_LINK, "Got bad LSS status 0x%x\n",
2662 wb_data[0]);
2663 return -ESRCH;
2664 }
2665 }
2666
2667 return 0; 2671 return 0;
2668} 2672}
2669 2673
@@ -2949,7 +2953,9 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2949 u32 val; 2953 u32 val;
2950 u16 i; 2954 u16 i;
2951 int rc = 0; 2955 int rc = 0;
2952 2956 if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2957 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2958 EMAC_MDIO_STATUS_10MB);
2953 /* address */ 2959 /* address */
2954 val = ((phy->addr << 21) | (devad << 16) | reg | 2960 val = ((phy->addr << 21) | (devad << 16) | reg |
2955 EMAC_MDIO_COMM_COMMAND_ADDRESS | 2961 EMAC_MDIO_COMM_COMMAND_ADDRESS |
@@ -3003,6 +3009,9 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
3003 } 3009 }
3004 } 3010 }
3005 3011
3012 if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3013 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3014 EMAC_MDIO_STATUS_10MB);
3006 return rc; 3015 return rc;
3007} 3016}
3008 3017
@@ -3012,6 +3021,9 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3012 u32 tmp; 3021 u32 tmp;
3013 u8 i; 3022 u8 i;
3014 int rc = 0; 3023 int rc = 0;
3024 if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3025 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3026 EMAC_MDIO_STATUS_10MB);
3015 3027
3016 /* address */ 3028 /* address */
3017 3029
@@ -3065,7 +3077,9 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3065 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); 3077 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3066 } 3078 }
3067 } 3079 }
3068 3080 if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3081 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3082 EMAC_MDIO_STATUS_10MB);
3069 return rc; 3083 return rc;
3070} 3084}
3071 3085
@@ -4353,6 +4367,9 @@ void bnx2x_link_status_update(struct link_params *params,
4353 4367
4354 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); 4368 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4355 vars->phy_flags = PHY_XGXS_FLAG; 4369 vars->phy_flags = PHY_XGXS_FLAG;
4370 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4371 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4372
4356 if (vars->link_up) { 4373 if (vars->link_up) {
4357 DP(NETIF_MSG_LINK, "phy link up\n"); 4374 DP(NETIF_MSG_LINK, "phy link up\n");
4358 4375
@@ -4444,6 +4461,8 @@ void bnx2x_link_status_update(struct link_params *params,
4444 4461
4445 /* indicate no mac active */ 4462 /* indicate no mac active */
4446 vars->mac_type = MAC_TYPE_NONE; 4463 vars->mac_type = MAC_TYPE_NONE;
4464 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4465 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4447 } 4466 }
4448 4467
4449 /* Sync media type */ 4468 /* Sync media type */
@@ -5903,20 +5922,30 @@ int bnx2x_set_led(struct link_params *params,
5903 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); 5922 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5904 EMAC_WR(bp, EMAC_REG_EMAC_LED, 5923 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5905 (tmp | EMAC_LED_OVERRIDE)); 5924 (tmp | EMAC_LED_OVERRIDE));
5906 return rc; 5925 /*
5926 * return here without enabling traffic
5927 * LED blink andsetting rate in ON mode.
5928 * In oper mode, enabling LED blink
5929 * and setting rate is needed.
5930 */
5931 if (mode == LED_MODE_ON)
5932 return rc;
5907 } 5933 }
5908 } else if (SINGLE_MEDIA_DIRECT(params) && 5934 } else if (SINGLE_MEDIA_DIRECT(params)) {
5909 (CHIP_IS_E1x(bp) ||
5910 CHIP_IS_E2(bp))) {
5911 /* 5935 /*
5912 * This is a work-around for HW issue found when link 5936 * This is a work-around for HW issue found when link
5913 * is up in CL73 5937 * is up in CL73
5914 */ 5938 */
5915 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5916 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); 5939 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5917 } else { 5940 if (CHIP_IS_E1x(bp) ||
5941 CHIP_IS_E2(bp) ||
5942 (mode == LED_MODE_ON))
5943 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5944 else
5945 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5946 hw_led_mode);
5947 } else
5918 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode); 5948 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
5919 }
5920 5949
5921 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); 5950 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
5922 /* Set blinking rate to ~15.9Hz */ 5951 /* Set blinking rate to ~15.9Hz */
@@ -6160,6 +6189,7 @@ static int bnx2x_update_link_down(struct link_params *params,
6160 /* update shared memory */ 6189 /* update shared memory */
6161 vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | 6190 vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
6162 LINK_STATUS_LINK_UP | 6191 LINK_STATUS_LINK_UP |
6192 LINK_STATUS_PHYSICAL_LINK_FLAG |
6163 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | 6193 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
6164 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | 6194 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
6165 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | 6195 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
@@ -6197,7 +6227,8 @@ static int bnx2x_update_link_up(struct link_params *params,
6197 u8 port = params->port; 6227 u8 port = params->port;
6198 int rc = 0; 6228 int rc = 0;
6199 6229
6200 vars->link_status |= LINK_STATUS_LINK_UP; 6230 vars->link_status |= (LINK_STATUS_LINK_UP |
6231 LINK_STATUS_PHYSICAL_LINK_FLAG);
6201 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG; 6232 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
6202 6233
6203 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 6234 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
@@ -7998,6 +8029,9 @@ static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
7998 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 8029 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
7999 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); 8030 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8000 8031
8032 /* Restart microcode to re-read the new mode */
8033 bnx2x_warpcore_reset_lane(bp, phy, 1);
8034 bnx2x_warpcore_reset_lane(bp, phy, 0);
8001 8035
8002} 8036}
8003 8037
@@ -8116,7 +8150,6 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
8116 offsetof(struct shmem_region, dev_info. 8150 offsetof(struct shmem_region, dev_info.
8117 port_feature_config[params->port]. 8151 port_feature_config[params->port].
8118 config)); 8152 config));
8119
8120 bnx2x_set_gpio_int(bp, gpio_num, 8153 bnx2x_set_gpio_int(bp, gpio_num,
8121 MISC_REGISTERS_GPIO_INT_OUTPUT_SET, 8154 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
8122 gpio_port); 8155 gpio_port);
@@ -8125,8 +8158,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
8125 * Disable transmit for this module 8158 * Disable transmit for this module
8126 */ 8159 */
8127 phy->media_type = ETH_PHY_NOT_PRESENT; 8160 phy->media_type = ETH_PHY_NOT_PRESENT;
8128 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 8161 if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8129 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) 8162 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) ||
8163 CHIP_IS_E3(bp))
8130 bnx2x_sfp_set_transmitter(params, phy, 0); 8164 bnx2x_sfp_set_transmitter(params, phy, 0);
8131 } 8165 }
8132} 8166}
@@ -8228,9 +8262,6 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
8228 u16 cnt, val, tmp1; 8262 u16 cnt, val, tmp1;
8229 struct bnx2x *bp = params->bp; 8263 struct bnx2x *bp = params->bp;
8230 8264
8231 /* SPF+ PHY: Set flag to check for Tx error */
8232 vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
8233
8234 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 8265 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8235 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); 8266 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8236 /* HW reset */ 8267 /* HW reset */
@@ -8414,9 +8445,6 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
8414 struct bnx2x *bp = params->bp; 8445 struct bnx2x *bp = params->bp;
8415 DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); 8446 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
8416 8447
8417 /* SPF+ PHY: Set flag to check for Tx error */
8418 vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
8419
8420 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); 8448 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8421 bnx2x_wait_reset_complete(bp, phy, params); 8449 bnx2x_wait_reset_complete(bp, phy, params);
8422 8450
@@ -8585,9 +8613,6 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
8585 struct bnx2x *bp = params->bp; 8613 struct bnx2x *bp = params->bp;
8586 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ 8614 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8587 8615
8588 /* SPF+ PHY: Set flag to check for Tx error */
8589 vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
8590
8591 bnx2x_wait_reset_complete(bp, phy, params); 8616 bnx2x_wait_reset_complete(bp, phy, params);
8592 rx_alarm_ctrl_val = (1<<2) | (1<<5) ; 8617 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
8593 /* Should be 0x6 to enable XS on Tx side. */ 8618 /* Should be 0x6 to enable XS on Tx side. */
@@ -9243,7 +9268,13 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9243 if (phy->req_duplex == DUPLEX_FULL) 9268 if (phy->req_duplex == DUPLEX_FULL)
9244 autoneg_val |= (1<<8); 9269 autoneg_val |= (1<<8);
9245 9270
9246 bnx2x_cl45_write(bp, phy, 9271 /*
9272 * Always write this if this is not 84833.
9273 * For 84833, write it only when it's a forced speed.
9274 */
9275 if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
9276 ((autoneg_val & (1<<12)) == 0))
9277 bnx2x_cl45_write(bp, phy,
9247 MDIO_AN_DEVAD, 9278 MDIO_AN_DEVAD,
9248 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); 9279 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
9249 9280
@@ -9257,13 +9288,12 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9257 bnx2x_cl45_write(bp, phy, 9288 bnx2x_cl45_write(bp, phy,
9258 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 9289 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
9259 0x3200); 9290 0x3200);
9260 } else if (phy->req_line_speed != SPEED_10 && 9291 } else
9261 phy->req_line_speed != SPEED_100) {
9262 bnx2x_cl45_write(bp, phy, 9292 bnx2x_cl45_write(bp, phy,
9263 MDIO_AN_DEVAD, 9293 MDIO_AN_DEVAD,
9264 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, 9294 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9265 1); 9295 1);
9266 } 9296
9267 /* Save spirom version */ 9297 /* Save spirom version */
9268 bnx2x_save_848xx_spirom_version(phy, params); 9298 bnx2x_save_848xx_spirom_version(phy, params);
9269 9299
@@ -9756,11 +9786,9 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
9756 bnx2x_cl45_read(bp, phy, 9786 bnx2x_cl45_read(bp, phy,
9757 MDIO_CTL_DEVAD, 9787 MDIO_CTL_DEVAD,
9758 0x400f, &val16); 9788 0x400f, &val16);
9759 /* Put to low power mode on newer FW */ 9789 bnx2x_cl45_write(bp, phy,
9760 if ((val16 & 0x303f) > 0x1009) 9790 MDIO_PMA_DEVAD,
9761 bnx2x_cl45_write(bp, phy, 9791 MDIO_PMA_REG_CTRL, 0x800);
9762 MDIO_PMA_DEVAD,
9763 MDIO_PMA_REG_CTRL, 0x800);
9764 } 9792 }
9765} 9793}
9766 9794
@@ -10191,8 +10219,15 @@ static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
10191 u32 cfg_pin; 10219 u32 cfg_pin;
10192 u8 port; 10220 u8 port;
10193 10221
10194 /* This works with E3 only, no need to check the chip 10222 /*
10195 before determining the port. */ 10223 * In case of no EPIO routed to reset the GPHY, put it
10224 * in low power mode.
10225 */
10226 bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800);
10227 /*
10228 * This works with E3 only, no need to check the chip
10229 * before determining the port.
10230 */
10196 port = params->port; 10231 port = params->port;
10197 cfg_pin = (REG_RD(bp, params->shmem_base + 10232 cfg_pin = (REG_RD(bp, params->shmem_base +
10198 offsetof(struct shmem_region, 10233 offsetof(struct shmem_region,
@@ -10603,7 +10638,8 @@ static struct bnx2x_phy phy_warpcore = {
10603 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, 10638 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10604 .addr = 0xff, 10639 .addr = 0xff,
10605 .def_md_devad = 0, 10640 .def_md_devad = 0,
10606 .flags = FLAGS_HW_LOCK_REQUIRED, 10641 .flags = (FLAGS_HW_LOCK_REQUIRED |
10642 FLAGS_TX_ERROR_CHECK),
10607 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10643 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10608 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10644 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10609 .mdio_ctrl = 0, 10645 .mdio_ctrl = 0,
@@ -10729,7 +10765,8 @@ static struct bnx2x_phy phy_8706 = {
10729 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, 10765 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
10730 .addr = 0xff, 10766 .addr = 0xff,
10731 .def_md_devad = 0, 10767 .def_md_devad = 0,
10732 .flags = FLAGS_INIT_XGXS_FIRST, 10768 .flags = (FLAGS_INIT_XGXS_FIRST |
10769 FLAGS_TX_ERROR_CHECK),
10733 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10770 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10734 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10771 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10735 .mdio_ctrl = 0, 10772 .mdio_ctrl = 0,
@@ -10760,7 +10797,8 @@ static struct bnx2x_phy phy_8726 = {
10760 .addr = 0xff, 10797 .addr = 0xff,
10761 .def_md_devad = 0, 10798 .def_md_devad = 0,
10762 .flags = (FLAGS_HW_LOCK_REQUIRED | 10799 .flags = (FLAGS_HW_LOCK_REQUIRED |
10763 FLAGS_INIT_XGXS_FIRST), 10800 FLAGS_INIT_XGXS_FIRST |
10801 FLAGS_TX_ERROR_CHECK),
10764 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10802 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10765 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10803 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10766 .mdio_ctrl = 0, 10804 .mdio_ctrl = 0,
@@ -10791,7 +10829,8 @@ static struct bnx2x_phy phy_8727 = {
10791 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 10829 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
10792 .addr = 0xff, 10830 .addr = 0xff,
10793 .def_md_devad = 0, 10831 .def_md_devad = 0,
10794 .flags = FLAGS_FAN_FAILURE_DET_REQ, 10832 .flags = (FLAGS_FAN_FAILURE_DET_REQ |
10833 FLAGS_TX_ERROR_CHECK),
10795 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10834 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10796 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, 10835 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10797 .mdio_ctrl = 0, 10836 .mdio_ctrl = 0,
@@ -11112,6 +11151,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
11112 */ 11151 */
11113 if (CHIP_REV(bp) == CHIP_REV_Ax) 11152 if (CHIP_REV(bp) == CHIP_REV_Ax)
11114 phy->flags |= FLAGS_MDC_MDIO_WA; 11153 phy->flags |= FLAGS_MDC_MDIO_WA;
11154 else
11155 phy->flags |= FLAGS_MDC_MDIO_WA_B0;
11115 } else { 11156 } else {
11116 switch (switch_cfg) { 11157 switch (switch_cfg) {
11117 case SWITCH_CFG_1G: 11158 case SWITCH_CFG_1G:
@@ -11500,13 +11541,12 @@ void bnx2x_init_xmac_loopback(struct link_params *params,
11500 * Set WC to loopback mode since link is required to provide clock 11541 * Set WC to loopback mode since link is required to provide clock
11501 * to the XMAC in 20G mode 11542 * to the XMAC in 20G mode
11502 */ 11543 */
11503 if (vars->line_speed == SPEED_20000) { 11544 bnx2x_set_aer_mmd(params, &params->phy[0]);
11504 bnx2x_set_aer_mmd(params, &params->phy[0]); 11545 bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0);
11505 bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0); 11546 params->phy[INT_PHY].config_loopback(
11506 params->phy[INT_PHY].config_loopback(
11507 &params->phy[INT_PHY], 11547 &params->phy[INT_PHY],
11508 params); 11548 params);
11509 } 11549
11510 bnx2x_xmac_enable(params, vars, 1); 11550 bnx2x_xmac_enable(params, vars, 1);
11511 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); 11551 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11512} 11552}
@@ -11684,12 +11724,16 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
11684 bnx2x_set_led(params, vars, LED_MODE_OFF, 0); 11724 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
11685 11725
11686 if (reset_ext_phy) { 11726 if (reset_ext_phy) {
11727 bnx2x_set_mdio_clk(bp, params->chip_id, port);
11687 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 11728 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
11688 phy_index++) { 11729 phy_index++) {
11689 if (params->phy[phy_index].link_reset) 11730 if (params->phy[phy_index].link_reset) {
11731 bnx2x_set_aer_mmd(params,
11732 &params->phy[phy_index]);
11690 params->phy[phy_index].link_reset( 11733 params->phy[phy_index].link_reset(
11691 &params->phy[phy_index], 11734 &params->phy[phy_index],
11692 params); 11735 params);
11736 }
11693 if (params->phy[phy_index].flags & 11737 if (params->phy[phy_index].flags &
11694 FLAGS_REARM_LATCH_SIGNAL) 11738 FLAGS_REARM_LATCH_SIGNAL)
11695 clear_latch_ind = 1; 11739 clear_latch_ind = 1;
@@ -12178,10 +12222,6 @@ static void bnx2x_analyze_link_error(struct link_params *params,
12178 u8 led_mode; 12222 u8 led_mode;
12179 u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0; 12223 u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0;
12180 12224
12181 /*DP(NETIF_MSG_LINK, "CHECK LINK: %x half_open:%x-> lss:%x\n",
12182 vars->link_up,
12183 half_open_conn, lss_status);*/
12184
12185 if ((lss_status ^ half_open_conn) == 0) 12225 if ((lss_status ^ half_open_conn) == 0)
12186 return; 12226 return;
12187 12227
@@ -12194,6 +12234,7 @@ static void bnx2x_analyze_link_error(struct link_params *params,
12194 * b. Update link_vars->link_up 12234 * b. Update link_vars->link_up
12195 */ 12235 */
12196 if (lss_status) { 12236 if (lss_status) {
12237 DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n");
12197 vars->link_status &= ~LINK_STATUS_LINK_UP; 12238 vars->link_status &= ~LINK_STATUS_LINK_UP;
12198 vars->link_up = 0; 12239 vars->link_up = 0;
12199 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; 12240 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
@@ -12203,6 +12244,7 @@ static void bnx2x_analyze_link_error(struct link_params *params,
12203 */ 12244 */
12204 led_mode = LED_MODE_OFF; 12245 led_mode = LED_MODE_OFF;
12205 } else { 12246 } else {
12247 DP(NETIF_MSG_LINK, "Remote Fault cleared\n");
12206 vars->link_status |= LINK_STATUS_LINK_UP; 12248 vars->link_status |= LINK_STATUS_LINK_UP;
12207 vars->link_up = 1; 12249 vars->link_up = 1;
12208 vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; 12250 vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
@@ -12219,6 +12261,15 @@ static void bnx2x_analyze_link_error(struct link_params *params,
12219 bnx2x_notify_link_changed(bp); 12261 bnx2x_notify_link_changed(bp);
12220} 12262}
12221 12263
12264/******************************************************************************
12265* Description:
12266* This function checks for half opened connection change indication.
12267* When such change occurs, it calls the bnx2x_analyze_link_error
12268* to check if Remote Fault is set or cleared. Reception of remote fault
12269* status message in the MAC indicates that the peer's MAC has detected
12270* a fault, for example, due to break in the TX side of fiber.
12271*
12272******************************************************************************/
12222static void bnx2x_check_half_open_conn(struct link_params *params, 12273static void bnx2x_check_half_open_conn(struct link_params *params,
12223 struct link_vars *vars) 12274 struct link_vars *vars)
12224{ 12275{
@@ -12229,9 +12280,28 @@ static void bnx2x_check_half_open_conn(struct link_params *params,
12229 if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) 12280 if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
12230 return; 12281 return;
12231 12282
12232 if (!CHIP_IS_E3(bp) && 12283 if (CHIP_IS_E3(bp) &&
12233 (REG_RD(bp, MISC_REG_RESET_REG_2) & 12284 (REG_RD(bp, MISC_REG_RESET_REG_2) &
12234 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))) { 12285 (MISC_REGISTERS_RESET_REG_2_XMAC))) {
12286 /* Check E3 XMAC */
12287 /*
12288 * Note that link speed cannot be queried here, since it may be
12289 * zero while link is down. In case UMAC is active, LSS will
12290 * simply not be set
12291 */
12292 mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
12293
12294 /* Clear stick bits (Requires rising edge) */
12295 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
12296 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
12297 XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
12298 XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
12299 if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS))
12300 lss_status = 1;
12301
12302 bnx2x_analyze_link_error(params, vars, lss_status);
12303 } else if (REG_RD(bp, MISC_REG_RESET_REG_2) &
12304 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
12235 /* Check E1X / E2 BMAC */ 12305 /* Check E1X / E2 BMAC */
12236 u32 lss_status_reg; 12306 u32 lss_status_reg;
12237 u32 wb_data[2]; 12307 u32 wb_data[2];
@@ -12253,14 +12323,20 @@ static void bnx2x_check_half_open_conn(struct link_params *params,
12253void bnx2x_period_func(struct link_params *params, struct link_vars *vars) 12323void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
12254{ 12324{
12255 struct bnx2x *bp = params->bp; 12325 struct bnx2x *bp = params->bp;
12326 u16 phy_idx;
12256 if (!params) { 12327 if (!params) {
12257 DP(NETIF_MSG_LINK, "Ininitliazed params !\n"); 12328 DP(NETIF_MSG_LINK, "Uninitialized params !\n");
12258 return; 12329 return;
12259 } 12330 }
12260 /* DP(NETIF_MSG_LINK, "Periodic called vars->phy_flags 0x%x speed 0x%x 12331
12261 RESET_REG_2 0x%x\n", vars->phy_flags, vars->line_speed, 12332 for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
12262 REG_RD(bp, MISC_REG_RESET_REG_2)); */ 12333 if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
12263 bnx2x_check_half_open_conn(params, vars); 12334 bnx2x_set_aer_mmd(params, &params->phy[phy_idx]);
12335 bnx2x_check_half_open_conn(params, vars);
12336 break;
12337 }
12338 }
12339
12264 if (CHIP_IS_E3(bp)) 12340 if (CHIP_IS_E3(bp))
12265 bnx2x_check_over_curr(params, vars); 12341 bnx2x_check_over_curr(params, vars);
12266} 12342}