return 0;
 }
 
+static int enic_dev_fw_info(struct enic *enic,
+       struct vnic_devcmd_fw_info **fw_info)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_fw_info(enic->vdev, fw_info);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
 static void enic_get_drvinfo(struct net_device *netdev,
        struct ethtool_drvinfo *drvinfo)
 {
        struct enic *enic = netdev_priv(netdev);
        struct vnic_devcmd_fw_info *fw_info;
 
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_fw_info(enic->vdev, &fw_info);
-       spin_unlock(&enic->devcmd_lock);
+       enic_dev_fw_info(enic, &fw_info);
 
        strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
        strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
        }
 }
 
+static int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_stats_dump(enic->vdev, vstats);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
 static void enic_get_ethtool_stats(struct net_device *netdev,
        struct ethtool_stats *stats, u64 *data)
 {
        struct vnic_stats *vstats;
        unsigned int i;
 
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_stats_dump(enic->vdev, &vstats);
-       spin_unlock(&enic->devcmd_lock);
+       enic_dev_stats_dump(enic, &vstats);
 
        for (i = 0; i < enic_n_tx_stats; i++)
                *(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset];
        }
 }
 
-static void enic_link_check(struct enic *enic)
+static void enic_msglvl_check(struct enic *enic)
 {
-       int link_status = vnic_dev_link_status(enic->vdev);
-       int carrier_ok = netif_carrier_ok(enic->netdev);
+       u32 msg_enable = vnic_dev_msg_lvl(enic->vdev);
 
-       if (link_status && !carrier_ok) {
-               printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name);
-               netif_carrier_on(enic->netdev);
-       } else if (!link_status && carrier_ok) {
-               printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name);
-               netif_carrier_off(enic->netdev);
+       if (msg_enable != enic->msg_enable) {
+               printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n",
+                       enic->netdev->name, enic->msg_enable, msg_enable);
+               enic->msg_enable = msg_enable;
        }
 }
 
        }
 }
 
-static void enic_msglvl_check(struct enic *enic)
+static void enic_link_check(struct enic *enic)
 {
-       u32 msg_enable = vnic_dev_msg_lvl(enic->vdev);
+       int link_status = vnic_dev_link_status(enic->vdev);
+       int carrier_ok = netif_carrier_ok(enic->netdev);
 
-       if (msg_enable != enic->msg_enable) {
-               printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n",
-                       enic->netdev->name, enic->msg_enable, msg_enable);
-               enic->msg_enable = msg_enable;
+       if (link_status && !carrier_ok) {
+               printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name);
+               netif_carrier_on(enic->netdev);
+       } else if (!link_status && carrier_ok) {
+               printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name);
+               netif_carrier_off(enic->netdev);
        }
 }
 
        struct net_device_stats *net_stats = &netdev->stats;
        struct vnic_stats *stats;
 
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_stats_dump(enic->vdev, &stats);
-       spin_unlock(&enic->devcmd_lock);
+       enic_dev_stats_dump(enic, &stats);
 
        net_stats->tx_packets = stats->tx.tx_frames_ok;
        net_stats->tx_bytes = stats->tx.tx_bytes_ok;
        return -EOPNOTSUPP;
 }
 
+static int enic_dev_packet_filter(struct enic *enic, int directed,
+       int multicast, int broadcast, int promisc, int allmulti)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_packet_filter(enic->vdev, directed,
+               multicast, broadcast, promisc, allmulti);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
+static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_add_addr(enic->vdev, addr);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
+static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_del_addr(enic->vdev, addr);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
 /* netif_tx_lock held, BHs disabled */
 static void enic_set_multicast_list(struct net_device *netdev)
 {
        if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS)
                mc_count = ENIC_MULTICAST_PERFECT_FILTERS;
 
-       spin_lock(&enic->devcmd_lock);
-
        if (enic->flags != flags) {
                enic->flags = flags;
-               vnic_dev_packet_filter(enic->vdev, directed,
+               enic_dev_packet_filter(enic, directed,
                        multicast, broadcast, promisc, allmulti);
        }
 
                                mc_addr[j]) == 0)
                                break;
                if (j == mc_count)
-                       enic_del_multicast_addr(enic, enic->mc_addr[i]);
+                       enic_dev_del_multicast_addr(enic, enic->mc_addr[i]);
        }
 
        for (i = 0; i < mc_count; i++) {
                                enic->mc_addr[j]) == 0)
                                break;
                if (j == enic->mc_count)
-                       enic_add_multicast_addr(enic, mc_addr[i]);
+                       enic_dev_add_multicast_addr(enic, mc_addr[i]);
        }
 
        /* Save the list to compare against next time
                memcpy(enic->mc_addr[i], mc_addr[i], ETH_ALEN);
 
        enic->mc_count = mc_count;
-
-       spin_unlock(&enic->devcmd_lock);
 }
 
 /* rtnl lock is held */
        return 0;
 }
 
+static int enic_dev_hw_version(struct enic *enic,
+       enum vnic_dev_hw_version *hw_ver)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_hw_version(enic->vdev, hw_ver);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
 static int enic_set_rq_alloc_buf(struct enic *enic)
 {
        enum vnic_dev_hw_version hw_ver;
        int err;
 
-       err = vnic_dev_hw_version(enic->vdev, &hw_ver);
+       err = enic_dev_hw_version(enic, &hw_ver);
        if (err)
                return err;
 
        }
 }
 
-static int enic_notify_set(struct enic *enic)
+static int enic_dev_notify_set(struct enic *enic)
 {
        int err;
 
        return err;
 }
 
+static int enic_dev_notify_unset(struct enic *enic)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_notify_unset(enic->vdev);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
+static int enic_dev_enable(struct enic *enic)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_enable(enic->vdev);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
+static int enic_dev_disable(struct enic *enic)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_disable(enic->vdev);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
 static void enic_notify_timer_start(struct enic *enic)
 {
        switch (vnic_dev_get_intr_mode(enic->vdev)) {
                return err;
        }
 
-       err = enic_notify_set(enic);
+       err = enic_dev_notify_set(enic);
        if (err) {
                printk(KERN_ERR PFX
                        "%s: Failed to alloc notify buffer, aborting.\n",
 
        netif_wake_queue(netdev);
        napi_enable(&enic->napi);
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_enable(enic->vdev);
-       spin_unlock(&enic->devcmd_lock);
+       enic_dev_enable(enic);
 
        for (i = 0; i < enic->intr_count; i++)
                vnic_intr_unmask(&enic->intr[i]);
        return 0;
 
 err_out_notify_unset:
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_notify_unset(enic->vdev);
-       spin_unlock(&enic->devcmd_lock);
+       enic_dev_notify_unset(enic);
 err_out_free_intr:
        enic_free_intr(enic);
 
 
        del_timer_sync(&enic->notify_timer);
 
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_disable(enic->vdev);
-       spin_unlock(&enic->devcmd_lock);
+       enic_dev_disable(enic);
        napi_disable(&enic->napi);
        netif_carrier_off(netdev);
        netif_tx_disable(netdev);
                        return err;
        }
 
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_notify_unset(enic->vdev);
-       spin_unlock(&enic->devcmd_lock);
+       enic_dev_notify_unset(enic);
        enic_free_intr(enic);
 
        for (i = 0; i < enic->wq_count; i++)
        const u8 rss_enable = 0;
        const u8 tso_ipid_split_en = 0;
        const u8 ig_vlan_strip_en = 1;
+       int err;
 
        /* Enable VLAN tag stripping.  RSS not enabled (yet).
         */
 
-       return enic_set_nic_cfg(enic,
+       spin_lock(&enic->devcmd_lock);
+       err = enic_set_nic_cfg(enic,
                rss_default_cpu, rss_hash_type,
                rss_hash_bits, rss_base_cpu,
                rss_enable, tso_ipid_split_en,
                ig_vlan_strip_en);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
+static int enic_dev_hang_notify(struct enic *enic)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_hang_notify(enic->vdev);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
 }
 
 int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
 
        rtnl_lock();
 
-       spin_lock(&enic->devcmd_lock);
-       vnic_dev_hang_notify(enic->vdev);
-       spin_unlock(&enic->devcmd_lock);
-
+       enic_dev_hang_notify(enic);
        enic_stop(enic->netdev);
        enic_dev_hang_reset(enic);
        enic_reset_multicast_list(enic);
        .ndo_start_xmit         = enic_hard_start_xmit,
        .ndo_get_stats          = enic_get_stats,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = enic_set_multicast_list,
        .ndo_set_mac_address    = enic_set_mac_address,
+       .ndo_set_multicast_list = enic_set_multicast_list,
        .ndo_change_mtu         = enic_change_mtu,
        .ndo_vlan_rx_register   = enic_vlan_rx_register,
        .ndo_vlan_rx_add_vid    = enic_vlan_rx_add_vid,
        enic_clear_intr_mode(enic);
 }
 
+static int enic_dev_stats_clear(struct enic *enic)
+{
+       int err;
+
+       spin_lock(&enic->devcmd_lock);
+       err = vnic_dev_stats_clear(enic->vdev);
+       spin_unlock(&enic->devcmd_lock);
+
+       return err;
+}
+
 int enic_dev_init(struct enic *enic)
 {
        struct net_device *netdev = enic->netdev;
 
        enic_init_vnic_resources(enic);
 
+       /* Clear LIF stats
+        */
+       enic_dev_stats_clear(enic);
+
        err = enic_set_rq_alloc_buf(enic);
        if (err) {
                printk(KERN_ERR PFX
                }
        }
 
+       /* Setup devcmd lock
+        */
+
+       spin_lock_init(&enic->devcmd_lock);
+
        err = enic_dev_init(enic);
        if (err) {
                printk(KERN_ERR PFX
                goto err_out_dev_close;
        }
 
-       /* Setup notification timer, HW reset task, and locks
+       /* Setup notification timer, HW reset task, and wq locks
         */
 
        init_timer(&enic->notify_timer);
        for (i = 0; i < enic->wq_count; i++)
                spin_lock_init(&enic->wq_lock[i]);
 
-       spin_lock_init(&enic->devcmd_lock);
-
        /* Register net device
         */