iwlwifi: serialize station management actions
authorReinette Chatre <reinette.chatre@intel.com>
Fri, 28 May 2010 16:28:39 +0000 (09:28 -0700)
committerReinette Chatre <reinette.chatre@intel.com>
Mon, 14 Jun 2010 17:51:16 +0000 (10:51 -0700)
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>
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl3945-base.c

index 7726e67044c08b91a36d41759b2dfd22c19ae263..24aff654fa9c44251b11f3d12ab63d639ea06384 100644 (file)
@@ -3391,10 +3391,12 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
        int ret;
        u8 sta_id;
 
-       sta_priv->common.sta_id = IWL_INVALID_STATION;
-
        IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
                        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);
        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",
                        sta->addr, ret);
                /* Should we return success if return code is EEXIST ? */
+               mutex_unlock(&priv->mutex);
                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",
                       sta->addr);
        iwl_rs_rate_init(priv, sta, sta_id);
+       mutex_unlock(&priv->mutex);
 
        return 0;
 }
index 83a26361a9b56b35d4364c93b9f9df32905c8cc6..c27c13fbb1aec26bac302623b96d089e1f13c0dd 100644 (file)
@@ -1373,10 +1373,14 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
 
        IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
                        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);
        if (ret)
                IWL_ERR(priv, "Error removing station %pM\n",
                        sta->addr);
+       mutex_unlock(&priv->mutex);
        return ret;
 }
 EXPORT_SYMBOL(iwl_mac_sta_remove);
index 6c353cacc8d663f43d1a19c4b4bebcb697d61e45..a27872de41061d62cec0af818aa72f88927396da 100644 (file)
@@ -3437,10 +3437,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
        bool is_ap = vif->type == NL80211_IFTYPE_STATION;
        u8 sta_id;
 
-       sta_priv->common.sta_id = IWL_INVALID_STATION;
-
        IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
                        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,
                                     &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",
                        sta->addr, ret);
                /* Should we return success if return code is EEXIST ? */
+               mutex_unlock(&priv->mutex);
                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",
                       sta->addr);
        iwl3945_rs_rate_init(priv, sta, sta_id);
+       mutex_unlock(&priv->mutex);
 
        return 0;
 }