Skip to content

Commit

Permalink
iwlwifi: more priv->mutex serialization
Browse files Browse the repository at this point in the history
Check status bits with mutex taken, because when we wait for mutex
unlock, status can change. Patch should also make remaining sync
commands be send with priv->mutex taken. That will prevent execute
these commands when we are currently reset firmware, what could
possibly cause troubles.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Stanislaw Gruszka authored and John W. Linville committed Apr 7, 2011
1 parent 3598e17 commit dc1a406
Showing 1 changed file with 20 additions and 14 deletions.
34 changes: 20 additions & 14 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,12 +483,14 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
container_of(work, struct iwl_priv, bt_full_concurrency);
struct iwl_rxon_context *ctx;

mutex_lock(&priv->mutex);

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
goto out;

/* dont send host command if rf-kill is on */
if (!iwl_is_ready_rf(priv))
return;
goto out;

IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
priv->bt_full_concurrent ?
Expand All @@ -498,15 +500,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
* LQ & RXON updated cmds must be sent before BT Config cmd
* to avoid 3-wire collisions
*/
mutex_lock(&priv->mutex);
for_each_context(priv, ctx) {
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
iwlcore_commit_rxon(priv, ctx);
}
mutex_unlock(&priv->mutex);

priv->cfg->ops->hcmd->send_bt_config(priv);
out:
mutex_unlock(&priv->mutex);
}

/**
Expand Down Expand Up @@ -2620,10 +2622,13 @@ static void iwl_bg_init_alive_start(struct work_struct *data)
struct iwl_priv *priv =
container_of(data, struct iwl_priv, init_alive_start.work);

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
mutex_lock(&priv->mutex);

if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
mutex_unlock(&priv->mutex);
return;
}

mutex_lock(&priv->mutex);
priv->cfg->ops->lib->init_alive_start(priv);
mutex_unlock(&priv->mutex);
}
Expand All @@ -2633,15 +2638,16 @@ static void iwl_bg_alive_start(struct work_struct *data)
struct iwl_priv *priv =
container_of(data, struct iwl_priv, alive_start.work);

mutex_lock(&priv->mutex);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
goto unlock;

/* enable dram interrupt */
if (priv->cfg->ops->lib->isr_ops.reset)
priv->cfg->ops->lib->isr_ops.reset(priv);

mutex_lock(&priv->mutex);
iwl_alive_start(priv);
unlock:
mutex_unlock(&priv->mutex);
}

Expand Down Expand Up @@ -3267,21 +3273,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,

IWL_DEBUG_MAC80211(priv, "enter\n");

mutex_lock(&priv->mutex);

if (iwl_is_rfkill(priv))
goto out_exit;
goto out;

if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
test_bit(STATUS_SCANNING, &priv->status))
goto out_exit;
goto out;

if (!iwl_is_associated_ctx(ctx))
goto out_exit;
goto out;

/* channel switch in progress */
if (priv->switch_rxon.switch_in_progress == true)
goto out_exit;
goto out;

mutex_lock(&priv->mutex);
if (priv->cfg->ops->lib->set_channel_switch) {

ch = channel->hw_value;
Expand Down Expand Up @@ -3337,7 +3344,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
}
out:
mutex_unlock(&priv->mutex);
out_exit:
if (!priv->switch_rxon.switch_in_progress)
ieee80211_chswitch_done(ctx->vif, false);
IWL_DEBUG_MAC80211(priv, "leave\n");
Expand Down

0 comments on commit dc1a406

Please sign in to comment.