mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
wifi: iwlwifi: mei: make sure ownership confirmed message is sent
[ Upstream commit5aa7ce31bd] It is possible that CSME will try to take ownership while the driver is stopping. In this case, if the CSME takes ownership message arrives after the driver started unregistering, the iwl_mei_cache->ops is already invalid, so the host will not answer with the ownership confirmed message. Similarly, if the take ownership message arrived after the mac was stopped or when iwl_mvm_up() failed, setting rfkill will not trigger sending the confirm message. As a result, CSME will not take ownership, which will result in a disconnection. Fix it by sending the ownership confirmed message immediately in such cases. Fixes:2da4366f9e("iwlwifi: mei: add the driver to allow cooperation with CSME") Signed-off-by: Avraham Stern <avraham.stern@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20221030191011.b2a4c009e3e6.I7f931b7ee8b168e8ac88b11f23bff98b7ed3cb19@changeid Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
61dd45b01b
commit
39138cee7a
@@ -446,9 +446,10 @@ void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info,
|
||||
void iwl_mei_host_disassociated(void);
|
||||
|
||||
/**
|
||||
* iwl_mei_device_down() - must be called when the device is down
|
||||
* iwl_mei_device_state() - must be called when the device changes up/down state
|
||||
* @up: true if the device is up, false otherwise.
|
||||
*/
|
||||
void iwl_mei_device_down(void);
|
||||
void iwl_mei_device_state(bool up);
|
||||
|
||||
#else
|
||||
|
||||
@@ -497,7 +498,7 @@ static inline void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_
|
||||
static inline void iwl_mei_host_disassociated(void)
|
||||
{}
|
||||
|
||||
static inline void iwl_mei_device_down(void)
|
||||
static inline void iwl_mei_device_state(bool up)
|
||||
{}
|
||||
|
||||
#endif /* CONFIG_IWLMEI */
|
||||
|
||||
@@ -147,6 +147,8 @@ struct iwl_mei_filters {
|
||||
* to send CSME_OWNERSHIP_CONFIRMED when the driver completes its down
|
||||
* flow.
|
||||
* @link_prot_state: true when we are in link protection PASSIVE
|
||||
* @device_down: true if the device is down. Used to remember to send
|
||||
* CSME_OWNERSHIP_CONFIRMED when the driver is already down.
|
||||
* @csa_throttle_end_wk: used when &csa_throttled is true
|
||||
* @data_q_lock: protects the access to the data queues which are
|
||||
* accessed without the mutex.
|
||||
@@ -167,6 +169,7 @@ struct iwl_mei {
|
||||
bool csa_throttled;
|
||||
bool csme_taking_ownership;
|
||||
bool link_prot_state;
|
||||
bool device_down;
|
||||
struct delayed_work csa_throttle_end_wk;
|
||||
spinlock_t data_q_lock;
|
||||
|
||||
@@ -798,14 +801,18 @@ static void iwl_mei_handle_csme_taking_ownership(struct mei_cl_device *cldev,
|
||||
|
||||
mei->got_ownership = false;
|
||||
|
||||
/*
|
||||
* Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi driver
|
||||
* is finished taking the device down.
|
||||
*/
|
||||
mei->csme_taking_ownership = true;
|
||||
if (iwl_mei_cache.ops && !mei->device_down) {
|
||||
/*
|
||||
* Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi
|
||||
* driver is finished taking the device down.
|
||||
*/
|
||||
mei->csme_taking_ownership = true;
|
||||
|
||||
if (iwl_mei_cache.ops)
|
||||
iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true);
|
||||
iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true, true);
|
||||
} else {
|
||||
iwl_mei_send_sap_msg(cldev,
|
||||
SAP_MSG_NOTIF_CSME_OWNERSHIP_CONFIRMED);
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_mei_handle_nvm(struct mei_cl_device *cldev,
|
||||
@@ -1616,7 +1623,7 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iwl_mei_set_netdev);
|
||||
|
||||
void iwl_mei_device_down(void)
|
||||
void iwl_mei_device_state(bool up)
|
||||
{
|
||||
struct iwl_mei *mei;
|
||||
|
||||
@@ -1630,7 +1637,9 @@ void iwl_mei_device_down(void)
|
||||
if (!mei)
|
||||
goto out;
|
||||
|
||||
if (!mei->csme_taking_ownership)
|
||||
mei->device_down = !up;
|
||||
|
||||
if (up || !mei->csme_taking_ownership)
|
||||
goto out;
|
||||
|
||||
iwl_mei_send_sap_msg(mei->cldev,
|
||||
@@ -1639,7 +1648,7 @@ void iwl_mei_device_down(void)
|
||||
out:
|
||||
mutex_unlock(&iwl_mei_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iwl_mei_device_down);
|
||||
EXPORT_SYMBOL_GPL(iwl_mei_device_state);
|
||||
|
||||
int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
|
||||
{
|
||||
@@ -1821,6 +1830,7 @@ static int iwl_mei_probe(struct mei_cl_device *cldev,
|
||||
|
||||
mei_cldev_set_drvdata(cldev, mei);
|
||||
mei->cldev = cldev;
|
||||
mei->device_down = true;
|
||||
|
||||
do {
|
||||
ret = iwl_mei_alloc_shared_mem(cldev);
|
||||
|
||||
@@ -1665,6 +1665,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
||||
iwl_rfi_send_config_cmd(mvm, NULL);
|
||||
}
|
||||
|
||||
iwl_mvm_mei_device_state(mvm, true);
|
||||
|
||||
IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
|
||||
return 0;
|
||||
error:
|
||||
|
||||
@@ -2201,10 +2201,10 @@ static inline void iwl_mvm_mei_host_disassociated(struct iwl_mvm *mvm)
|
||||
iwl_mei_host_disassociated();
|
||||
}
|
||||
|
||||
static inline void iwl_mvm_mei_device_down(struct iwl_mvm *mvm)
|
||||
static inline void iwl_mvm_mei_device_state(struct iwl_mvm *mvm, bool up)
|
||||
{
|
||||
if (mvm->mei_registered)
|
||||
iwl_mei_device_down();
|
||||
iwl_mei_device_state(up);
|
||||
}
|
||||
|
||||
static inline void iwl_mvm_mei_set_sw_rfkill_state(struct iwl_mvm *mvm)
|
||||
|
||||
@@ -1375,7 +1375,7 @@ void iwl_mvm_stop_device(struct iwl_mvm *mvm)
|
||||
iwl_trans_stop_device(mvm->trans);
|
||||
iwl_free_fw_paging(&mvm->fwrt);
|
||||
iwl_fw_dump_conf_clear(&mvm->fwrt);
|
||||
iwl_mvm_mei_device_down(mvm);
|
||||
iwl_mvm_mei_device_state(mvm, false);
|
||||
}
|
||||
|
||||
static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
|
||||
|
||||
Reference in New Issue
Block a user