iwlwifi: serialize station management actions
We are seeing some race conditions between incoming station management requests (station add/remove) and the internal unassoc RXON command that modifies station table. Modify these flows to require the mutex to be held and thus serializing them. This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2207 Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
This commit is contained in:
Родитель
b054b747a6
Коммит
da5ae1cfff
|
@ -3391,10 +3391,12 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
|
||||||
int ret;
|
int ret;
|
||||||
u8 sta_id;
|
u8 sta_id;
|
||||||
|
|
||||||
sta_priv->common.sta_id = IWL_INVALID_STATION;
|
|
||||||
|
|
||||||
IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
|
IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
|
||||||
sta->addr);
|
sta->addr);
|
||||||
|
mutex_lock(&priv->mutex);
|
||||||
|
IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
|
||||||
|
sta->addr);
|
||||||
|
sta_priv->common.sta_id = IWL_INVALID_STATION;
|
||||||
|
|
||||||
atomic_set(&sta_priv->pending_frames, 0);
|
atomic_set(&sta_priv->pending_frames, 0);
|
||||||
if (vif->type == NL80211_IFTYPE_AP)
|
if (vif->type == NL80211_IFTYPE_AP)
|
||||||
|
@ -3406,6 +3408,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
|
||||||
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
|
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
|
||||||
sta->addr, ret);
|
sta->addr, ret);
|
||||||
/* Should we return success if return code is EEXIST ? */
|
/* Should we return success if return code is EEXIST ? */
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3415,6 +3418,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
|
||||||
IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
|
IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
|
||||||
sta->addr);
|
sta->addr);
|
||||||
iwl_rs_rate_init(priv, sta, sta_id);
|
iwl_rs_rate_init(priv, sta, sta_id);
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1373,10 +1373,14 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
|
IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
|
||||||
sta->addr);
|
sta->addr);
|
||||||
|
mutex_lock(&priv->mutex);
|
||||||
|
IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
|
||||||
|
sta->addr);
|
||||||
ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
|
ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
|
||||||
if (ret)
|
if (ret)
|
||||||
IWL_ERR(priv, "Error removing station %pM\n",
|
IWL_ERR(priv, "Error removing station %pM\n",
|
||||||
sta->addr);
|
sta->addr);
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iwl_mac_sta_remove);
|
EXPORT_SYMBOL(iwl_mac_sta_remove);
|
||||||
|
|
|
@ -3437,10 +3437,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
|
||||||
bool is_ap = vif->type == NL80211_IFTYPE_STATION;
|
bool is_ap = vif->type == NL80211_IFTYPE_STATION;
|
||||||
u8 sta_id;
|
u8 sta_id;
|
||||||
|
|
||||||
sta_priv->common.sta_id = IWL_INVALID_STATION;
|
|
||||||
|
|
||||||
IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
|
IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
|
||||||
sta->addr);
|
sta->addr);
|
||||||
|
mutex_lock(&priv->mutex);
|
||||||
|
IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
|
||||||
|
sta->addr);
|
||||||
|
sta_priv->common.sta_id = IWL_INVALID_STATION;
|
||||||
|
|
||||||
|
|
||||||
ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
|
ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
|
||||||
&sta_id);
|
&sta_id);
|
||||||
|
@ -3448,6 +3451,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
|
||||||
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
|
IWL_ERR(priv, "Unable to add station %pM (%d)\n",
|
||||||
sta->addr, ret);
|
sta->addr, ret);
|
||||||
/* Should we return success if return code is EEXIST ? */
|
/* Should we return success if return code is EEXIST ? */
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3457,6 +3461,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
|
||||||
IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
|
IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
|
||||||
sta->addr);
|
sta->addr);
|
||||||
iwl3945_rs_rate_init(priv, sta, sta_id);
|
iwl3945_rs_rate_init(priv, sta, sta_id);
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче