Commit c779273b authored by Eliad Peller's avatar Eliad Peller Committed by Emmanuel Grumbach

iwlwifi: mvm: fix ROC reference accounting

commit b112889c ("iwlwifi: mvm: add Aux ROC request/response flow")
added aux ROC flow in addition to the existing ROC flow. While doing
it, it moved the ROC reference release to a common work item, which
is being called for both the ROC and aux ROC flows.

This resulted in invalid reference accounting, as no reference was
taken in case of aux ROC, while a reference was released on completion.

Fix it by adding a reference for the aux ROC as well, and release
only the relevant references on completion (according to the set bits).

While at it, convert cancel_work_sync() to flush_work(), in order
to make sure the references are being cleaned properly.

Fixes: b112889c ("iwlwifi: mvm: add Aux ROC request/response flow")
Signed-off-by: default avatarEliad Peller <eliadx.peller@intel.com>
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent a61408e9
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -1356,6 +1356,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file, ...@@ -1356,6 +1356,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN); PRINT_MVM_REF(IWL_MVM_REF_UCODE_DOWN);
PRINT_MVM_REF(IWL_MVM_REF_SCAN); PRINT_MVM_REF(IWL_MVM_REF_SCAN);
PRINT_MVM_REF(IWL_MVM_REF_ROC); PRINT_MVM_REF(IWL_MVM_REF_ROC);
PRINT_MVM_REF(IWL_MVM_REF_ROC_AUX);
PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT); PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS); PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
PRINT_MVM_REF(IWL_MVM_REF_USER); PRINT_MVM_REF(IWL_MVM_REF_USER);
......
...@@ -1410,7 +1410,7 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) ...@@ -1410,7 +1410,7 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
* The work item could be running or queued if the * The work item could be running or queued if the
* ROC time event stops just as we get here. * ROC time event stops just as we get here.
*/ */
cancel_work_sync(&mvm->roc_done_wk); flush_work(&mvm->roc_done_wk);
iwl_trans_stop_device(mvm->trans); iwl_trans_stop_device(mvm->trans);
......
...@@ -276,6 +276,7 @@ enum iwl_mvm_ref_type { ...@@ -276,6 +276,7 @@ enum iwl_mvm_ref_type {
IWL_MVM_REF_UCODE_DOWN, IWL_MVM_REF_UCODE_DOWN,
IWL_MVM_REF_SCAN, IWL_MVM_REF_SCAN,
IWL_MVM_REF_ROC, IWL_MVM_REF_ROC,
IWL_MVM_REF_ROC_AUX,
IWL_MVM_REF_P2P_CLIENT, IWL_MVM_REF_P2P_CLIENT,
IWL_MVM_REF_AP_IBSS, IWL_MVM_REF_AP_IBSS,
IWL_MVM_REF_USER, IWL_MVM_REF_USER,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -108,12 +108,14 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) ...@@ -108,12 +108,14 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
* in the case that the time event actually completed in the firmware * in the case that the time event actually completed in the firmware
* (which is handled in iwl_mvm_te_handle_notif). * (which is handled in iwl_mvm_te_handle_notif).
*/ */
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) if (test_and_clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) {
queues |= BIT(IWL_MVM_OFFCHANNEL_QUEUE); queues |= BIT(IWL_MVM_OFFCHANNEL_QUEUE);
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) iwl_mvm_unref(mvm, IWL_MVM_REF_ROC);
}
if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) {
queues |= BIT(mvm->aux_queue); queues |= BIT(mvm->aux_queue);
iwl_mvm_unref(mvm, IWL_MVM_REF_ROC_AUX);
iwl_mvm_unref(mvm, IWL_MVM_REF_ROC); }
synchronize_net(); synchronize_net();
...@@ -393,6 +395,7 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm, ...@@ -393,6 +395,7 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
} else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) { } else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) {
set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status); set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
te_data->running = true; te_data->running = true;
iwl_mvm_ref(mvm, IWL_MVM_REF_ROC_AUX);
ieee80211_ready_on_channel(mvm->hw); /* Start TE */ ieee80211_ready_on_channel(mvm->hw); /* Start TE */
} else { } else {
IWL_DEBUG_TE(mvm, IWL_DEBUG_TE(mvm,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment