diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2008-07-10 23:53:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-14 14:52:58 -0400 |
commit | 1ff50bda6eef4466366e197541508fc69af0f0c0 (patch) | |
tree | 79499aa72caab98d52cb95602eb64d08b24c4ed4 /drivers/net/wireless/iwlwifi/iwl4965-base.c | |
parent | 6c5379077f47f6eff9c23caf8513751d2f582e72 (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.c | 39 |
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 | */ |
578 | static int iwl4965_send_qos_params_command(struct iwl_priv *priv, | 578 | static 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 | |||
586 | static 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: | |||
2845 | static void iwl4965_config_ap(struct iwl_priv *priv) | 2836 | static 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; |