Merge branch 'devicetree/next' of git://git.secretlab.ca/git/linux-2.6
[pandora-kernel.git] / drivers / net / bnx2x / bnx2x_link.c
index a5c3488..bcd8f00 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                       */
 /******************************************************************/
@@ -1313,28 +1344,21 @@ static void bnx2x_update_pfc_xmac(struct link_params *params,
        REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
        REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
 
-       udelay(30);
-}
-
-
-static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
-                                    u32 pfc_frames_sent[2],
-                                    u32 pfc_frames_received[2])
-{
-       /* Read pfc statistic */
-       struct bnx2x *bp = params->bp;
-       u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
-               NIG_REG_INGRESS_BMAC0_MEM;
 
-       DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
+       /* Set MAC address for source TX Pause/PFC frames */
+       REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO,
+              ((params->mac_addr[2] << 24) |
+               (params->mac_addr[3] << 16) |
+               (params->mac_addr[4] << 8) |
+               (params->mac_addr[5])));
+       REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI,
+              ((params->mac_addr[0] << 8) |
+               (params->mac_addr[1])));
 
-       REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
-                                       pfc_frames_sent, 2);
+       udelay(30);
+}
 
-       REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
-                                       pfc_frames_received, 2);
 
-}
 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
                                    u32 pfc_frames_sent[2],
                                    u32 pfc_frames_received[2])
@@ -1366,28 +1390,23 @@ static void bnx2x_emac_get_pfc_stat(struct link_params *params,
        pfc_frames_sent[0] = val_xon + val_xoff;
 }
 
+/* Read pfc statistic*/
 void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
                         u32 pfc_frames_sent[2],
                         u32 pfc_frames_received[2])
 {
        /* Read pfc statistic */
        struct bnx2x *bp = params->bp;
-       u32 val = 0;
+
        DP(NETIF_MSG_LINK, "pfc statistic\n");
 
        if (!vars->link_up)
                return;
 
-       val = REG_RD(bp, MISC_REG_RESET_REG_2);
-       if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
-           == 0) {
-               DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
+       if (MAC_TYPE_EMAC == vars->mac_type) {
+               DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n");
                bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
                                        pfc_frames_received);
-       } else {
-               DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
-               bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
-                                        pfc_frames_received);
        }
 }
 /******************************************************************/
@@ -1530,6 +1549,16 @@ static void bnx2x_umac_enable(struct link_params *params,
        REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
        udelay(50);
 
+       /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
+       REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
+              ((params->mac_addr[2] << 24) |
+               (params->mac_addr[3] << 16) |
+               (params->mac_addr[4] << 8) |
+               (params->mac_addr[5])));
+       REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1,
+              ((params->mac_addr[0] << 8) |
+               (params->mac_addr[1])));
+
        /* Enable RX and TX */
        val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
        val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
@@ -2327,6 +2356,15 @@ int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
 
        return 0;
 }
+static void bnx2x_update_mng(struct link_params *params, u32 link_status)
+{
+       struct bnx2x *bp = params->bp;
+
+       REG_WR(bp, params->shmem_base +
+              offsetof(struct shmem_region,
+                       port_mb[params->port].link_status), link_status);
+}
+
 static void bnx2x_update_pfc_nig(struct link_params *params,
                struct link_vars *vars,
                struct bnx2x_nig_brb_pfc_port_params *nig_params)
@@ -2436,6 +2474,14 @@ int bnx2x_update_pfc(struct link_params *params,
        struct bnx2x *bp = params->bp;
        int bnx2x_status = 0;
        u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
+
+       if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
+               vars->link_status |= LINK_STATUS_PFC_ENABLED;
+       else
+               vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
+
+       bnx2x_update_mng(params, vars->link_status);
+
        /* update NIG params */
        bnx2x_update_pfc_nig(params, vars, pfc_params);
 
@@ -2537,6 +2583,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 +2654,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;
 }
 
@@ -2648,16 +2710,6 @@ static int bnx2x_bmac_enable(struct link_params *params,
        return rc;
 }
 
-
-static void bnx2x_update_mng(struct link_params *params, u32 link_status)
-{
-       struct bnx2x *bp = params->bp;
-
-       REG_WR(bp, params->shmem_base +
-              offsetof(struct shmem_region,
-                       port_mb[params->port].link_status), link_status);
-}
-
 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
 {
        u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
@@ -3478,7 +3530,7 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
                vars->flow_ctrl = params->req_fc_auto_adv;
        else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
                ret = 1;
-               if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616) {
+               if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
                        bnx2x_cl22_read(bp, phy,
                                        0x4, &ld_pause);
                        bnx2x_cl22_read(bp, phy,
@@ -3512,7 +3564,7 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
                                        struct link_params *params,
                                        struct link_vars *vars) {
-       u16 val16 = 0, lane;
+       u16 val16 = 0, lane, bam37 = 0;
        struct bnx2x *bp = params->bp;
        DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
        /* Check adding advertisement for 1G KX */
@@ -3564,6 +3616,18 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
        bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
                         MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
 
+       /* Enable CL37 BAM */
+       if (REG_RD(bp, params->shmem_base +
+                  offsetof(struct shmem_region, dev_info.
+                           port_hw_config[params->port].default_cfg)) &
+           PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
+               bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+                               MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37);
+               bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+                       MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1);
+               DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
+       }
+
        /* Advertise pause */
        bnx2x_ext_phy_set_pause(params, phy, vars);
 
@@ -4406,6 +4470,14 @@ void bnx2x_link_status_update(struct link_params *params,
 
        vars->aeu_int_mask = REG_RD(bp, sync_offset);
 
+       /* Sync PFC status */
+       if (vars->link_status & LINK_STATUS_PFC_ENABLED)
+               params->feature_config_flags |=
+                                       FEATURE_CONFIG_PFC_ENABLED;
+       else
+               params->feature_config_flags &=
+                                       ~FEATURE_CONFIG_PFC_ENABLED;
+
        DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
                 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
        DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
@@ -5489,7 +5561,7 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
        u16 cnt, ctrl;
        /* Wait for soft reset to get cleared up to 1 sec */
        for (cnt = 0; cnt < 1000; cnt++) {
-               if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616)
+               if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
                        bnx2x_cl22_read(bp, phy,
                                MDIO_PMA_REG_CTRL, &ctrl);
                else
@@ -6081,7 +6153,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 +6198,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 +6208,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 +6224,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 +6284,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 +6846,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 +6856,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 +6990,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 +7006,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);
 
@@ -7110,6 +7195,30 @@ static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
 /******************************************************************/
 /*                     SFP+ module Section                       */
 /******************************************************************/
+static void bnx2x_set_disable_pmd_transmit(struct link_params *params,
+                                          struct bnx2x_phy *phy,
+                                          u8 pmd_dis)
+{
+       struct bnx2x *bp = params->bp;
+       /*
+        * Disable transmitter only for bootcodes which can enable it afterwards
+        * (for D3 link)
+        */
+       if (pmd_dis) {
+               if (params->feature_config_flags &
+                    FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED)
+                       DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n");
+               else {
+                       DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n");
+                       return;
+               }
+       } else
+               DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n");
+       bnx2x_cl45_write(bp, phy,
+                        MDIO_PMA_DEVAD,
+                        MDIO_PMA_REG_TX_DISABLE, pmd_dis);
+}
+
 static u8 bnx2x_get_gpio_port(struct link_params *params)
 {
        u8 gpio_port;
@@ -7819,6 +7928,9 @@ static void bnx2x_warpcore_power_module(struct link_params *params,
                        dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
                        PORT_HW_CFG_E3_PWR_DIS_MASK) >>
                        PORT_HW_CFG_E3_PWR_DIS_SHIFT;
+
+       if (pin_cfg == PIN_CFG_NA)
+               return;
        DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
                       power, pin_cfg);
        /*
@@ -7828,6 +7940,12 @@ static void bnx2x_warpcore_power_module(struct link_params *params,
        bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
 }
 
+static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,
+                                   struct link_params *params)
+{
+       bnx2x_warpcore_power_module(params, phy, 0);
+}
+
 static void bnx2x_power_sfp_module(struct link_params *params,
                                   struct bnx2x_phy *phy,
                                   u8 power)
@@ -8049,16 +8167,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 +8207,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 +8227,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 +8273,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 +8300,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 +8414,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 +8437,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 +8465,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 +8585,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 +8596,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
@@ -8494,6 +8622,9 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
 
 
+       /* Enable/Disable PHY transmitter output */
+       bnx2x_set_disable_pmd_transmit(params, phy, 0);
+
        /* Make MOD_ABS give interrupt on change */
        bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
                        &val);
@@ -8516,7 +8647,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 +8787,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 +8816,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 +8846,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 +8896,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 +8909,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 +8919,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 +8959,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;
@@ -8868,10 +8999,14 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
                                  struct link_params *params)
 {
        struct bnx2x *bp = params->bp;
+
+       /* Enable/Disable PHY transmitter output */
+       bnx2x_set_disable_pmd_transmit(params, phy, 1);
+
        /* 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);
 
 }
 
@@ -9047,11 +9182,14 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
                         an_1000_val);
 
-       /* set 10 speed advertisement */
+       /* set 100 speed advertisement */
        if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
             (phy->speed_cap_mask &
-            (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
-             PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
+             (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
+              PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) &&
+            (phy->supported &
+             (SUPPORTED_100baseT_Half |
+              SUPPORTED_100baseT_Full)))) {
                an_10_100_val |= (1<<7);
                /* Enable autoneg and restart autoneg for legacy speeds */
                autoneg_val |= (1<<9 | 1<<12);
@@ -9062,9 +9200,12 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
        }
        /* set 10 speed advertisement */
        if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
-           (phy->speed_cap_mask &
-         (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
-          PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
+            (phy->speed_cap_mask &
+             (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
+              PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) &&
+            (phy->supported &
+             (SUPPORTED_10baseT_Half |
+              SUPPORTED_10baseT_Full)))) {
                an_10_100_val |= (1<<5);
                autoneg_val |= (1<<9 | 1<<12);
                if (phy->req_duplex == DUPLEX_FULL)
@@ -9073,7 +9214,10 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
        }
 
        /* Only 10/100 are allowed to work in FORCE mode */
-       if (phy->req_line_speed == SPEED_100) {
+       if ((phy->req_line_speed == SPEED_100) &&
+           (phy->supported &
+            (SUPPORTED_100baseT_Half |
+             SUPPORTED_100baseT_Full))) {
                autoneg_val |= (1<<13);
                /* Enabled AUTO-MDIX when autoneg is disabled */
                bnx2x_cl45_write(bp, phy,
@@ -9081,7 +9225,10 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
                                 (1<<15 | 1<<9 | 7<<0));
                DP(NETIF_MSG_LINK, "Setting 100M force\n");
        }
-       if (phy->req_line_speed == SPEED_10) {
+       if ((phy->req_line_speed == SPEED_10) &&
+           (phy->supported &
+            (SUPPORTED_10baseT_Half |
+             SUPPORTED_10baseT_Full))) {
                /* Enabled AUTO-MDIX when autoneg is disabled */
                bnx2x_cl45_write(bp, phy,
                                 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
@@ -9149,11 +9296,22 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
                                   struct link_vars *vars)
 {
        u32 idx;
+       u32 pair_swap;
        u16 val;
-       u16 data = 0x01b1;
+       u16 data;
        struct bnx2x *bp = params->bp;
        /* Do pair swap */
 
+       /* Check for configuration. */
+       pair_swap = REG_RD(bp, params->shmem_base +
+                          offsetof(struct shmem_region,
+                       dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
+               PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
+
+       if (pair_swap == 0)
+               return 0;
+
+       data = (u16)pair_swap;
 
        /* Write CMD_OPEN_OVERRIDE to STATUS reg */
        bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
@@ -9198,6 +9356,88 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
        return 0;
 }
 
+
+static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp,
+                                     u32 shmem_base_path[],
+                                     u32 chip_id)
+{
+       u32 reset_pin[2];
+       u32 idx;
+       u8 reset_gpios;
+       if (CHIP_IS_E3(bp)) {
+               /* Assume that these will be GPIOs, not EPIOs. */
+               for (idx = 0; idx < 2; idx++) {
+                       /* Map config param to register bit. */
+                       reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
+                               offsetof(struct shmem_region,
+                               dev_info.port_hw_config[0].e3_cmn_pin_cfg));
+                       reset_pin[idx] = (reset_pin[idx] &
+                               PORT_HW_CFG_E3_PHY_RESET_MASK) >>
+                               PORT_HW_CFG_E3_PHY_RESET_SHIFT;
+                       reset_pin[idx] -= PIN_CFG_GPIO0_P0;
+                       reset_pin[idx] = (1 << reset_pin[idx]);
+               }
+               reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
+       } else {
+               /* E2, look from diff place of shmem. */
+               for (idx = 0; idx < 2; idx++) {
+                       reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
+                               offsetof(struct shmem_region,
+                               dev_info.port_hw_config[0].default_cfg));
+                       reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
+                       reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
+                       reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
+                       reset_pin[idx] = (1 << reset_pin[idx]);
+               }
+               reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
+       }
+
+       return reset_gpios;
+}
+
+static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
+                               struct link_params *params)
+{
+       struct bnx2x *bp = params->bp;
+       u8 reset_gpios;
+       u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base +
+                               offsetof(struct shmem2_region,
+                               other_shmem_base_addr));
+
+       u32 shmem_base_path[2];
+       shmem_base_path[0] = params->shmem_base;
+       shmem_base_path[1] = other_shmem_base_addr;
+
+       reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path,
+                                                 params->chip_id);
+
+       bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
+       udelay(10);
+       DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n",
+               reset_gpios);
+
+       return 0;
+}
+
+static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
+                                               u32 shmem_base_path[],
+                                               u32 chip_id)
+{
+       u8 reset_gpios;
+
+       reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
+
+       bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
+       udelay(10);
+       bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
+       msleep(800);
+       DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
+               reset_gpios);
+
+       return 0;
+}
+
+#define PHY84833_CONSTANT_LATENCY 1193
 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                                   struct link_params *params,
                                   struct link_vars *vars)
@@ -9206,7 +9446,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
        u8 port, initialize = 1;
        u16 val;
        u16 temp;
-       u32 actual_phy_selection, cms_enable;
+       u32 actual_phy_selection, cms_enable, idx;
        int rc = 0;
 
        msleep(1);
@@ -9221,17 +9461,11 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                               MISC_REGISTERS_GPIO_OUTPUT_HIGH,
                               port);
        } else {
+               /* MDIO reset */
                bnx2x_cl45_write(bp, phy,
                                MDIO_PMA_DEVAD,
                                MDIO_PMA_REG_CTRL, 0x8000);
-       }
-
-       bnx2x_wait_reset_complete(bp, phy, params);
-       /* Wait for GPHY to come out of reset */
-       msleep(50);
-
-       /* Bring PHY out of super isolate mode */
-       if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
+               /* Bring PHY out of super isolate mode */
                bnx2x_cl45_read(bp, phy,
                                MDIO_CTL_DEVAD,
                                MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
@@ -9239,9 +9473,13 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                bnx2x_cl45_write(bp, phy,
                                MDIO_CTL_DEVAD,
                                MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
-               bnx2x_wait_reset_complete(bp, phy, params);
        }
 
+       bnx2x_wait_reset_complete(bp, phy, params);
+
+       /* Wait for GPHY to come out of reset */
+       msleep(50);
+
        if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
                bnx2x_84833_pair_swap_cfg(phy, params, vars);
 
@@ -9263,8 +9501,14 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
                 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
                 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
-       val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
-               MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
+
+       if (CHIP_IS_E3(bp)) {
+               val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
+                        MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
+       } else {
+               val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
+                       MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
+       }
 
        actual_phy_selection = bnx2x_phy_selection(params);
 
@@ -9294,24 +9538,86 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
        DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
                   params->multi_phy_config, val);
 
+       /* AutogrEEEn */
+       if (params->feature_config_flags &
+               FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
+               /* Ensure that f/w is ready */
+               for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
+                       bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
+                                       MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
+                       if (val == PHY84833_CMD_OPEN_FOR_CMDS)
+                               break;
+                       usleep_range(1000, 1000);
+               }
+               if (idx >= PHY84833_HDSHK_WAIT) {
+                       DP(NETIF_MSG_LINK, "AutogrEEEn: FW not ready.\n");
+                       return -EINVAL;
+               }
+
+               /* Select EEE mode */
+               bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+                               MDIO_84833_TOP_CFG_SCRATCH_REG3,
+                               0x2);
+
+               /* Set Idle and Latency */
+               bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+                               MDIO_84833_TOP_CFG_SCRATCH_REG4,
+                               PHY84833_CONSTANT_LATENCY + 1);
+
+               bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+                               MDIO_84833_TOP_CFG_DATA3_REG,
+                               PHY84833_CONSTANT_LATENCY + 1);
+
+               bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+                               MDIO_84833_TOP_CFG_DATA4_REG,
+                               PHY84833_CONSTANT_LATENCY);
+
+               /* Send EEE instruction to command register */
+               bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+                               MDIO_84833_TOP_CFG_SCRATCH_REG0,
+                               PHY84833_DIAG_CMD_SET_EEE_MODE);
+
+               /* Ensure that the command has completed */
+               for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
+                       bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
+                                       MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
+                       if ((val == PHY84833_CMD_COMPLETE_PASS) ||
+                               (val == PHY84833_CMD_COMPLETE_ERROR))
+                               break;
+                       usleep_range(1000, 1000);
+               }
+               if ((idx >= PHY84833_HDSHK_WAIT) ||
+                       (val == PHY84833_CMD_COMPLETE_ERROR)) {
+                       DP(NETIF_MSG_LINK, "AutogrEEEn: command failed.\n");
+                       return -EINVAL;
+               }
+
+               /* Reset command handler */
+               bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+                           MDIO_84833_TOP_CFG_SCRATCH_REG2,
+                           PHY84833_CMD_CLEAR_COMPLETE);
+       }
+
        if (initialize)
                rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
        else
                bnx2x_save_848xx_spirom_version(phy, params);
-       cms_enable = REG_RD(bp, params->shmem_base +
+       /* 84833 PHY has a better feature and doesn't need to support this. */
+       if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
+               cms_enable = REG_RD(bp, params->shmem_base +
                        offsetof(struct shmem_region,
                        dev_info.port_hw_config[params->port].default_cfg)) &
                        PORT_HW_CFG_ENABLE_CMS_MASK;
 
-       bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
-               MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
-       if (cms_enable)
-               val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
-       else
-               val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
-       bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
-               MDIO_CTL_REG_84823_USER_CTRL_REG, val);
-
+               bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
+                               MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
+               if (cms_enable)
+                       val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
+               else
+                       val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
+               bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
+                                MDIO_CTL_REG_84823_USER_CTRL_REG, val);
+       }
 
        return rc;
 }
@@ -9435,6 +9741,7 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
 {
        struct bnx2x *bp = params->bp;
        u8 port;
+       u16 val16;
 
        if (!(CHIP_IS_E1(bp)))
                port = BP_PATH(bp);
@@ -9446,9 +9753,14 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
                               MISC_REGISTERS_GPIO_OUTPUT_LOW,
                               port);
        } else {
-               bnx2x_cl45_write(bp, phy,
-                               MDIO_PMA_DEVAD,
-                               MDIO_PMA_REG_CTRL, 0x800);
+               bnx2x_cl45_read(bp, phy,
+                               MDIO_CTL_DEVAD,
+                               0x400f, &val16);
+               /* Put to low power mode on newer FW */
+               if ((val16 & 0x303f) > 0x1009)
+                       bnx2x_cl45_write(bp, phy,
+                                       MDIO_PMA_DEVAD,
+                                       MDIO_PMA_REG_CTRL, 0x800);
        }
 }
 
@@ -9647,11 +9959,21 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
                }
                break;
        }
+
+       /*
+        * This is a workaround for E3+84833 until autoneg
+        * restart is fixed in f/w
+        */
+       if (CHIP_IS_E3(bp)) {
+               bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+                               MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
+       }
 }
+
 /******************************************************************/
-/*                     54616S PHY SECTION                        */
+/*                     54618SE PHY SECTION                       */
 /******************************************************************/
-static int bnx2x_54616s_config_init(struct bnx2x_phy *phy,
+static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
                                               struct link_params *params,
                                               struct link_vars *vars)
 {
@@ -9660,7 +9982,7 @@ static int bnx2x_54616s_config_init(struct bnx2x_phy *phy,
        u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
        u32 cfg_pin;
 
-       DP(NETIF_MSG_LINK, "54616S cfg init\n");
+       DP(NETIF_MSG_LINK, "54618SE cfg init\n");
        usleep_range(1000, 1000);
 
        /* This works with E3 only, no need to check the chip
@@ -9809,6 +10131,30 @@ static int bnx2x_54616s_config_init(struct bnx2x_phy *phy,
                DP(NETIF_MSG_LINK, "Setting 10M force\n");
        }
 
+       /* Check if we should turn on Auto-GrEEEn */
+       bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
+       if (temp == MDIO_REG_GPHY_ID_54618SE) {
+               if (params->feature_config_flags &
+                   FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
+                       temp = 6;
+                       DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
+               } else {
+                       temp = 0;
+                       DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
+               }
+               bnx2x_cl22_write(bp, phy,
+                                MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
+               bnx2x_cl22_write(bp, phy,
+                                MDIO_REG_GPHY_CL45_DATA_REG,
+                                MDIO_REG_GPHY_EEE_ADV);
+               bnx2x_cl22_write(bp, phy,
+                                MDIO_REG_GPHY_CL45_ADDR_REG,
+                                (0x1 << 14) | MDIO_AN_DEVAD);
+               bnx2x_cl22_write(bp, phy,
+                                MDIO_REG_GPHY_CL45_DATA_REG,
+                                temp);
+       }
+
        bnx2x_cl22_write(bp, phy,
                        0x04,
                        an_10_100_val | fc_val);
@@ -9822,11 +10168,11 @@ static int bnx2x_54616s_config_init(struct bnx2x_phy *phy,
        return 0;
 }
 
-static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy,
-                                     struct link_params *params, u8 mode)
+static void bnx2x_54618se_set_link_led(struct bnx2x_phy *phy,
+                                      struct link_params *params, u8 mode)
 {
        struct bnx2x *bp = params->bp;
-       DP(NETIF_MSG_LINK, "54616S set link led (mode=%x)\n", mode);
+       DP(NETIF_MSG_LINK, "54618SE set link led (mode=%x)\n", mode);
        switch (mode) {
        case LED_MODE_FRONT_PANEL_OFF:
        case LED_MODE_OFF:
@@ -9838,8 +10184,8 @@ static void bnx2x_54616s_set_link_led(struct bnx2x_phy *phy,
        return;
 }
 
-static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy,
-                                   struct link_params *params)
+static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
+                                    struct link_params *params)
 {
        struct bnx2x *bp = params->bp;
        u32 cfg_pin;
@@ -9858,9 +10204,9 @@ static void bnx2x_54616s_link_reset(struct bnx2x_phy *phy,
        bnx2x_set_cfg_pin(bp, cfg_pin, 0);
 }
 
-static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy,
-                                  struct link_params *params,
-                                  struct link_vars *vars)
+static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
+                                   struct link_params *params,
+                                   struct link_vars *vars)
 {
        struct bnx2x *bp = params->bp;
        u16 val;
@@ -9871,7 +10217,7 @@ static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy,
        bnx2x_cl22_read(bp, phy,
                        0x19,
                        &legacy_status);
-       DP(NETIF_MSG_LINK, "54616S read_status: 0x%x\n", legacy_status);
+       DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status);
 
        /* Read status to clear the PHY interrupt. */
        bnx2x_cl22_read(bp, phy,
@@ -9923,21 +10269,45 @@ static u8 bnx2x_54616s_read_status(struct bnx2x_phy *phy,
                        vars->link_status |=
                                LINK_STATUS_PARALLEL_DETECTION_USED;
 
-               DP(NETIF_MSG_LINK, "BCM54616S: link speed is %d\n",
+               DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
                           vars->line_speed);
+
+               /* Report whether EEE is resolved. */
+               bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val);
+               if (val == MDIO_REG_GPHY_ID_54618SE) {
+                       if (vars->link_status &
+                           LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
+                               val = 0;
+                       else {
+                               bnx2x_cl22_write(bp, phy,
+                                       MDIO_REG_GPHY_CL45_ADDR_REG,
+                                       MDIO_AN_DEVAD);
+                               bnx2x_cl22_write(bp, phy,
+                                       MDIO_REG_GPHY_CL45_DATA_REG,
+                                       MDIO_REG_GPHY_EEE_RESOLVED);
+                               bnx2x_cl22_write(bp, phy,
+                                       MDIO_REG_GPHY_CL45_ADDR_REG,
+                                       (0x1 << 14) | MDIO_AN_DEVAD);
+                               bnx2x_cl22_read(bp, phy,
+                                       MDIO_REG_GPHY_CL45_DATA_REG,
+                                       &val);
+                       }
+                       DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val);
+               }
+
                bnx2x_ext_phy_resolve_fc(phy, params, vars);
        }
        return link_up;
 }
 
-static void bnx2x_54616s_config_loopback(struct bnx2x_phy *phy,
-                                      struct link_params *params)
+static void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy,
+                                         struct link_params *params)
 {
        struct bnx2x *bp = params->bp;
        u16 val;
        u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
 
-       DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54616s\n");
+       DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n");
 
        /* Enable master/slave manual mmode and set to master */
        /* mii write 9 [bits set 11 12] */
@@ -9999,7 +10369,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));
@@ -10031,9 +10401,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,
@@ -10261,7 +10631,7 @@ static struct bnx2x_phy phy_warpcore = {
        .link_reset     = (link_reset_t)bnx2x_warpcore_link_reset,
        .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
        .format_fw_ver  = (format_fw_ver_t)NULL,
-       .hw_reset       = (hw_reset_t)NULL,
+       .hw_reset       = (hw_reset_t)bnx2x_warpcore_hw_reset,
        .set_link_led   = (set_link_led_t)NULL,
        .phy_specific_func = (phy_specific_func_t)NULL
 };
@@ -10527,9 +10897,7 @@ static struct bnx2x_phy phy_84833 = {
        .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
        .mdio_ctrl      = 0,
-       .supported      = (SUPPORTED_10baseT_Half |
-                          SUPPORTED_10baseT_Full |
-                          SUPPORTED_100baseT_Half |
+       .supported      = (SUPPORTED_100baseT_Half |
                           SUPPORTED_100baseT_Full |
                           SUPPORTED_1000baseT_Full |
                           SUPPORTED_10000baseT_Full |
@@ -10549,13 +10917,13 @@ static struct bnx2x_phy phy_84833 = {
        .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
        .config_loopback = (config_loopback_t)NULL,
        .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
-       .hw_reset       = (hw_reset_t)NULL,
+       .hw_reset       = (hw_reset_t)bnx2x_84833_hw_reset_phy,
        .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
        .phy_specific_func = (phy_specific_func_t)NULL
 };
 
-static struct bnx2x_phy phy_54616s = {
-       .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616,
+static struct bnx2x_phy phy_54618se = {
+       .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
        .addr           = 0xff,
        .def_md_devad   = 0,
        .flags          = FLAGS_INIT_XGXS_FIRST,
@@ -10578,13 +10946,13 @@ static struct bnx2x_phy phy_54616s = {
        .speed_cap_mask = 0,
        /* req_duplex = */0,
        /* rsrv = */0,
-       .config_init    = (config_init_t)bnx2x_54616s_config_init,
-       .read_status    = (read_status_t)bnx2x_54616s_read_status,
-       .link_reset     = (link_reset_t)bnx2x_54616s_link_reset,
-       .config_loopback = (config_loopback_t)bnx2x_54616s_config_loopback,
+       .config_init    = (config_init_t)bnx2x_54618se_config_init,
+       .read_status    = (read_status_t)bnx2x_54618se_read_status,
+       .link_reset     = (link_reset_t)bnx2x_54618se_link_reset,
+       .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
        .format_fw_ver  = (format_fw_ver_t)NULL,
        .hw_reset       = (hw_reset_t)NULL,
-       .set_link_led   = (set_link_led_t)bnx2x_54616s_set_link_led,
+       .set_link_led   = (set_link_led_t)bnx2x_54618se_set_link_led,
        .phy_specific_func = (phy_specific_func_t)NULL
 };
 /*****************************************************************/
@@ -10827,8 +11195,8 @@ static int bnx2x_populate_ext_phy(struct bnx2x *bp,
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
                *phy = phy_84833;
                break;
-       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
-               *phy = phy_54616s;
+       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
+               *phy = phy_54618se;
                break;
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
                *phy = phy_7101;
@@ -11666,6 +12034,10 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
                if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
                                                      port_of_path))
                        return -EINVAL;
+               /* Disable PHY transmitter output */
+               bnx2x_cl45_write(bp, phy_blk[port],
+                                MDIO_PMA_DEVAD,
+                                MDIO_PMA_REG_TX_DISABLE, 1);
 
        }
        return 0;
@@ -11700,6 +12072,13 @@ static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
                                                shmem2_base_path,
                                                phy_index, chip_id);
                break;
+       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
+               /*
+                * GPIO3's are linked, and so both need to be toggled
+                * to obtain required 2us pulse.
+                */
+               rc = bnx2x_84833_common_init_phy(bp, shmem_base_path, chip_id);
+               break;
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
                rc = -EINVAL;
                break;
@@ -11757,6 +12136,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;
@@ -11799,7 +12307,15 @@ u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
 void bnx2x_hw_reset_phy(struct link_params *params)
 {
        u8 phy_index;
-       for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
+       struct bnx2x *bp = params->bp;
+       bnx2x_update_mng(params, 0);
+       bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
+                      (NIG_MASK_XGXS0_LINK_STATUS |
+                       NIG_MASK_XGXS0_LINK10G |
+                       NIG_MASK_SERDES0_LINK_STATUS |
+                       NIG_MASK_MI_INT));
+
+       for (phy_index = INT_PHY; phy_index < MAX_PHYS;
              phy_index++) {
                if (params->phy[phy_index].hw_reset) {
                        params->phy[phy_index].hw_reset(