return 0;
 }
 
+/**
+ * qlcnic_83xx_idc_vnic_pf_entry
+ *
+ * @adapter: adapter structure
+ *
+ * Ensure vNIC mode privileged function starts only after vNIC mode is
+ * enabled by management function.
+ * If vNIC mode is ready, start initialization.
+ *
+ * Returns: -EIO or 0
+ *
+ **/
+int qlcnic_83xx_idc_vnic_pf_entry(struct qlcnic_adapter *adapter)
+{
+       u32 state;
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+
+       /* Privileged function waits till mgmt function enables VNIC mode */
+       state = QLCRDX(adapter->ahw, QLC_83XX_VNIC_STATE);
+       if (state != QLCNIC_DEV_NPAR_OPER) {
+               if (!ahw->idc.vnic_wait_limit--) {
+                       qlcnic_83xx_idc_enter_failed_state(adapter, 1);
+                       return -EIO;
+               }
+               dev_info(&adapter->pdev->dev, "vNIC mode disabled\n");
+               return -EIO;
+
+       } else {
+               /* Perform one time initialization from ready state */
+               if (ahw->idc.vnic_state != QLCNIC_DEV_NPAR_OPER) {
+                       qlcnic_83xx_idc_update_idc_params(adapter);
+
+                       /* If the previous state is UNKNOWN, device will be
+                          already attached properly by Init routine*/
+                       if (ahw->idc.prev_state != QLC_83XX_IDC_DEV_UNKNOWN) {
+                               if (qlcnic_83xx_idc_reattach_driver(adapter))
+                                       return -EIO;
+                       }
+                       adapter->ahw->idc.vnic_state =  QLCNIC_DEV_NPAR_OPER;
+                       dev_info(&adapter->pdev->dev, "vNIC mode enabled\n");
+               }
+       }
+
+       return 0;
+}
+
 static int qlcnic_83xx_idc_unknown_state(struct qlcnic_adapter *adapter)
 {
        adapter->ahw->idc.err_code = -EIO;
                qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
                set_bit(__QLCNIC_RESETTING, &adapter->state);
                clear_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
+               if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
+                       qlcnic_83xx_disable_vnic_mode(adapter, 1);
                qlcnic_83xx_idc_detach_driver(adapter);
        }
 
        if (ret == -EIO)
                return -EIO;
 
-       if (ret == QLC_83XX_DEFAULT_MODE) {
+       if (ret == QLC_83XX_VIRTUAL_NIC_MODE) {
+               if (qlcnic_83xx_config_vnic_opmode(adapter))
+                       return -EIO;
+       } else if (ret == QLC_83XX_DEFAULT_MODE) {
                if (qlcnic_83xx_config_default_opmode(adapter))
                        return -EIO;
        }
 
--- /dev/null
+#include "qlcnic.h"
+#include "qlcnic_hw.h"
+
+int qlcnic_83xx_enable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
+{
+       if (lock) {
+               if (qlcnic_83xx_lock_driver(adapter))
+                       return -EBUSY;
+       }
+       QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_OPER);
+       if (lock)
+               qlcnic_83xx_unlock_driver(adapter);
+
+       return 0;
+}
+
+int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
+{
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+
+       if (lock) {
+               if (qlcnic_83xx_lock_driver(adapter))
+                       return -EBUSY;
+       }
+
+       QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_NON_OPER);
+       ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
+
+       if (lock)
+               qlcnic_83xx_unlock_driver(adapter);
+
+       return 0;
+}
+
+static int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
+{
+       u8 id;
+       int i, ret = -EBUSY;
+       u32 data = QLCNIC_MGMT_FUNC;
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+
+       if (qlcnic_83xx_lock_driver(adapter))
+               return ret;
+
+       if (qlcnic_config_npars) {
+               for (i = 0; i < ahw->act_pci_func; i++) {
+                       id = adapter->npars[i].pci_func;
+                       if (id == ahw->pci_func)
+                               continue;
+                       data |= qlcnic_config_npars &
+                               QLC_83XX_SET_FUNC_OPMODE(0x3, id);
+               }
+       } else {
+               data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
+               data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, ahw->pci_func)) |
+                      QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC,
+                                               ahw->pci_func);
+       }
+       QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data);
+
+       qlcnic_83xx_unlock_driver(adapter);
+
+       return 0;
+}
+
+static void
+qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
+{
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+
+       if (ahw->port_type == QLCNIC_XGBE) {
+               adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF;
+               adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF;
+               adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+               adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+
+       } else if (ahw->port_type == QLCNIC_GBE) {
+               adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
+               adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+               adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+               adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G;
+       }
+       adapter->num_txd = MAX_CMD_DESCRIPTORS;
+       adapter->max_rds_rings = MAX_RDS_RINGS;
+}
+
+
+/**
+ * qlcnic_83xx_init_mgmt_vnic
+ *
+ * @adapter: adapter structure
+ * Management virtual NIC sets the operational mode of other vNIC's and
+ * configures embedded switch (ESWITCH).
+ * Returns: Success(0) or error code.
+ *
+ **/
+static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
+{
+       int err = -EIO;
+
+       if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
+               if (qlcnic_init_pci_info(adapter))
+                       return err;
+
+               if (qlcnic_83xx_set_vnic_opmode(adapter))
+                       return err;
+
+               if (qlcnic_set_default_offload_settings(adapter))
+                       return err;
+       } else {
+               if (qlcnic_reset_npar_config(adapter))
+                       return err;
+       }
+
+       if (qlcnic_83xx_get_port_info(adapter))
+               return err;
+
+       qlcnic_83xx_config_vnic_buff_descriptors(adapter);
+       adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
+       adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
+       qlcnic_83xx_enable_vnic_mode(adapter, 1);
+
+       dev_info(&adapter->pdev->dev, "HAL Version: %d, Management function\n",
+                adapter->ahw->fw_hal_version);
+
+       return 0;
+}
+
+static int qlcnic_83xx_init_privileged_vnic(struct qlcnic_adapter *adapter)
+{
+       int err = -EIO;
+
+       if (qlcnic_83xx_get_port_info(adapter))
+               return err;
+
+       qlcnic_83xx_config_vnic_buff_descriptors(adapter);
+       adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
+       adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
+
+       dev_info(&adapter->pdev->dev,
+                "HAL Version: %d, Privileged function\n",
+                adapter->ahw->fw_hal_version);
+       return 0;
+}
+
+static int qlcnic_83xx_init_non_privileged_vnic(struct qlcnic_adapter *adapter)
+{
+       int err = -EIO;
+
+       qlcnic_83xx_get_fw_version(adapter);
+       if (qlcnic_set_eswitch_port_config(adapter))
+               return err;
+
+       if (qlcnic_83xx_get_port_info(adapter))
+               return err;
+
+       qlcnic_83xx_config_vnic_buff_descriptors(adapter);
+       adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
+       adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
+
+       dev_info(&adapter->pdev->dev, "HAL Version: %d, Virtual function\n",
+                adapter->ahw->fw_hal_version);
+
+       return 0;
+}
+
+/**
+ * qlcnic_83xx_vnic_opmode
+ *
+ * @adapter: adapter structure
+ * Identify virtual NIC operational modes.
+ *
+ * Returns: Success(0) or error code.
+ *
+ **/
+int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
+{
+       u32 op_mode, priv_level;
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+       struct qlcnic_nic_template *nic_ops = adapter->nic_ops;
+
+       qlcnic_get_func_no(adapter);
+       op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
+
+       if (op_mode == QLC_83XX_DEFAULT_OPMODE)
+               priv_level = QLCNIC_MGMT_FUNC;
+       else
+               priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
+                                                        ahw->pci_func);
+
+       if (priv_level == QLCNIC_NON_PRIV_FUNC) {
+               ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
+               ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
+               nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic;
+       } else if (priv_level == QLCNIC_PRIV_FUNC) {
+               ahw->op_mode = QLCNIC_PRIV_FUNC;
+               ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry;
+               nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic;
+       } else if (priv_level == QLCNIC_MGMT_FUNC) {
+               ahw->op_mode = QLCNIC_MGMT_FUNC;
+               ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
+               nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic;
+       } else {
+               return -EIO;
+       }
+
+       if (ahw->capabilities & BIT_23)
+               adapter->flags |= QLCNIC_ESWITCH_ENABLED;
+       else
+               adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
+
+       adapter->ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
+       adapter->ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;
+
+       return 0;
+}