wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed);
 
+       mutex_lock(&wcn->conf_mutex);
+
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
                int ch = WCN36XX_HW_CHANNEL(wcn);
                wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n",
                }
        }
 
+       mutex_unlock(&wcn->conf_mutex);
+
        return 0;
 }
 
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n");
 
+       mutex_lock(&wcn->conf_mutex);
+
        *total &= FIF_ALLMULTI;
 
        fp = (void *)(unsigned long)multicast;
                else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc)
                        wcn36xx_smd_set_mc_list(wcn, vif, fp);
        }
+
+       mutex_unlock(&wcn->conf_mutex);
        kfree(fp);
 }
 
                         key_conf->key,
                         key_conf->keylen);
 
+       mutex_lock(&wcn->conf_mutex);
+
        switch (key_conf->cipher) {
        case WLAN_CIPHER_SUITE_WEP40:
                vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40;
        }
 
 out:
+       mutex_unlock(&wcn->conf_mutex);
+
        return ret;
 }
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n",
                    vif, changed);
 
+       mutex_lock(&wcn->conf_mutex);
+
        if (changed & BSS_CHANGED_BEACON_INFO) {
                wcn36xx_dbg(WCN36XX_DBG_MAC,
                            "mac bss changed dtim period %d\n",
                                     bss_conf->aid);
 
                        vif_priv->sta_assoc = true;
-                       rcu_read_lock();
+
+                       /*
+                        * Holding conf_mutex ensures mutal exclusion with
+                        * wcn36xx_sta_remove() and as such ensures that sta
+                        * won't be freed while we're operating on it. As such
+                        * we do not need to hold the rcu_read_lock().
+                        */
                        sta = ieee80211_find_sta(vif, bss_conf->bssid);
                        if (!sta) {
                                wcn36xx_err("sta %pM is not found\n",
                         * place where AID is available.
                         */
                        wcn36xx_smd_config_sta(wcn, vif, sta);
-                       rcu_read_unlock();
                } else {
                        wcn36xx_dbg(WCN36XX_DBG_MAC,
                                    "disassociated bss %pM vif %pM AID=%d\n",
                }
        }
 out:
+
+       mutex_unlock(&wcn->conf_mutex);
+
        return;
 }
 
        struct wcn36xx *wcn = hw->priv;
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value);
 
+       mutex_lock(&wcn->conf_mutex);
        wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value);
+       mutex_unlock(&wcn->conf_mutex);
+
        return 0;
 }
 
        struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif);
 
+       mutex_lock(&wcn->conf_mutex);
+
        list_del(&vif_priv->list);
        wcn36xx_smd_delete_sta_self(wcn, vif->addr);
+
+       mutex_unlock(&wcn->conf_mutex);
 }
 
 static int wcn36xx_add_interface(struct ieee80211_hw *hw,
                return -EOPNOTSUPP;
        }
 
+       mutex_lock(&wcn->conf_mutex);
+
        list_add(&vif_priv->list, &wcn->vif_list);
        wcn36xx_smd_add_sta_self(wcn, vif);
 
+       mutex_unlock(&wcn->conf_mutex);
+
        return 0;
 }
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n",
                    vif, sta->addr);
 
+       mutex_lock(&wcn->conf_mutex);
+
        spin_lock_init(&sta_priv->ampdu_lock);
        sta_priv->vif = vif_priv;
        /*
                sta_priv->aid = sta->aid;
                wcn36xx_smd_config_sta(wcn, vif, sta);
        }
+
+       mutex_unlock(&wcn->conf_mutex);
+
        return 0;
 }
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n",
                    vif, sta->addr, sta_priv->sta_index);
 
+       mutex_lock(&wcn->conf_mutex);
+
        wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index);
        sta_priv->vif = NULL;
+
+       mutex_unlock(&wcn->conf_mutex);
+
        return 0;
 }
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
                    action, tid);
 
+       mutex_lock(&wcn->conf_mutex);
+
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
                sta_priv->tid = tid;
                wcn36xx_err("Unknown AMPDU action\n");
        }
 
+       mutex_unlock(&wcn->conf_mutex);
+
        return 0;
 }
 
        wcn = hw->priv;
        wcn->hw = hw;
        wcn->dev = &pdev->dev;
+       mutex_init(&wcn->conf_mutex);
        mutex_init(&wcn->hal_mutex);
        mutex_init(&wcn->scan_lock);