aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c40
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
647struct iwl_mvm_reprobe {
648 struct device *dev;
649 struct work_struct work;
650};
651
652static 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
647static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) 663static 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 /*