summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-07-11 11:53:34 +0800
committerJohn W. Linville <linville@tuxdriver.com>2008-07-14 14:52:58 -0400
commit1ff50bda6eef4466366e197541508fc69af0f0c0 (patch)
tree79499aa72caab98d52cb95602eb64d08b24c4ed4 /drivers/net/wireless/iwlwifi/iwl4965-base.c
parent6c5379077f47f6eff9c23caf8513751d2f582e72 (diff)
downloadlwn-1ff50bda6eef4466366e197541508fc69af0f0c0.tar.gz
lwn-1ff50bda6eef4466366e197541508fc69af0f0c0.zip
iwlwifi: make iwl4965_mac_conf_tx in atomic context
This patch fixes iwl4965_mac_conf_tx. A mutex was taken in atomic context leading to Oops. This patch removes the mutex and extends the hold priv->lock. None of the field of QOS is accessed without priv->lock held. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c39
1 files changed, 15 insertions, 24 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index fbb854e31bdb..55648a8c88a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -575,25 +575,14 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
/*
* QoS support
*/
-static int iwl4965_send_qos_params_command(struct iwl_priv *priv,
- struct iwl4965_qosparam_cmd *qos)
+static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
{
-
- return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl4965_qosparam_cmd), qos);
-}
-
-static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
-{
- unsigned long flags;
-
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
if (!priv->qos_data.qos_enable)
return;
- spin_lock_irqsave(&priv->lock, flags);
priv->qos_data.def_qos_parm.qos_flags = 0;
if (priv->qos_data.qos_cap.q_AP.queue_request &&
@@ -607,15 +596,14 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
if (priv->current_ht_config.is_ht)
priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
- spin_unlock_irqrestore(&priv->lock, flags);
-
if (force || iwl_is_associated(priv)) {
IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
priv->qos_data.qos_active,
priv->qos_data.def_qos_parm.qos_flags);
- iwl4965_send_qos_params_command(priv,
- &(priv->qos_data.def_qos_parm));
+ iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+ sizeof(struct iwl_qosparam_cmd),
+ &priv->qos_data.def_qos_parm, NULL);
}
}
@@ -2424,6 +2412,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
struct ieee80211_conf *conf = NULL;
int ret = 0;
DECLARE_MAC_BUF(mac);
+ unsigned long flags;
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
@@ -2513,7 +2502,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
priv->assoc_station_added = 1;
- iwl4965_activate_qos(priv, 0);
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_activate_qos(priv, 0);
+ spin_unlock_irqrestore(&priv->lock, flags);
iwl_power_update_mode(priv, 0);
/* we have just associated, don't start scan too early */
@@ -2845,6 +2836,7 @@ out:
static void iwl4965_config_ap(struct iwl_priv *priv)
{
int ret = 0;
+ unsigned long flags;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -2892,7 +2884,9 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
- iwl4965_activate_qos(priv, 1);
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_activate_qos(priv, 1);
+ spin_unlock_irqrestore(&priv->lock, flags);
iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
}
iwl4965_send_beacon_cmd(priv);
@@ -3340,15 +3334,12 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
priv->qos_data.qos_active = 1;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
- iwl4965_activate_qos(priv, 1);
+ iwl_activate_qos(priv, 1);
else if (priv->assoc_id && iwl_is_associated(priv))
- iwl4965_activate_qos(priv, 0);
+ iwl_activate_qos(priv, 0);
- mutex_unlock(&priv->mutex);
+ spin_unlock_irqrestore(&priv->lock, flags);
IWL_DEBUG_MAC80211("leave\n");
return 0;