bnx2x: Remove support for emulation/FPGA
[pandora-kernel.git] / drivers / net / bnx2x / bnx2x_link.c
index 452e262..f2f367d 100644 (file)
@@ -521,22 +521,6 @@ static u8 bnx2x_emac_enable(struct link_params *params,
        /* enable emac and not bmac */
        REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
 
-       /* for paladium */
-       if (CHIP_REV_IS_EMUL(bp)) {
-               /* Use lane 1 (of lanes 0-3) */
-               REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
-               REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
-       }
-       /* for fpga */
-       else
-
-       if (CHIP_REV_IS_FPGA(bp)) {
-               /* Use lane 1 (of lanes 0-3) */
-               DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
-
-               REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
-               REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
-       } else
        /* ASIC */
        if (vars->phy_flags & PHY_XGXS_FLAG) {
                u32 ser_lane = ((params->lane_config &
@@ -654,15 +638,7 @@ static u8 bnx2x_emac_enable(struct link_params *params,
        REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
        REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
 
-       if (CHIP_REV_IS_EMUL(bp)) {
-               /* take the BigMac out of reset */
-               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
-                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
-
-               /* enable access for bmac registers */
-               REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
-       } else
-               REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
+       REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
 
        vars->mac_type = MAC_TYPE_EMAC;
        return 0;
@@ -1086,14 +1062,6 @@ static u8 bnx2x_bmac1_enable(struct link_params *params,
        wb_data[1] = 0;
        REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
                    wb_data, 2);
-       /* fix for emulation */
-       if (CHIP_REV_IS_EMUL(bp)) {
-               wb_data[0] = 0xf000;
-               wb_data[1] = 0;
-               REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
-                           wb_data, 2);
-       }
-
 
        return 0;
 }
@@ -1422,6 +1390,7 @@ static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
        }
        if (tmp & EMAC_MDIO_COMM_START_BUSY) {
                DP(NETIF_MSG_LINK, "write phy register failed\n");
+               netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
                rc = -EFAULT;
        } else {
                /* data */
@@ -1442,6 +1411,7 @@ static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
                }
                if (tmp & EMAC_MDIO_COMM_START_BUSY) {
                        DP(NETIF_MSG_LINK, "write phy register failed\n");
+                       netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
                        rc = -EFAULT;
                }
        }
@@ -1489,7 +1459,7 @@ static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
        }
        if (val & EMAC_MDIO_COMM_START_BUSY) {
                DP(NETIF_MSG_LINK, "read phy register failed\n");
-
+               netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
                *ret_val = 0;
                rc = -EFAULT;
 
@@ -1512,7 +1482,7 @@ static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
                }
                if (val & EMAC_MDIO_COMM_START_BUSY) {
                        DP(NETIF_MSG_LINK, "read phy register failed\n");
-
+                       netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
                        *ret_val = 0;
                        rc = -EFAULT;
                }
@@ -1827,6 +1797,9 @@ static u8 bnx2x_reset_unicore(struct link_params *params,
                }
        }
 
+       netdev_err(bp->dev,  "Warning: PHY was not initialized,"
+                             " Port %d\n",
+                        params->port);
        DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
        return -EINVAL;
 
@@ -2846,7 +2819,8 @@ static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
 }
 
 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
-                                    struct bnx2x_phy *phy)
+                                    struct bnx2x_phy *phy,
+                                    struct link_params *params)
 {
        u16 cnt, ctrl;
        /* Wait for soft reset to get cleared upto 1 sec */
@@ -2857,6 +2831,11 @@ static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
                        break;
                msleep(1);
        }
+
+       if (cnt == 1000)
+               netdev_err(bp->dev,  "Warning: PHY was not initialized,"
+                                     " Port %d\n",
+                        params->port);
        DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
        return cnt;
 }
@@ -4402,7 +4381,7 @@ static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
        /* HW reset */
        bnx2x_ext_phy_hw_reset(bp, params->port);
        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
-       bnx2x_wait_reset_complete(bp, phy);
+       bnx2x_wait_reset_complete(bp, phy, params);
 
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
@@ -4453,30 +4432,74 @@ static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
 /******************************************************************/
 /*                     SFP+ module Section                       */
 /******************************************************************/
-static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
+static u8 bnx2x_get_gpio_port(struct link_params *params)
+{
+       u8 gpio_port;
+       u32 swap_val, swap_override;
+       struct bnx2x *bp = params->bp;
+       if (CHIP_IS_E2(bp))
+               gpio_port = BP_PATH(bp);
+       else
+               gpio_port = params->port;
+       swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+       swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
+       return gpio_port ^ (swap_val && swap_override);
+}
+static void bnx2x_sfp_set_transmitter(struct link_params *params,
                                      struct bnx2x_phy *phy,
-                                     u8 port,
                                      u8 tx_en)
 {
        u16 val;
+       u8 port = params->port;
+       struct bnx2x *bp = params->bp;
+       u32 tx_en_mode;
 
-       DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
-                tx_en, port);
        /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
-       bnx2x_cl45_read(bp, phy,
-                     MDIO_PMA_DEVAD,
-                     MDIO_PMA_REG_PHY_IDENTIFIER,
-                     &val);
+       tx_en_mode = REG_RD(bp, params->shmem_base +
+                           offsetof(struct shmem_region,
+                                    dev_info.port_hw_config[port].sfp_ctrl)) &
+               PORT_HW_CFG_TX_LASER_MASK;
+       DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
+                          "mode = %x\n", tx_en, port, tx_en_mode);
+       switch (tx_en_mode) {
+       case PORT_HW_CFG_TX_LASER_MDIO:
 
-       if (tx_en)
-               val &= ~(1<<15);
-       else
-               val |= (1<<15);
+               bnx2x_cl45_read(bp, phy,
+                               MDIO_PMA_DEVAD,
+                               MDIO_PMA_REG_PHY_IDENTIFIER,
+                               &val);
 
-       bnx2x_cl45_write(bp, phy,
-                      MDIO_PMA_DEVAD,
-                      MDIO_PMA_REG_PHY_IDENTIFIER,
-                      val);
+               if (tx_en)
+                       val &= ~(1<<15);
+               else
+                       val |= (1<<15);
+
+               bnx2x_cl45_write(bp, phy,
+                                MDIO_PMA_DEVAD,
+                                MDIO_PMA_REG_PHY_IDENTIFIER,
+                                val);
+       break;
+       case PORT_HW_CFG_TX_LASER_GPIO0:
+       case PORT_HW_CFG_TX_LASER_GPIO1:
+       case PORT_HW_CFG_TX_LASER_GPIO2:
+       case PORT_HW_CFG_TX_LASER_GPIO3:
+       {
+               u16 gpio_pin;
+               u8 gpio_port, gpio_mode;
+               if (tx_en)
+                       gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
+               else
+                       gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
+
+               gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
+               gpio_port = bnx2x_get_gpio_port(params);
+               bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
+               break;
+       }
+       default:
+               DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
+               break;
+       }
 }
 
 static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
@@ -4797,9 +4820,9 @@ static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
        else
                vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
 
-       netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
-                            " Port %d from %s part number %s\n",
-                   params->port, vendor_name, vendor_pn);
+       netdev_err(bp->dev,  "Warning: Unqualified SFP+ module detected,"
+                             " Port %d from %s part number %s\n",
+                        params->port, vendor_name, vendor_pn);
        phy->flags |= FLAGS_SFP_NOT_APPROVED;
        return -EINVAL;
 }
@@ -4955,11 +4978,11 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
 
        switch (action) {
        case DISABLE_TX:
-               bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+               bnx2x_sfp_set_transmitter(params, phy, 0);
                break;
        case ENABLE_TX:
                if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
-                       bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
+                       bnx2x_sfp_set_transmitter(params, phy, 1);
                break;
        default:
                DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
@@ -4968,6 +4991,38 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
        }
 }
 
+static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
+                                          u8 gpio_mode)
+{
+       struct bnx2x *bp = params->bp;
+
+       u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
+                           offsetof(struct shmem_region,
+                       dev_info.port_hw_config[params->port].sfp_ctrl)) &
+               PORT_HW_CFG_FAULT_MODULE_LED_MASK;
+       switch (fault_led_gpio) {
+       case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
+               return;
+       case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
+       case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
+       case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
+       case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
+       {
+               u8 gpio_port = bnx2x_get_gpio_port(params);
+               u16 gpio_pin = fault_led_gpio -
+                       PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
+               DP(NETIF_MSG_LINK, "Set fault module-detected led "
+                                  "pin %x port %x mode %x\n",
+                              gpio_pin, gpio_port, gpio_mode);
+               bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
+       }
+       break;
+       default:
+               DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
+                              fault_led_gpio);
+       }
+}
+
 static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
                                     struct link_params *params)
 {
@@ -4990,9 +5045,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
                DP(NETIF_MSG_LINK, "Module verification failed!!\n");
                rc = -EINVAL;
                /* Turn on fault module-detected led */
-               bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
-                                 MISC_REGISTERS_GPIO_HIGH,
-                                 params->port);
+               bnx2x_set_sfp_module_fault_led(params,
+                                              MISC_REGISTERS_GPIO_HIGH);
+
                if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
                    ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
@@ -5003,10 +5058,7 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
                }
        } else {
                /* Turn off fault module-detected led */
-               DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
-               bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
-                                         MISC_REGISTERS_GPIO_LOW,
-                                         params->port);
+               bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
        }
 
        /* power up the SFP module */
@@ -5028,9 +5080,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
        if (rc == 0 ||
            (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
            PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
-               bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
+               bnx2x_sfp_set_transmitter(params, phy, 1);
        else
-               bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+               bnx2x_sfp_set_transmitter(params, phy, 0);
 
        return rc;
 }
@@ -5043,9 +5095,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
        u8 port = params->port;
 
        /* Set valid module led off */
-       bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
-                         MISC_REGISTERS_GPIO_HIGH,
-                         params->port);
+       bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
 
        /* Get current gpio val reflecting module plugged in / out*/
        gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
@@ -5076,7 +5126,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
                 */
                if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
                    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
-                       bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+                       bnx2x_sfp_set_transmitter(params, phy, 0);
        }
 }
 
@@ -5135,14 +5185,15 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
                                 struct link_params *params,
                                 struct link_vars *vars)
 {
-       u16 cnt, val;
+       u32 tx_en_mode;
+       u16 cnt, val, tmp1;
        struct bnx2x *bp = params->bp;
        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
        /* HW reset */
        bnx2x_ext_phy_hw_reset(bp, params->port);
        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
-       bnx2x_wait_reset_complete(bp, phy);
+       bnx2x_wait_reset_complete(bp, phy, params);
 
        /* Wait until fw is loaded */
        for (cnt = 0; cnt < 100; cnt++) {
@@ -5209,6 +5260,26 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
                                 0x0004);
        }
        bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
+
+       /*
+        * If TX Laser is controlled by GPIO_0, do not let PHY go into low
+        * power mode, if TX Laser is disabled
+        */
+
+       tx_en_mode = REG_RD(bp, params->shmem_base +
+                           offsetof(struct shmem_region,
+                               dev_info.port_hw_config[params->port].sfp_ctrl))
+                       & PORT_HW_CFG_TX_LASER_MASK;
+
+       if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
+               DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
+               bnx2x_cl45_read(bp, phy,
+                       MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
+               tmp1 |= 0x1;
+               bnx2x_cl45_write(bp, phy,
+                       MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
+       }
+
        return 0;
 }
 
@@ -5297,15 +5368,9 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
        u32 val;
        u32 swap_val, swap_override, aeu_gpio_mask, offset;
        DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
-       /* Restore normal power mode*/
-       bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
-                           MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
-
-       bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
-                           MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
 
        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
-       bnx2x_wait_reset_complete(bp, phy);
+       bnx2x_wait_reset_complete(bp, phy, params);
 
        bnx2x_8726_external_rom_boot(phy, params);
 
@@ -5489,13 +5554,14 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
                                 struct link_params *params,
                                 struct link_vars *vars)
 {
-       u16 tmp1, val, mod_abs;
+       u32 tx_en_mode;
+       u16 tmp1, val, mod_abs, tmp2;
        u16 rx_alarm_ctrl_val;
        u16 lasi_ctrl_val;
        struct bnx2x *bp = params->bp;
        /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
 
-       bnx2x_wait_reset_complete(bp, phy);
+       bnx2x_wait_reset_complete(bp, phy, params);
        rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
        lasi_ctrl_val = 0x0004;
 
@@ -5626,6 +5692,26 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
                                 phy->tx_preemphasis[1]);
        }
 
+       /*
+        * If TX Laser is controlled by GPIO_0, do not let PHY go into low
+        * power mode, if TX Laser is disabled
+        */
+       tx_en_mode = REG_RD(bp, params->shmem_base +
+                           offsetof(struct shmem_region,
+                               dev_info.port_hw_config[params->port].sfp_ctrl))
+                       & PORT_HW_CFG_TX_LASER_MASK;
+
+       if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
+
+               DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
+               bnx2x_cl45_read(bp, phy,
+                       MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
+               tmp2 |= 0x1000;
+               tmp2 &= 0xFFEF;
+               bnx2x_cl45_write(bp, phy,
+                       MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
+       }
+
        return 0;
 }
 
@@ -5702,7 +5788,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
 
                if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
                    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
-                       bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+                       bnx2x_sfp_set_transmitter(params, phy, 0);
 
                if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
                        bnx2x_sfp_module_detection(phy, params);
@@ -5862,7 +5948,7 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
 {
        struct bnx2x *bp = params->bp;
        /* Disable Transmitter */
-       bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
+       bnx2x_sfp_set_transmitter(params, phy, 0);
        /* Clear LASI */
        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
 
@@ -5874,19 +5960,23 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
                                           struct link_params *params)
 {
-       u16 val, fw_ver1, fw_ver2, cnt;
+       u16 val, fw_ver1, fw_ver2, cnt, adj;
        struct bnx2x *bp = params->bp;
 
+       adj = 0;
+       if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+               adj = -1;
+
        /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
        /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0014);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, 0x0000);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, 0x0300);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x0009);
 
        for (cnt = 0; cnt < 100; cnt++) {
-               bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+               bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val);
                if (val & 1)
                        break;
                udelay(5);
@@ -5900,11 +5990,11 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
 
 
        /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
-       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0000);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200);
+       bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x000A);
        for (cnt = 0; cnt < 100; cnt++) {
-               bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
+               bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val);
                if (val & 1)
                        break;
                udelay(5);
@@ -5917,9 +6007,9 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
        }
 
        /* lower 16 bits of the register SPI_FW_STATUS */
-       bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
+       bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, &fw_ver1);
        /* upper 16 bits of register SPI_FW_STATUS */
-       bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
+       bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, &fw_ver2);
 
        bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
                                  phy->ver_addr);
@@ -5928,49 +6018,53 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
 static void bnx2x_848xx_set_led(struct bnx2x *bp,
                                struct bnx2x_phy *phy)
 {
-       u16 val;
+       u16 val, adj;
+
+       adj = 0;
+       if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+               adj = -1;
 
        /* PHYC_CTL_LED_CTL */
        bnx2x_cl45_read(bp, phy,
                        MDIO_PMA_DEVAD,
-                       MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
+                       MDIO_PMA_REG_8481_LINK_SIGNAL + adj, &val);
        val &= 0xFE00;
        val |= 0x0092;
 
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD,
-                        MDIO_PMA_REG_8481_LINK_SIGNAL, val);
+                        MDIO_PMA_REG_8481_LINK_SIGNAL + adj, val);
 
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD,
-                        MDIO_PMA_REG_8481_LED1_MASK,
+                        MDIO_PMA_REG_8481_LED1_MASK + adj,
                         0x80);
 
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD,
-                        MDIO_PMA_REG_8481_LED2_MASK,
+                        MDIO_PMA_REG_8481_LED2_MASK + adj,
                         0x18);
 
        /* Select activity source by Tx and Rx, as suggested by PHY AE */
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD,
-                        MDIO_PMA_REG_8481_LED3_MASK,
+                        MDIO_PMA_REG_8481_LED3_MASK + adj,
                         0x0006);
 
        /* Select the closest activity blink rate to that in 10/100/1000 */
        bnx2x_cl45_write(bp, phy,
                        MDIO_PMA_DEVAD,
-                       MDIO_PMA_REG_8481_LED3_BLINK,
+                       MDIO_PMA_REG_8481_LED3_BLINK + adj,
                        0);
 
        bnx2x_cl45_read(bp, phy,
                        MDIO_PMA_DEVAD,
-                       MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
+                       MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, &val);
        val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
 
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD,
-                        MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
+                        MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, val);
 
        /* 'Interrupt Mask' */
        bnx2x_cl45_write(bp, phy,
@@ -6117,7 +6211,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
 
        /* HW reset */
        bnx2x_ext_phy_hw_reset(bp, params->port);
-       bnx2x_wait_reset_complete(bp, phy);
+       bnx2x_wait_reset_complete(bp, phy, params);
 
        bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
        return bnx2x_848xx_cmn_config_init(phy, params, vars);
@@ -6129,12 +6223,15 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
 {
        struct bnx2x *bp = params->bp;
        u8 port, initialize = 1;
-       u16 val;
+       u16 val, adj;
        u16 temp;
-       u32 actual_phy_selection;
+       u32 actual_phy_selection, cms_enable;
        u8 rc = 0;
 
        /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
+       adj = 0;
+       if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+               adj = 3;
 
        msleep(1);
        if (CHIP_IS_E2(bp))
@@ -6144,7 +6241,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
        bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
                       port);
-       bnx2x_wait_reset_complete(bp, phy);
+       bnx2x_wait_reset_complete(bp, phy, params);
        /* Wait for GPHY to come out of reset */
        msleep(50);
        /*
@@ -6159,7 +6256,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
        /* Set dual-media configuration according to configuration */
 
        bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
-                       MDIO_CTL_REG_84823_MEDIA, &val);
+                       MDIO_CTL_REG_84823_MEDIA + adj, &val);
        val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
                 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
                 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
@@ -6192,7 +6289,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
 
        bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
-                        MDIO_CTL_REG_84823_MEDIA, val);
+                        MDIO_CTL_REG_84823_MEDIA + adj, val);
        DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
                   params->multi_phy_config, val);
 
@@ -6200,6 +6297,21 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
                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 +
+                       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);
+
+
        return rc;
 }
 
@@ -6208,15 +6320,20 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
                                  struct link_vars *vars)
 {
        struct bnx2x *bp = params->bp;
-       u16 val, val1, val2;
+       u16 val, val1, val2, adj;
        u8 link_up = 0;
 
+       /* Reg offset adjustment for 84833 */
+       adj = 0;
+       if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+               adj = -1;
+
        /* Check 10G-BaseT link status */
        /* Check PMD signal ok */
        bnx2x_cl45_read(bp, phy,
                        MDIO_AN_DEVAD, 0xFFFA, &val1);
        bnx2x_cl45_read(bp, phy,
-                       MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
+                       MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL + adj,
                        &val2);
        DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
 
@@ -6544,7 +6661,7 @@ static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
        /* HW reset */
        bnx2x_ext_phy_hw_reset(bp, params->port);
-       bnx2x_wait_reset_complete(bp, phy);
+       bnx2x_wait_reset_complete(bp, phy, params);
 
        bnx2x_cl45_write(bp, phy,
                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
@@ -7041,6 +7158,43 @@ static struct bnx2x_phy phy_84823 = {
        .phy_specific_func = (phy_specific_func_t)NULL
 };
 
+static struct bnx2x_phy phy_84833 = {
+       .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
+       .addr           = 0xff,
+       .flags          = FLAGS_FAN_FAILURE_DET_REQ |
+                           FLAGS_REARM_LATCH_SIGNAL,
+       .def_md_devad   = 0,
+       .reserved       = 0,
+       .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_100baseT_Full |
+                          SUPPORTED_1000baseT_Full |
+                          SUPPORTED_10000baseT_Full |
+                          SUPPORTED_TP |
+                          SUPPORTED_Autoneg |
+                          SUPPORTED_Pause |
+                          SUPPORTED_Asym_Pause),
+       .media_type     = ETH_PHY_BASE_T,
+       .ver_addr       = 0,
+       .req_flow_ctrl  = 0,
+       .req_line_speed = 0,
+       .speed_cap_mask = 0,
+       .req_duplex     = 0,
+       .rsrv           = 0,
+       .config_init    = (config_init_t)bnx2x_848x3_config_init,
+       .read_status    = (read_status_t)bnx2x_848xx_read_status,
+       .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,
+       .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
+       .phy_specific_func = (phy_specific_func_t)NULL
+};
+
 /*****************************************************************/
 /*                                                               */
 /* Populate the phy according. Main function: bnx2x_populate_phy   */
@@ -7194,6 +7348,9 @@ static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
                *phy = phy_84823;
                break;
+       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
+               *phy = phy_84833;
+               break;
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
                *phy = phy_7101;
                break;
@@ -7489,57 +7646,6 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
        set_phy_vars(params);
 
        DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
-       if (CHIP_REV_IS_FPGA(bp)) {
-
-               vars->link_up = 1;
-               vars->line_speed = SPEED_10000;
-               vars->duplex = DUPLEX_FULL;
-               vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
-               vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
-               /* enable on E1.5 FPGA */
-               if (CHIP_IS_E1H(bp)) {
-                       vars->flow_ctrl |=
-                                       (BNX2X_FLOW_CTRL_TX |
-                                        BNX2X_FLOW_CTRL_RX);
-                       vars->link_status |=
-                                       (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
-                                        LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
-               }
-
-               bnx2x_emac_enable(params, vars, 0);
-               if (!(CHIP_IS_E2(bp)))
-                       bnx2x_pbf_update(params, vars->flow_ctrl,
-                                        vars->line_speed);
-               /* disable drain */
-               REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
-
-               /* update shared memory */
-               bnx2x_update_mng(params, vars->link_status);
-
-               return 0;
-
-       } else
-       if (CHIP_REV_IS_EMUL(bp)) {
-
-               vars->link_up = 1;
-               vars->line_speed = SPEED_10000;
-               vars->duplex = DUPLEX_FULL;
-               vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
-               vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
-
-               bnx2x_bmac_enable(params, vars, 0);
-
-               bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
-               /* Disable drain */
-               REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
-                                   + params->port*4, 0);
-
-               /* update shared memory */
-               bnx2x_update_mng(params, vars->link_status);
-
-               return 0;
-
-       } else
        if (params->loopback_mode == LOOPBACK_BMAC) {
 
                vars->link_up = 1;
@@ -7878,12 +7984,57 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
 
        return 0;
 }
+static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
+                                        u8 *io_gpio, u8 *io_port)
+{
+
+       u32 phy_gpio_reset = REG_RD(bp, shmem_base +
+                                         offsetof(struct shmem_region,
+                               dev_info.port_hw_config[PORT_0].default_cfg));
+       switch (phy_gpio_reset) {
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
+               *io_gpio = 0;
+               *io_port = 0;
+               break;
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
+               *io_gpio = 1;
+               *io_port = 0;
+               break;
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
+               *io_gpio = 2;
+               *io_port = 0;
+               break;
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
+               *io_gpio = 3;
+               *io_port = 0;
+               break;
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
+               *io_gpio = 0;
+               *io_port = 1;
+               break;
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
+               *io_gpio = 1;
+               *io_port = 1;
+               break;
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
+               *io_gpio = 2;
+               *io_port = 1;
+               break;
+       case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
+               *io_gpio = 3;
+               *io_port = 1;
+               break;
+       default:
+               /* Don't override the io_gpio and io_port */
+               break;
+       }
+}
 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
                                     u32 shmem_base_path[],
                                     u32 shmem2_base_path[], u8 phy_index,
                                     u32 chip_id)
 {
-       s8 port;
+       s8 port, reset_gpio;
        u32 swap_val, swap_override;
        struct bnx2x_phy phy[PORT_MAX];
        struct bnx2x_phy *phy_blk[PORT_MAX];
@@ -7891,13 +8042,26 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
        swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
        swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
 
+       reset_gpio = MISC_REGISTERS_GPIO_1;
        port = 1;
 
-       bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
+       /*
+        * Retrieve the reset gpio/port which control the reset.
+        * Default is GPIO1, PORT1
+        */
+       bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
+                                    (u8 *)&reset_gpio, (u8 *)&port);
 
        /* Calculate the port based on port swap */
        port ^= (swap_val && swap_override);
 
+       /* Initiate PHY reset*/
+       bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
+                      port);
+       msleep(1);
+       bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+                      port);
+
        msleep(5);
 
        /* PART1 - Reset both phys */
@@ -8000,6 +8164,10 @@ static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
                break;
        }
 
+       if (rc != 0)
+               netdev_err(bp->dev,  "Warning: PHY was not initialized,"
+                                     " Port %d\n",
+                        0);
        return rc;
 }
 
@@ -8012,9 +8180,6 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
        u32 ext_phy_type, ext_phy_config;
        DP(NETIF_MSG_LINK, "Begin common phy init\n");
 
-       if (CHIP_REV_IS_EMUL(bp))
-               return 0;
-
        /* Check if common init was already done */
        phy_ver = REG_RD(bp, shmem_base_path[0] +
                         offsetof(struct shmem_region,