diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/ops.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index fa1e1ce9f2be..5d5dedddd2dc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -644,6 +644,22 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | |||
644 | ieee80211_free_txskb(mvm->hw, skb); | 644 | ieee80211_free_txskb(mvm->hw, skb); |
645 | } | 645 | } |
646 | 646 | ||
647 | struct iwl_mvm_reprobe { | ||
648 | struct device *dev; | ||
649 | struct work_struct work; | ||
650 | }; | ||
651 | |||
652 | static void iwl_mvm_reprobe_wk(struct work_struct *wk) | ||
653 | { | ||
654 | struct iwl_mvm_reprobe *reprobe; | ||
655 | |||
656 | reprobe = container_of(wk, struct iwl_mvm_reprobe, work); | ||
657 | if (device_reprobe(reprobe->dev)) | ||
658 | dev_err(reprobe->dev, "reprobe failed!\n"); | ||
659 | kfree(reprobe); | ||
660 | module_put(THIS_MODULE); | ||
661 | } | ||
662 | |||
647 | static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) | 663 | static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) |
648 | { | 664 | { |
649 | iwl_abort_notification_waits(&mvm->notif_wait); | 665 | iwl_abort_notification_waits(&mvm->notif_wait); |
@@ -655,7 +671,29 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) | |||
655 | * can't recover this since we're already half suspended. | 671 | * can't recover this since we're already half suspended. |
656 | */ | 672 | */ |
657 | if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { | 673 | if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { |
658 | IWL_ERR(mvm, "Firmware error during reconfiguration! Abort.\n"); | 674 | struct iwl_mvm_reprobe *reprobe; |
675 | |||
676 | IWL_ERR(mvm, | ||
677 | "Firmware error during reconfiguration - reprobe!\n"); | ||
678 | |||
679 | /* | ||
680 | * get a module reference to avoid doing this while unloading | ||
681 | * anyway and to avoid scheduling a work with code that's | ||
682 | * being removed. | ||
683 | */ | ||
684 | if (!try_module_get(THIS_MODULE)) { | ||
685 | IWL_ERR(mvm, "Module is being unloaded - abort\n"); | ||
686 | return; | ||
687 | } | ||
688 | |||
689 | reprobe = kzalloc(sizeof(*reprobe), GFP_ATOMIC); | ||
690 | if (!reprobe) { | ||
691 | module_put(THIS_MODULE); | ||
692 | return; | ||
693 | } | ||
694 | reprobe->dev = mvm->trans->dev; | ||
695 | INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); | ||
696 | schedule_work(&reprobe->work); | ||
659 | } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && | 697 | } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && |
660 | iwlwifi_mod_params.restart_fw) { | 698 | iwlwifi_mod_params.restart_fw) { |
661 | /* | 699 | /* |