|
@@ -372,6 +372,8 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
|
|
|
|
|
|
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",
|
|
@@ -382,6 +384,8 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ mutex_unlock(&wcn->conf_mutex);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -396,6 +400,8 @@ static void wcn36xx_configure_filter(struct ieee80211_hw *hw,
|
|
|
|
|
|
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n");
|
|
|
|
|
|
+ mutex_lock(&wcn->conf_mutex);
|
|
|
+
|
|
|
*total &= FIF_ALLMULTI;
|
|
|
|
|
|
fp = (void *)(unsigned long)multicast;
|
|
@@ -408,6 +414,8 @@ static void wcn36xx_configure_filter(struct ieee80211_hw *hw,
|
|
|
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);
|
|
|
}
|
|
|
|
|
@@ -471,6 +479,8 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|
|
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;
|
|
@@ -565,6 +575,8 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|
|
}
|
|
|
|
|
|
out:
|
|
|
+ mutex_unlock(&wcn->conf_mutex);
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -725,6 +737,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
|
|
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",
|
|
@@ -787,7 +801,13 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
|
|
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",
|
|
@@ -811,7 +831,6 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
|
|
* 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",
|
|
@@ -873,6 +892,9 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
|
|
}
|
|
|
}
|
|
|
out:
|
|
|
+
|
|
|
+ mutex_unlock(&wcn->conf_mutex);
|
|
|
+
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -882,7 +904,10 @@ static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
|
|
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;
|
|
|
}
|
|
|
|
|
@@ -893,8 +918,12 @@ static void wcn36xx_remove_interface(struct ieee80211_hw *hw,
|
|
|
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,
|
|
@@ -915,9 +944,13 @@ 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;
|
|
|
}
|
|
|
|
|
@@ -930,6 +963,8 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
|
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;
|
|
|
/*
|
|
@@ -941,6 +976,9 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
|
sta_priv->aid = sta->aid;
|
|
|
wcn36xx_smd_config_sta(wcn, vif, sta);
|
|
|
}
|
|
|
+
|
|
|
+ mutex_unlock(&wcn->conf_mutex);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -954,8 +992,13 @@ static int wcn36xx_sta_remove(struct ieee80211_hw *hw,
|
|
|
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;
|
|
|
}
|
|
|
|
|
@@ -999,6 +1042,8 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
|
|
|
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;
|
|
@@ -1038,6 +1083,8 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
|
|
|
wcn36xx_err("Unknown AMPDU action\n");
|
|
|
}
|
|
|
|
|
|
+ mutex_unlock(&wcn->conf_mutex);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1216,6 +1263,7 @@ static int wcn36xx_probe(struct platform_device *pdev)
|
|
|
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);
|
|
|
|