diff options
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 72 |
1 files changed, 20 insertions, 52 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index b88b1e001f07..77e280a00a5d 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -2622,77 +2622,45 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw, | |||
2622 | priv->vif = NULL; | 2622 | priv->vif = NULL; |
2623 | } | 2623 | } |
2624 | 2624 | ||
2625 | struct mwl8k_config_worker { | 2625 | static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) |
2626 | struct mwl8k_work_struct header; | ||
2627 | u32 changed; | ||
2628 | }; | ||
2629 | |||
2630 | static int mwl8k_config_wt(struct work_struct *wt) | ||
2631 | { | 2626 | { |
2632 | struct mwl8k_config_worker *worker = | ||
2633 | (struct mwl8k_config_worker *)wt; | ||
2634 | struct ieee80211_hw *hw = worker->header.hw; | ||
2635 | struct ieee80211_conf *conf = &hw->conf; | 2627 | struct ieee80211_conf *conf = &hw->conf; |
2636 | struct mwl8k_priv *priv = hw->priv; | 2628 | struct mwl8k_priv *priv = hw->priv; |
2637 | int rc = 0; | 2629 | int rc; |
2638 | 2630 | ||
2639 | if (conf->flags & IEEE80211_CONF_IDLE) { | 2631 | if (conf->flags & IEEE80211_CONF_IDLE) { |
2640 | mwl8k_cmd_802_11_radio_disable(hw); | 2632 | mwl8k_cmd_802_11_radio_disable(hw); |
2641 | priv->current_channel = NULL; | 2633 | priv->current_channel = NULL; |
2642 | goto mwl8k_config_exit; | 2634 | return 0; |
2643 | } | 2635 | } |
2644 | 2636 | ||
2645 | if (mwl8k_cmd_802_11_radio_enable(hw)) { | 2637 | rc = mwl8k_fw_lock(hw); |
2646 | rc = -EINVAL; | 2638 | if (rc) |
2647 | goto mwl8k_config_exit; | 2639 | return rc; |
2648 | } | ||
2649 | 2640 | ||
2650 | priv->current_channel = conf->channel; | 2641 | rc = mwl8k_cmd_802_11_radio_enable(hw); |
2642 | if (rc) | ||
2643 | goto out; | ||
2651 | 2644 | ||
2652 | if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) { | 2645 | rc = mwl8k_cmd_set_rf_channel(hw, conf->channel); |
2653 | rc = -EINVAL; | 2646 | if (rc) |
2654 | goto mwl8k_config_exit; | 2647 | goto out; |
2655 | } | 2648 | |
2649 | priv->current_channel = conf->channel; | ||
2656 | 2650 | ||
2657 | if (conf->power_level > 18) | 2651 | if (conf->power_level > 18) |
2658 | conf->power_level = 18; | 2652 | conf->power_level = 18; |
2659 | if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) { | 2653 | rc = mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level); |
2660 | rc = -EINVAL; | 2654 | if (rc) |
2661 | goto mwl8k_config_exit; | 2655 | goto out; |
2662 | } | ||
2663 | 2656 | ||
2664 | if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7)) | 2657 | if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7)) |
2665 | rc = -EINVAL; | 2658 | rc = -EINVAL; |
2666 | 2659 | ||
2667 | mwl8k_config_exit: | 2660 | out: |
2668 | return rc; | 2661 | mwl8k_fw_unlock(hw); |
2669 | } | ||
2670 | |||
2671 | static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) | ||
2672 | { | ||
2673 | int rc = 0; | ||
2674 | struct mwl8k_config_worker *worker; | ||
2675 | |||
2676 | worker = kzalloc(sizeof(*worker), GFP_KERNEL); | ||
2677 | if (worker == NULL) | ||
2678 | return -ENOMEM; | ||
2679 | |||
2680 | worker->changed = changed; | ||
2681 | |||
2682 | rc = mwl8k_queue_work(hw, &worker->header, mwl8k_config_wt); | ||
2683 | if (rc == -ETIMEDOUT) { | ||
2684 | printk(KERN_ERR "%s() timed out.\n", __func__); | ||
2685 | rc = -EINVAL; | ||
2686 | } | ||
2687 | |||
2688 | kfree(worker); | ||
2689 | 2662 | ||
2690 | /* | 2663 | return rc; |
2691 | * mac80211 will crash on anything other than -EINVAL on | ||
2692 | * error. Looks like wireless extensions which calls mac80211 | ||
2693 | * may be the actual culprit... | ||
2694 | */ | ||
2695 | return rc ? -EINVAL : 0; | ||
2696 | } | 2664 | } |
2697 | 2665 | ||
2698 | struct mwl8k_bss_info_changed_worker { | 2666 | struct mwl8k_bss_info_changed_worker { |