aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-07-10 23:53:34 -0400
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)
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 fbb854e31bd..55648a8c88a 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,
575/* 575/*
576 * QoS support 576 * QoS support
577*/ 577*/
578static int iwl4965_send_qos_params_command(struct iwl_priv *priv, 578static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
579 struct iwl4965_qosparam_cmd *qos)
580{ 579{
581
582 return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,
583 sizeof(struct iwl4965_qosparam_cmd), qos);
584}
585
586static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
587{
588 unsigned long flags;
589
590 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 580 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
591 return; 581 return;
592 582
593 if (!priv->qos_data.qos_enable) 583 if (!priv->qos_data.qos_enable)
594 return; 584 return;
595 585
596 spin_lock_irqsave(&priv->lock, flags);
597 priv->qos_data.def_qos_parm.qos_flags = 0; 586 priv->qos_data.def_qos_parm.qos_flags = 0;
598 587
599 if (priv->qos_data.qos_cap.q_AP.queue_request && 588 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)
607 if (priv->current_ht_config.is_ht) 596 if (priv->current_ht_config.is_ht)
608 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; 597 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
609 598
610 spin_unlock_irqrestore(&priv->lock, flags);
611
612 if (force || iwl_is_associated(priv)) { 599 if (force || iwl_is_associated(priv)) {
613 IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", 600 IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
614 priv->qos_data.qos_active, 601 priv->qos_data.qos_active,
615 priv->qos_data.def_qos_parm.qos_flags); 602 priv->qos_data.def_qos_parm.qos_flags);
616 603
617 iwl4965_send_qos_params_command(priv, 604 iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
618 &(priv->qos_data.def_qos_parm)); 605 sizeof(struct iwl_qosparam_cmd),
606 &priv->qos_data.def_qos_parm, NULL);
619 } 607 }
620} 608}
621 609
@@ -2424,6 +2412,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
2424 struct ieee80211_conf *conf = NULL; 2412 struct ieee80211_conf *conf = NULL;
2425 int ret = 0; 2413 int ret = 0;
2426 DECLARE_MAC_BUF(mac); 2414 DECLARE_MAC_BUF(mac);
2415 unsigned long flags;
2427 2416
2428 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { 2417 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
2429 IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); 2418 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)
2513 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) 2502 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
2514 priv->assoc_station_added = 1; 2503 priv->assoc_station_added = 1;
2515 2504
2516 iwl4965_activate_qos(priv, 0); 2505 spin_lock_irqsave(&priv->lock, flags);
2506 iwl_activate_qos(priv, 0);
2507 spin_unlock_irqrestore(&priv->lock, flags);
2517 2508
2518 iwl_power_update_mode(priv, 0); 2509 iwl_power_update_mode(priv, 0);
2519 /* we have just associated, don't start scan too early */ 2510 /* we have just associated, don't start scan too early */
@@ -2845,6 +2836,7 @@ out:
2845static void iwl4965_config_ap(struct iwl_priv *priv) 2836static void iwl4965_config_ap(struct iwl_priv *priv)
2846{ 2837{
2847 int ret = 0; 2838 int ret = 0;
2839 unsigned long flags;
2848 2840
2849 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2841 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2850 return; 2842 return;
@@ -2892,7 +2884,9 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
2892 /* restore RXON assoc */ 2884 /* restore RXON assoc */
2893 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2885 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
2894 iwl4965_commit_rxon(priv); 2886 iwl4965_commit_rxon(priv);
2895 iwl4965_activate_qos(priv, 1); 2887 spin_lock_irqsave(&priv->lock, flags);
2888 iwl_activate_qos(priv, 1);
2889 spin_unlock_irqrestore(&priv->lock, flags);
2896 iwl_rxon_add_station(priv, iwl_bcast_addr, 0); 2890 iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
2897 } 2891 }
2898 iwl4965_send_beacon_cmd(priv); 2892 iwl4965_send_beacon_cmd(priv);
@@ -3340,15 +3334,12 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
3340 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; 3334 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
3341 priv->qos_data.qos_active = 1; 3335 priv->qos_data.qos_active = 1;
3342 3336
3343 spin_unlock_irqrestore(&priv->lock, flags);
3344
3345 mutex_lock(&priv->mutex);
3346 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) 3337 if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
3347 iwl4965_activate_qos(priv, 1); 3338 iwl_activate_qos(priv, 1);
3348 else if (priv->assoc_id && iwl_is_associated(priv)) 3339 else if (priv->assoc_id && iwl_is_associated(priv))
3349 iwl4965_activate_qos(priv, 0); 3340 iwl_activate_qos(priv, 0);
3350 3341
3351 mutex_unlock(&priv->mutex); 3342 spin_unlock_irqrestore(&priv->lock, flags);
3352 3343
3353 IWL_DEBUG_MAC80211("leave\n"); 3344 IWL_DEBUG_MAC80211("leave\n");
3354 return 0; 3345 return 0;