bnx2x: remove unnecessary read of PCI_CAP_ID_EXP
[cascardo/linux.git] / drivers / net / bnx2x / bnx2x_link.c
index 241b1e4..8363636 100644 (file)
@@ -296,6 +296,23 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
 /******************************************************************/
 /*                     EPIO/GPIO section                         */
 /******************************************************************/
+static void bnx2x_get_epio(struct bnx2x *bp, u32 epio_pin, u32 *en)
+{
+       u32 epio_mask, gp_oenable;
+       *en = 0;
+       /* Sanity check */
+       if (epio_pin > 31) {
+               DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin);
+               return;
+       }
+
+       epio_mask = 1 << epio_pin;
+       /* Set this EPIO to output */
+       gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
+       REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
+
+       *en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
+}
 static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
 {
        u32 epio_mask, gp_output, gp_oenable;
@@ -334,6 +351,20 @@ static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
        }
 }
 
+static u32 bnx2x_get_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 *val)
+{
+       if (pin_cfg == PIN_CFG_NA)
+               return -EINVAL;
+       if (pin_cfg >= PIN_CFG_EPIO0) {
+               bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
+       } else {
+               u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
+               u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
+               *val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
+       }
+       return 0;
+
+}
 /******************************************************************/
 /*                             ETS section                       */
 /******************************************************************/
@@ -2537,6 +2568,12 @@ static int bnx2x_bmac1_enable(struct link_params *params,
        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
                    wb_data, 2);
 
+       if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) {
+               REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LSS_STATUS,
+                           wb_data, 2);
+               if (wb_data[0] > 0)
+                       return -ESRCH;
+       }
        return 0;
 }
 
@@ -2602,6 +2639,16 @@ static int bnx2x_bmac2_enable(struct link_params *params,
        udelay(30);
        bnx2x_update_pfc_bmac2(params, vars, is_lb);
 
+       if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) {
+               REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LSS_STAT,
+                           wb_data, 2);
+               if (wb_data[0] > 0) {
+                       DP(NETIF_MSG_LINK, "Got bad LSS status 0x%x\n",
+                                      wb_data[0]);
+                       return -ESRCH;
+               }
+       }
+
        return 0;
 }
 
@@ -6081,7 +6128,7 @@ static int bnx2x_update_link_down(struct link_params *params,
 
        DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
        bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
-
+       vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
        /* indicate no mac active */
        vars->mac_type = MAC_TYPE_NONE;
 
@@ -6126,6 +6173,7 @@ static int bnx2x_update_link_up(struct link_params *params,
        int rc = 0;
 
        vars->link_status |= LINK_STATUS_LINK_UP;
+       vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
 
        if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
                vars->link_status |=
@@ -6135,9 +6183,15 @@ static int bnx2x_update_link_up(struct link_params *params,
                vars->link_status |=
                        LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
        if (USES_WARPCORE(bp)) {
-               if (link_10g)
-                       bnx2x_xmac_enable(params, vars, 0);
-               else
+               if (link_10g) {
+                       if (bnx2x_xmac_enable(params, vars, 0) ==
+                           -ESRCH) {
+                               DP(NETIF_MSG_LINK, "Found errors on XMAC\n");
+                               vars->link_up = 0;
+                               vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
+                               vars->link_status &= ~LINK_STATUS_LINK_UP;
+                       }
+               } else
                        bnx2x_umac_enable(params, vars, 0);
                bnx2x_set_led(params, vars,
                              LED_MODE_OPER, vars->line_speed);
@@ -6145,7 +6199,13 @@ static int bnx2x_update_link_up(struct link_params *params,
        if ((CHIP_IS_E1x(bp) ||
             CHIP_IS_E2(bp))) {
                if (link_10g) {
-                       bnx2x_bmac_enable(params, vars, 0);
+                       if (bnx2x_bmac_enable(params, vars, 0) ==
+                           -ESRCH) {
+                               DP(NETIF_MSG_LINK, "Found errors on BMAC\n");
+                               vars->link_up = 0;
+                               vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
+                               vars->link_status &= ~LINK_STATUS_LINK_UP;
+                       }
 
                        bnx2x_set_led(params, vars,
                                      LED_MODE_OPER, SPEED_10000);
@@ -6199,7 +6259,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
        u8 is_mi_int = 0;
        u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
        u8 active_external_phy = INT_PHY;
-
+       vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
        for (phy_index = INT_PHY; phy_index < params->num_phys;
              phy_index++) {
                phy_vars[phy_index].flow_ctrl = 0;
@@ -6761,9 +6821,9 @@ static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
 
        /* enable LASI */
        bnx2x_cl45_write(bp, phy,
-                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
+                        MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
        bnx2x_cl45_write(bp, phy,
-                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,  0x0004);
+                        MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
 
        bnx2x_8073_set_pause_cl37(params, phy, vars);
 
@@ -6771,7 +6831,7 @@ static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
                        MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
 
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
 
        DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
 
@@ -6905,7 +6965,7 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
        u16 an1000_status = 0;
 
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
 
        DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
 
@@ -6921,7 +6981,7 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
 
        /* Check the LASI */
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
 
        DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
 
@@ -8049,16 +8109,16 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
        DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
        /* Clear RX Alarm*/
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
 
-       bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
-                            MDIO_PMA_REG_TX_ALARM_CTRL);
+       bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
+                            MDIO_PMA_LASI_TXCTRL);
 
        /* clear LASI indication*/
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
        DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
 
        bnx2x_cl45_read(bp, phy,
@@ -8089,9 +8149,9 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
        /* Capture 10G link fault. Read twice to clear stale value. */
        if (vars->line_speed == SPEED_10000) {
                bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
-                           MDIO_PMA_REG_TX_ALARM, &val1);
+                           MDIO_PMA_LASI_TXSTAT, &val1);
                bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
-                           MDIO_PMA_REG_TX_ALARM, &val1);
+                           MDIO_PMA_LASI_TXSTAT, &val1);
                if (val1 & (1<<0))
                        vars->fault_detected = 1;
        }
@@ -8109,6 +8169,10 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
        u32 tx_en_mode;
        u16 cnt, val, tmp1;
        struct bnx2x *bp = params->bp;
+
+       /* SPF+ PHY: Set flag to check for Tx error */
+       vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
+
        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
        /* HW reset */
@@ -8151,11 +8215,11 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
                                 MDIO_PMA_DEVAD,
                                 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
                                 0);
                /* Arm LASI for link and Tx fault. */
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 3);
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
        } else {
                /* Force 1Gbps using autoneg with 1G advertisement */
 
@@ -8178,10 +8242,10 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
                bnx2x_cl45_write(bp, phy,
                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
                                 0x0400);
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
                                 0x0004);
        }
        bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
@@ -8292,6 +8356,9 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
        struct bnx2x *bp = params->bp;
        DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
 
+       /* SPF+ PHY: Set flag to check for Tx error */
+       vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
+
        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
        bnx2x_wait_reset_complete(bp, phy, params);
 
@@ -8312,9 +8379,9 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
                bnx2x_cl45_write(bp, phy,
                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
                                 0x400);
        } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
                   (phy->speed_cap_mask &
@@ -8340,14 +8407,14 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
                 * change
                 */
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
                                 0x400);
 
        } else { /* Default 10G. Set only LASI control */
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
        }
 
        /* Set TX PreEmphasis if needed */
@@ -8460,6 +8527,9 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
        struct bnx2x *bp = params->bp;
        /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
 
+       /* SPF+ PHY: Set flag to check for Tx error */
+       vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
+
        bnx2x_wait_reset_complete(bp, phy, params);
        rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
        /* Should be 0x6 to enable XS on Tx side. */
@@ -8468,13 +8538,13 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
        DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
        /* enable LASI */
        bnx2x_cl45_write(bp, phy,
-                        MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+                        MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
                         rx_alarm_ctrl_val);
        bnx2x_cl45_write(bp, phy,
-                        MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL,
+                        MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
                         0);
        bnx2x_cl45_write(bp, phy,
-                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
+                        MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val);
 
        /*
         * Initially configure MOD_ABS to interrupt when module is
@@ -8516,7 +8586,7 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
                        MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
 
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
 
        /* Set option 1G speed */
        if (phy->req_line_speed == SPEED_1000) {
@@ -8656,7 +8726,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
                 */
                bnx2x_cl45_read(bp, phy,
                                MDIO_PMA_DEVAD,
-                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+                               MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
 
        } else {
                /* Module is present */
@@ -8685,7 +8755,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
                 */
                bnx2x_cl45_read(bp, phy,
                                MDIO_PMA_DEVAD,
-                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+                               MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
 
 
                if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
@@ -8715,23 +8785,23 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
 
        /* If PHY is not initialized, do not check link status */
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
                        &lasi_ctrl);
        if (!lasi_ctrl)
                return 0;
 
        /* Check the LASI on Rx */
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
                        &rx_alarm_status);
        vars->line_speed = 0;
        DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
 
-       bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM,
-                            MDIO_PMA_REG_TX_ALARM_CTRL);
+       bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
+                            MDIO_PMA_LASI_TXCTRL);
 
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
 
        DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
 
@@ -8765,7 +8835,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
                        /* Disable all RX_ALARMs except for mod_abs */
                        bnx2x_cl45_write(bp, phy,
                                         MDIO_PMA_DEVAD,
-                                        MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
+                                        MDIO_PMA_LASI_RXCTRL, (1<<5));
 
                        bnx2x_cl45_read(bp, phy,
                                        MDIO_PMA_DEVAD,
@@ -8778,7 +8848,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
                        /* Clear RX alarm */
                        bnx2x_cl45_read(bp, phy,
                                MDIO_PMA_DEVAD,
-                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+                               MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
                        return 0;
                }
        } /* Over current check */
@@ -8788,7 +8858,7 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
                bnx2x_8727_handle_mod_abs(phy, params);
                /* Enable all mod_abs and link detection bits */
                bnx2x_cl45_write(bp, phy,
-                                MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
+                                MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
                                 ((1<<5) | (1<<2)));
        }
        DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
@@ -8828,10 +8898,10 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
        /* Capture 10G link fault. */
        if (vars->line_speed == SPEED_10000) {
                bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
-                           MDIO_PMA_REG_TX_ALARM, &val1);
+                           MDIO_PMA_LASI_TXSTAT, &val1);
 
                bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
-                           MDIO_PMA_REG_TX_ALARM, &val1);
+                           MDIO_PMA_LASI_TXSTAT, &val1);
 
                if (val1 & (1<<0)) {
                        vars->fault_detected = 1;
@@ -8871,7 +8941,7 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
        /* Disable Transmitter */
        bnx2x_sfp_set_transmitter(params, phy, 0);
        /* Clear LASI */
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
 
 }
 
@@ -10067,7 +10137,7 @@ static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
        bnx2x_wait_reset_complete(bp, phy, params);
 
        bnx2x_cl45_write(bp, phy,
-                        MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
+                        MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
        DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
@@ -10099,9 +10169,9 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
        u8 link_up;
        u16 val1, val2;
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
+                       MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
        DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
                   val2, val1);
        bnx2x_cl45_read(bp, phy,
@@ -11832,6 +11902,135 @@ int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
        return rc;
 }
 
+static void bnx2x_check_over_curr(struct link_params *params,
+                                 struct link_vars *vars)
+{
+       struct bnx2x *bp = params->bp;
+       u32 cfg_pin;
+       u8 port = params->port;
+       u32 pin_val;
+
+       cfg_pin = (REG_RD(bp, params->shmem_base +
+                         offsetof(struct shmem_region,
+                              dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
+                  PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
+               PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
+
+       /* Ignore check if no external input PIN available */
+       if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0)
+               return;
+
+       if (!pin_val) {
+               if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
+                       netdev_err(bp->dev, "Error:  Power fault on Port %d has"
+                                           " been detected and the power to "
+                                           "that SFP+ module has been removed"
+                                           " to prevent failure of the card."
+                                           " Please remove the SFP+ module and"
+                                           " restart the system to clear this"
+                                           " error.\n",
+                        params->port);
+                       vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
+               }
+       } else
+               vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
+}
+
+static void bnx2x_analyze_link_error(struct link_params *params,
+                                    struct link_vars *vars, u32 lss_status)
+{
+       struct bnx2x *bp = params->bp;
+       /* Compare new value with previous value */
+       u8 led_mode;
+       u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0;
+
+       /*DP(NETIF_MSG_LINK, "CHECK LINK: %x half_open:%x-> lss:%x\n",
+                      vars->link_up,
+                      half_open_conn, lss_status);*/
+
+       if ((lss_status ^ half_open_conn) == 0)
+               return;
+
+       /* If values differ */
+       DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up,
+                      half_open_conn, lss_status);
+
+       /*
+        * a. Update shmem->link_status accordingly
+        * b. Update link_vars->link_up
+        */
+       if (lss_status) {
+               vars->link_status &= ~LINK_STATUS_LINK_UP;
+               vars->link_up = 0;
+               vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
+               /*
+                * Set LED mode to off since the PHY doesn't know about these
+                * errors
+                */
+               led_mode = LED_MODE_OFF;
+       } else {
+               vars->link_status |= LINK_STATUS_LINK_UP;
+               vars->link_up = 1;
+               vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
+               led_mode = LED_MODE_OPER;
+       }
+       /* Update the LED according to the link state */
+       bnx2x_set_led(params, vars, led_mode, SPEED_10000);
+
+       /* Update link status in the shared memory */
+       bnx2x_update_mng(params, vars->link_status);
+
+       /* C. Trigger General Attention */
+       vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT;
+       bnx2x_notify_link_changed(bp);
+}
+
+static void bnx2x_check_half_open_conn(struct link_params *params,
+                                      struct link_vars *vars)
+{
+       struct bnx2x *bp = params->bp;
+       u32 lss_status = 0;
+       u32 mac_base;
+       /* In case link status is physically up @ 10G do */
+       if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
+               return;
+
+       if (!CHIP_IS_E3(bp) &&
+           (REG_RD(bp, MISC_REG_RESET_REG_2) &
+                  (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))) {
+               /* Check E1X / E2 BMAC */
+               u32 lss_status_reg;
+               u32 wb_data[2];
+               mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
+                       NIG_REG_INGRESS_BMAC0_MEM;
+               /*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
+               if (CHIP_IS_E2(bp))
+                       lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
+               else
+                       lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
+
+               REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
+               lss_status = (wb_data[0] > 0);
+
+               bnx2x_analyze_link_error(params, vars, lss_status);
+       }
+}
+
+void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
+{
+       struct bnx2x *bp = params->bp;
+       if (!params) {
+               DP(NETIF_MSG_LINK, "Ininitliazed params !\n");
+               return;
+       }
+       /* DP(NETIF_MSG_LINK, "Periodic called vars->phy_flags 0x%x speed 0x%x
+        RESET_REG_2 0x%x\n", vars->phy_flags, vars->line_speed,
+         REG_RD(bp, MISC_REG_RESET_REG_2)); */
+       bnx2x_check_half_open_conn(params, vars);
+       if (CHIP_IS_E3(bp))
+               bnx2x_check_over_curr(params, vars);
+}
+
 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
 {
        u8 phy_index;