• Emmanuel Grumbach's avatar
    iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface · 37107588
    Emmanuel Grumbach authored
    [ Upstream commit 155f7e04 ]
    
    Fix a bug that happens in the following scenario:
    1) suspend without WoWLAN
    2) mac80211 calls drv_stop because of the suspend
    3) __iwl_mvm_mac_stop deallocates the aux station
    4) during drv_stop the firmware crashes
    5) iwlmvm:
    	* sets IWL_MVM_STATUS_HW_RESTART_REQUESTED
    	* asks mac80211 to kick the restart flow
    6) mac80211 puts the restart worker into a freezable
       queue which means that the worker will not run for now
       since the workqueue is already frozen
    7) ...
    8) resume
    9) mac80211 runs ieee80211_reconfig as part of the resume
    10) mac80211 detects that a restart flow has been requested
        and that we are now resuming from suspend and cancels
        the restart worker
    11) mac80211 calls drv_start()
    12) __iwl_mvm_mac_start checks that IWL_MVM_STATUS_HW_RESTART_REQUESTED
        clears it, sets IWL_MVM_STATUS_IN_HW_RESTART and calls
        iwl_mvm_restart_cleanup()
    13) iwl_fw_error_dump gets called and accesses the device
        to get debug data
    14) iwl_mvm_up adds the aux station
    15) iwl_mvm_add_aux_sta() allocates an internal station for
        the aux station
    16) iwl_mvm_allocate_int_sta() tests IWL_MVM_STATUS_IN_HW_RESTART
        and doesn't really allocate a station ID for the aux
        station
    17) a new queue is added for the aux station
    
    Note that steps from 5 to 9 aren't really part of the
    problem but were described for the sake of completeness.
    
    Once the iwl_mvm_mac_stop() is called, the device is not
    accessible, meaning that step 12) can't succeed and we'll
    see the following:
    
    drivers/net/wireless/intel/iwlwifi/pcie/trans.c:2122 iwl_trans_pcie_grab_nic_access+0xc0/0x1d6 [iwlwifi]()
    Timeout waiting for hardware access (CSR_GP_CNTRL 0x080403d8)
    Call Trace:
    [<ffffffffc03e6ad3>] iwl_trans_pcie_grab_nic_access+0xc0/0x1d6 [iwlwifi]
    [<ffffffffc03e6a13>] iwl_trans_pcie_dump_regs+0x3fd/0x3fd [iwlwifi]
    [<ffffffffc03dad42>] iwl_fw_error_dump+0x4f5/0xe8b [iwlwifi]
    [<ffffffffc04bd43e>] __iwl_mvm_mac_start+0x5a/0x21a [iwlmvm]
    [<ffffffffc04bd6d2>] iwl_mvm_mac_start+0xd4/0x103 [iwlmvm]
    [<ffffffffc042d378>] drv_start+0xa1/0xc5 [iwl7000_mac80211]
    [<ffffffffc045a339>] ieee80211_reconfig+0x145/0xf50 [mac80211]
    [<ffffffffc044788b>] ieee80211_resume+0x62/0x66 [mac80211]
    [<ffffffffc0366c5b>] wiphy_resume+0xa9/0xc6 [cfg80211]
    
    The station id of the aux station is set to 0xff in step 3
    and because we don't really allocate a new station id for
    the auxliary station (as explained in 16), we end up sending
    a command to the firmware asking to connect the queue
    to station id 0xff. This makes the firmware crash with the
    following information:
    
    0x00002093 | ADVANCED_SYSASSERT
    0x000002F0 | trm_hw_status0
    0x00000000 | trm_hw_status1
    0x00000B38 | branchlink2
    0x0001978C | interruptlink1
    0x00000000 | interruptlink2
    0xFF080501 | data1
    0xDEADBEEF | data2
    0xDEADBEEF | data3
    Firmware error during reconfiguration - reprobe!
    FW error in SYNC CMD SCD_QUEUE_CFG
    
    Fix this by clearing IWL_MVM_STATUS_HW_RESTART_REQUESTED
    in iwl_mvm_mac_stop(). We won't be able to collect debug
    data anyway and when we will brought up again, we will
    have a clean state from the firmware perspective.
    Since we won't have IWL_MVM_STATUS_IN_HW_RESTART set in
    step 12) we won't get to the 2093 ASSERT either.
    
    Fixes: bf8b286f ("iwlwifi: mvm: defer setting IWL_MVM_STATUS_IN_HW_RESTART")
    Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
    Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    37107588
mac80211.c 122 KB