1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

wifi: iwlwifi: mei: make sure ownership confirmed message is sent

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
This commit is contained in:
Avraham Stern 2022-10-30 19:17:41 +02:00 committed by Gregory Greenman
parent e5d3a64e65
commit 5aa7ce31bd
5 changed files with 29 additions and 16 deletions

View file

@ -448,9 +448,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
@ -499,7 +500,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 */

View file

@ -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);

View file

@ -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:

View file

@ -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)

View file

@ -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)