Skip to content

Commit 0232d2c

Browse files
sara-slucacoelho
authored andcommitted
iwlwifi: fix access to prph when transport is stopped
When getting HW rfkill we get stop_device being called from two paths. One path is the IRQ calling stop device, and updating op mode and stack. As a result, cfg80211 is running rfkill sync work that shuts down all devices (second path). In the second path, we eventually get to iwl_mvm_stop_device which calls iwl_fw_dump_conf_clear->iwl_fw_dbg_stop_recording, that access periphery registers. The device may be stopped at this point from the first path, which will result with a failure to access those registers. Simply checking for the trans status is insufficient, since the race will still exist, only minimized. Instead, move the stop from iwl_fw_dump_conf_clear (which is getting called only from stop path) to the transport stop device function, where the access is always safe. This has the added value, of actually stopping dbgc before stopping device even when the stop is initiated from the transport. Fixes: 1efc384 ("iwlwifi: stop dbgc recording before stopping DMA") Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
1 parent f3402d6 commit 0232d2c

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

drivers/net/wireless/intel/iwlwifi/fw/dbg.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,6 @@ static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt)
209209

210210
static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
211211
{
212-
iwl_fw_dbg_stop_recording(fwrt);
213-
214212
fwrt->dump.conf = FW_DBG_INVALID;
215213
}
216214

drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
*
5050
*****************************************************************************/
5151
#include "iwl-trans.h"
52+
#include "iwl-prph.h"
5253
#include "iwl-context-info.h"
5354
#include "internal.h"
5455

@@ -156,6 +157,11 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
156157

157158
trans_pcie->is_down = true;
158159

160+
/* Stop dbgc before stopping device */
161+
iwl_write_prph(trans, DBGC_IN_SAMPLE, 0);
162+
udelay(100);
163+
iwl_write_prph(trans, DBGC_OUT_CTRL, 0);
164+
159165
/* tell the device to stop sending interrupts */
160166
iwl_disable_interrupts(trans);
161167

drivers/net/wireless/intel/iwlwifi/pcie/trans.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,15 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
12271227

12281228
trans_pcie->is_down = true;
12291229

1230+
/* Stop dbgc before stopping device */
1231+
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
1232+
iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x100);
1233+
} else {
1234+
iwl_write_prph(trans, DBGC_IN_SAMPLE, 0);
1235+
udelay(100);
1236+
iwl_write_prph(trans, DBGC_OUT_CTRL, 0);
1237+
}
1238+
12301239
/* tell the device to stop sending interrupts */
12311240
iwl_disable_interrupts(trans);
12321241

0 commit comments

Comments
 (0)