Skip to content

Commit

Permalink
wifi: iwlwifi: mei: make sure ownership confirmed message is sent
Browse files Browse the repository at this point in the history
[ Upstream commit 5aa7ce3 ]

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: 2da4366 ("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>
  • Loading branch information
AviStern authored and gregkh committed Dec 31, 2022
1 parent 61dd45b commit 39138ce
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 16 deletions.
7 changes: 4 additions & 3 deletions drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 */
Expand Down
30 changes: 20 additions & 10 deletions drivers/net/wireless/intel/iwlwifi/mei/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -1616,7 +1623,7 @@ void iwl_mei_set_netdev(struct net_device *netdev)
}
EXPORT_SYMBOL_GPL(iwl_mei_set_netdev);

void iwl_mei_device_down(void)
void iwl_mei_device_state(bool up)
{
struct iwl_mei *mei;

Expand All @@ -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,
Expand All @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/intel/iwlwifi/mvm/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/intel/iwlwifi/mvm/ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 39138ce

Please sign in to comment.