static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header)
 {
        u8 *bssid, *bssid1;
-       int i = 0;
        struct net_device *ndev = NULL;
+       struct wilc_vif *vif;
 
        bssid = mac_header + 10;
        bssid1 = mac_header + 4;
 
-       mutex_lock(&wilc->vif_mutex);
-       for (i = 0; i < wilc->vif_num; i++) {
-               if (wilc->vif[i]->mode == WILC_STATION_MODE)
-                       if (ether_addr_equal_unaligned(bssid,
-                                                      wilc->vif[i]->bssid)) {
-                               ndev = wilc->vif[i]->ndev;
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               if (vif->mode == WILC_STATION_MODE)
+                       if (ether_addr_equal_unaligned(bssid, vif->bssid)) {
+                               ndev = vif->ndev;
                                goto out;
                        }
-               if (wilc->vif[i]->mode == WILC_AP_MODE)
-                       if (ether_addr_equal_unaligned(bssid1,
-                                                      wilc->vif[i]->bssid)) {
-                               ndev = wilc->vif[i]->ndev;
+               if (vif->mode == WILC_AP_MODE)
+                       if (ether_addr_equal_unaligned(bssid1, vif->bssid)) {
+                               ndev = vif->ndev;
                                goto out;
                        }
        }
 out:
-       mutex_unlock(&wilc->vif_mutex);
        return ndev;
 }
 
 
 int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
 {
-       u8 i = 0;
+       int srcu_idx;
        u8 ret_val = 0;
+       struct wilc_vif *vif;
 
-       for (i = 0; i < wilc->vif_num; i++)
-               if (!is_zero_ether_addr(wilc->vif[i]->bssid))
+       srcu_idx = srcu_read_lock(&wilc->srcu);
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               if (!is_zero_ether_addr(vif->bssid))
                        ret_val++;
-
+       }
+       srcu_read_unlock(&wilc->srcu, srcu_idx);
        return ret_val;
 }
 
                do {
                        ret = wilc_wlan_handle_txq(wl, &txq_count);
                        if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
-                               int i;
+                               int srcu_idx;
                                struct wilc_vif *ifc;
 
-                               mutex_lock(&wl->vif_mutex);
-                               for (i = 0; i < wl->vif_num; i++) {
-                                       ifc = wl->vif[i];
+                               srcu_idx = srcu_read_lock(&wl->srcu);
+                               list_for_each_entry_rcu(ifc, &wl->vif_list,
+                                                       list) {
                                        if (ifc->mac_opened && ifc->ndev)
                                                netif_wake_queue(ifc->ndev);
                                }
-                               mutex_unlock(&wl->vif_mutex);
+                               srcu_read_unlock(&wl->srcu, srcu_idx);
                        }
                } while (ret == -ENOBUFS && !wl->close);
        }
                                                wilc_tx_complete);
 
        if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) {
-               int i;
+               int srcu_idx;
+               struct wilc_vif *vif;
 
-               mutex_lock(&wilc->vif_mutex);
-               for (i = 0; i < wilc->vif_num; i++) {
-                       if (wilc->vif[i]->mac_opened)
-                               netif_stop_queue(wilc->vif[i]->ndev);
+               srcu_idx = srcu_read_lock(&wilc->srcu);
+               list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+                       if (vif->mac_opened)
+                               netif_stop_queue(vif->ndev);
                }
-               mutex_unlock(&wilc->vif_mutex);
+               srcu_read_unlock(&wilc->srcu, srcu_idx);
        }
 
        return 0;
 
 void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size)
 {
-       int i = 0;
+       int srcu_idx;
        struct wilc_vif *vif;
 
-       mutex_lock(&wilc->vif_mutex);
-       for (i = 0; i < wilc->vif_num; i++) {
+       srcu_idx = srcu_read_lock(&wilc->srcu);
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
                u16 type = le16_to_cpup((__le16 *)buff);
 
-               vif = netdev_priv(wilc->vif[i]->ndev);
                if ((type == vif->frame_reg[0].type && vif->frame_reg[0].reg) ||
                    (type == vif->frame_reg[1].type && vif->frame_reg[1].reg)) {
                        wilc_wfi_p2p_rx(vif, buff, size);
                        break;
                }
        }
-       mutex_unlock(&wilc->vif_mutex);
+       srcu_read_unlock(&wilc->srcu, srcu_idx);
 }
 
 static const struct net_device_ops wilc_netdev_ops = {
 
 void wilc_netdev_cleanup(struct wilc *wilc)
 {
-       int i;
+       struct wilc_vif *vif;
+       int srcu_idx;
 
        if (!wilc)
                return;
                wilc->firmware = NULL;
        }
 
-       for (i = 0; i < wilc->vif_num; i++) {
-               if (wilc->vif[i] && wilc->vif[i]->ndev)
-                       unregister_netdev(wilc->vif[i]->ndev);
+       srcu_idx = srcu_read_lock(&wilc->srcu);
+       list_for_each_entry_rcu(vif, &wilc->vif_list, list) {
+               if (vif->ndev)
+                       unregister_netdev(vif->ndev);
        }
+       srcu_read_unlock(&wilc->srcu, srcu_idx);
 
        wilc_wfi_deinit_mon_interface(wilc, false);
        flush_workqueue(wilc->hif_workqueue);
        destroy_workqueue(wilc->hif_workqueue);
+
+       do {
+               mutex_lock(&wilc->vif_mutex);
+               if (wilc->vif_num <= 0) {
+                       mutex_unlock(&wilc->vif_mutex);
+                       break;
+               }
+               vif = wilc_get_wl_to_vif(wilc);
+               if (!IS_ERR(vif))
+                       list_del_rcu(&vif->list);
+
+               wilc->vif_num--;
+               mutex_unlock(&wilc->vif_mutex);
+               synchronize_srcu(&wilc->srcu);
+       } while (1);
+
        wilc_wlan_cfg_deinit(wilc);
        wlan_deinit_locks(wilc);
        kfree(wilc->bus_data);
 }
 EXPORT_SYMBOL_GPL(wilc_netdev_cleanup);
 
+static u8 wilc_get_available_idx(struct wilc *wl)
+{
+       int idx = 0;
+       struct wilc_vif *vif;
+       int srcu_idx;
+
+       srcu_idx = srcu_read_lock(&wl->srcu);
+       list_for_each_entry_rcu(vif, &wl->vif_list, list) {
+               if (vif->idx == 0)
+                       idx = 1;
+               else
+                       idx = 0;
+       }
+       srcu_read_unlock(&wl->srcu, srcu_idx);
+       return idx;
+}
+
 struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
                                      int vif_type, enum nl80211_iftype type,
                                      bool rtnl_locked)
 
        ndev->needs_free_netdev = true;
        vif->iftype = vif_type;
-       vif->wilc->vif[wl->vif_num] = vif;
-       vif->idx = wl->vif_num;
-       wl->vif_num += 1;
+       vif->idx = wilc_get_available_idx(wl);
        vif->mac_opened = 0;
+       mutex_lock(&wl->vif_mutex);
+       list_add_tail_rcu(&vif->list, &wl->vif_list);
+       wl->vif_num += 1;
+       mutex_unlock(&wl->vif_mutex);
+       synchronize_srcu(&wl->srcu);
+
        return vif;
 }
 
 
        }
 }
 
-static struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
+struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl)
 {
-       int i;
+       struct wilc_vif *vif;
 
-       for (i = 0; i < wl->vif_num; i++)
-               if (wl->vif[i])
-                       return wl->vif[i];
+       vif = list_first_or_null_rcu(&wl->vif_list, typeof(*vif), list);
+       if (!vif)
+               return ERR_PTR(-EINVAL);
 
-       return ERR_PTR(-EINVAL);
+       return vif;
 }
 
 static int set_channel(struct wiphy *wiphy,
        struct wilc_vif *vif;
        u32 channelnum;
        int result;
+       int srcu_idx;
 
-       mutex_lock(&wl->vif_mutex);
+       srcu_idx = srcu_read_lock(&wl->srcu);
        vif = wilc_get_wl_to_vif(wl);
        if (IS_ERR(vif)) {
-               mutex_unlock(&wl->vif_mutex);
+               srcu_read_unlock(&wl->srcu, srcu_idx);
                return PTR_ERR(vif);
        }
 
        if (result)
                netdev_err(vif->ndev, "Error in setting channel\n");
 
-       mutex_unlock(&wl->vif_mutex);
+       srcu_read_unlock(&wl->srcu, srcu_idx);
        return result;
 }
 
        return 0;
 }
 
-struct wilc_vif *wilc_get_interface(struct wilc *wl)
-{
-       int i;
-       struct wilc_vif *vif = NULL;
-
-       mutex_lock(&wl->vif_mutex);
-       for (i = 0; i < wl->vif_num; i++) {
-               if (wl->vif[i]) {
-                       vif = wl->vif[i];
-                       break;
-               }
-       }
-       mutex_unlock(&wl->vif_mutex);
-       return vif;
-}
-
 static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
 {
-       int ret;
+       int ret = -EINVAL;
        struct cfg_param_attr cfg_param_val;
        struct wilc *wl = wiphy_priv(wiphy);
        struct wilc_vif *vif;
        struct wilc_priv *priv;
+       int srcu_idx;
 
-       vif = wilc_get_interface(wl);
-       if (!vif)
-               return -EINVAL;
+       srcu_idx = srcu_read_lock(&wl->srcu);
+       vif = wilc_get_wl_to_vif(wl);
+       if (IS_ERR(vif))
+               goto out;
 
        priv = &vif->priv;
        cfg_param_val.flag = 0;
                } else {
                        netdev_err(vif->ndev,
                                   "Fragmentation threshold out of range\n");
-                       return -EINVAL;
+                       goto out;
                }
        }
 
                        cfg_param_val.rts_threshold = wiphy->rts_threshold;
                } else {
                        netdev_err(vif->ndev, "RTS threshold out of range\n");
-                       return -EINVAL;
+                       goto out;
                }
        }
 
        if (ret)
                netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n");
 
+out:
+       srcu_read_unlock(&wl->srcu, srcu_idx);
        return ret;
 }
 
        return ret;
 }
 
-static int wilc_get_vif_from_type(struct wilc *wl, int type)
+static struct wilc_vif *wilc_get_vif_from_type(struct wilc *wl, int type)
 {
-       int i;
+       struct wilc_vif *vif;
 
-       mutex_lock(&wl->vif_mutex);
-       for (i = 0; i < wl->vif_num; i++) {
-               if (wl->vif[i]->iftype == type) {
-                       mutex_unlock(&wl->vif_mutex);
-                       return i;
-               }
+       list_for_each_entry_rcu(vif, &wl->vif_list, list) {
+               if (vif->iftype == type)
+                       return vif;
        }
-       mutex_unlock(&wl->vif_mutex);
 
-       return -EINVAL;
+       return NULL;
 }
 
 static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
        struct wilc_vif *vif;
        struct wireless_dev *wdev;
        int iftype;
-       int ret;
 
        if (type == NL80211_IFTYPE_MONITOR) {
                struct net_device *ndev;
-               int ap_index = wilc_get_vif_from_type(wl, WILC_AP_MODE);
-
-               if (ap_index < 0) {
-                       ap_index = wilc_get_vif_from_type(wl, WILC_GO_MODE);
-                       if (ap_index < 0)
+               int srcu_idx;
+
+               srcu_idx = srcu_read_lock(&wl->srcu);
+               vif = wilc_get_vif_from_type(wl, WILC_AP_MODE);
+               if (!vif) {
+                       vif = wilc_get_vif_from_type(wl, WILC_GO_MODE);
+                       if (!vif) {
+                               srcu_read_unlock(&wl->srcu, srcu_idx);
                                goto validate_interface;
+                       }
                }
 
-               vif  = wl->vif[ap_index];
-               if (vif->monitor_flag)
+               if (vif->monitor_flag) {
+                       srcu_read_unlock(&wl->srcu, srcu_idx);
                        goto validate_interface;
+               }
 
                ndev = wilc_wfi_init_mon_interface(wl, name, vif->ndev);
-               if (ndev)
+               if (ndev) {
                        vif->monitor_flag = 1;
-               else
+               } else {
+                       srcu_read_unlock(&wl->srcu, srcu_idx);
                        return ERR_PTR(-EINVAL);
+               }
 
                wdev = &vif->priv.wdev;
+               srcu_read_unlock(&wl->srcu, srcu_idx);
                return wdev;
        }
 
        mutex_lock(&wl->vif_mutex);
        if (wl->vif_num == WILC_NUM_CONCURRENT_IFC) {
                pr_err("Reached maximum number of interface\n");
-               ret = -EINVAL;
-               goto out_err;
+               mutex_unlock(&wl->vif_mutex);
+               return ERR_PTR(-EINVAL);
        }
+       mutex_unlock(&wl->vif_mutex);
 
        switch (type) {
        case NL80211_IFTYPE_STATION:
                iftype = WILC_AP_MODE;
                break;
        default:
-               ret = -EOPNOTSUPP;
-               goto out_err;
+               return ERR_PTR(-EOPNOTSUPP);
        }
 
        vif = wilc_netdev_ifc_init(wl, name, iftype, type, true);
-       if (IS_ERR(vif)) {
-               ret = PTR_ERR(vif);
-               goto out_err;
-       }
-
-       mutex_unlock(&wl->vif_mutex);
+       if (IS_ERR(vif))
+               return ERR_CAST(vif);
 
        return &vif->priv.wdev;
-
-out_err:
-       mutex_unlock(&wl->vif_mutex);
-       return ERR_PTR(ret);
 }
 
 static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 {
        struct wilc *wl = wiphy_priv(wiphy);
        struct wilc_vif *vif;
-       int i;
 
        if (wdev->iftype == NL80211_IFTYPE_AP ||
            wdev->iftype == NL80211_IFTYPE_P2P_GO)
        unregister_netdevice(vif->ndev);
        vif->monitor_flag = 0;
 
-       mutex_lock(&wl->vif_mutex);
        wilc_set_operation_mode(vif, 0, 0, 0);
-       for (i = vif->idx; i < wl->vif_num; i++) {
-               if ((i + 1) >= wl->vif_num) {
-                       wl->vif[i] = NULL;
-               } else {
-                       vif = wl->vif[i + 1];
-                       vif->idx = i;
-                       wl->vif[i] = vif;
-                       wilc_set_operation_mode(vif, wilc_get_vif_idx(vif),
-                                               vif->iftype, vif->idx);
-               }
-       }
+       mutex_lock(&wl->vif_mutex);
+       list_del_rcu(&vif->list);
        wl->vif_num--;
        mutex_unlock(&wl->vif_mutex);
-
+       synchronize_srcu(&wl->srcu);
        return 0;
 }
 
 {
        struct wilc *wl = wiphy_priv(wiphy);
        struct wilc_vif *vif;
+       int srcu_idx;
 
-       mutex_lock(&wl->vif_mutex);
+       srcu_idx = srcu_read_lock(&wl->srcu);
        vif = wilc_get_wl_to_vif(wl);
        if (IS_ERR(vif)) {
-               mutex_unlock(&wl->vif_mutex);
+               srcu_read_unlock(&wl->srcu, srcu_idx);
                return;
        }
 
        netdev_info(vif->ndev, "cfg set wake up = %d\n", enabled);
-       mutex_unlock(&wl->vif_mutex);
+       srcu_read_unlock(&wl->srcu, srcu_idx);
 }
 
 static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
        init_completion(&wl->cfg_event);
        init_completion(&wl->sync_event);
        init_completion(&wl->txq_thread_started);
+       init_srcu_struct(&wl->srcu);
 }
 
 void wlan_deinit_locks(struct wilc *wilc)
        mutex_destroy(&wilc->cfg_cmd_lock);
        mutex_destroy(&wilc->txq_add_to_head_cs);
        mutex_destroy(&wilc->vif_mutex);
+       cleanup_srcu_struct(&wilc->srcu);
 }
 
 int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
        wl->chip_ps_state = WILC_CHIP_WAKEDUP;
        INIT_LIST_HEAD(&wl->txq_head.list);
        INIT_LIST_HEAD(&wl->rxq_head.list);
+       INIT_LIST_HEAD(&wl->vif_list);
 
        wl->hif_workqueue = create_singlethread_workqueue("WILC_wq");
        if (!wl->hif_workqueue) {