2023-04-18 09:38:55

by Greenman, Gregory

[permalink] [raw]
Subject: [PATCH 11/11] wifi: iwlwifi: mvm: fix RFKILL report when driver is going down

From: Avraham Stern <[email protected]>

When CSME takes ownership, the driver sets RFKILL on, and this
triggers driver unload and sending the confirmation SAP message.
However, when IWL_MVM_MEI_REPORT_RFKILL is set, RFKILL was not
reported and as a result, the driver did not confirm the ownership
transition. Fix it.

Signed-off-by: Avraham Stern <[email protected]>
Signed-off-by: Gregory Greenman <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h | 4 ++--
drivers/net/wireless/intel/iwlwifi/mei/main.c | 13 +++++++------
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 +++++-
3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h b/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
index ae66192feefe..655d95d3a068 100644
--- a/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
+++ b/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2021 Intel Corporation
+ * Copyright (C) 2021 - 2022 Intel Corporation
*/

#ifndef __iwl_mei_h__
@@ -301,7 +301,7 @@ struct iwl_mei_colloc_info {
struct iwl_mei_ops {
void (*me_conn_status)(void *priv,
const struct iwl_mei_conn_info *conn_info);
- void (*rfkill)(void *priv, bool blocked);
+ void (*rfkill)(void *priv, bool blocked, bool csme_taking_ownership);
void (*roaming_forbidden)(void *priv, bool forbidden);
void (*sap_connected)(void *priv);
void (*nic_stolen)(void *priv);
diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c
index f1e0fe806a00..0a29fb013005 100644
--- a/drivers/net/wireless/intel/iwlwifi/mei/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c
@@ -724,7 +724,7 @@ iwl_mei_handle_conn_status(struct mei_cl_device *cldev,
status->link_prot_state);
else
iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv,
- status->link_prot_state);
+ status->link_prot_state, false);
}

static void iwl_mei_set_init_conf(struct iwl_mei *mei)
@@ -796,7 +796,7 @@ static void iwl_mei_handle_amt_state(struct mei_cl_device *cldev,
if (mei->amt_enabled)
iwl_mei_set_init_conf(mei);
else if (iwl_mei_cache.ops)
- iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false);
+ iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false, false);

schedule_work(&mei->netdev_work);

@@ -837,7 +837,7 @@ static void iwl_mei_handle_csme_taking_ownership(struct mei_cl_device *cldev,
*/
mei->csme_taking_ownership = true;

- 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);
@@ -892,7 +892,7 @@ static void iwl_mei_handle_rx_host_own_req(struct mei_cl_device *cldev,

/* We can now start the connection, unblock rfkill */
if (iwl_mei_cache.ops)
- iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false);
+ iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false, false);
}

static void iwl_mei_handle_pldr_ack(struct mei_cl_device *cldev,
@@ -1791,7 +1791,8 @@ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
if (iwl_mei_is_connected()) {
if (mei->amt_enabled)
iwl_mei_send_sap_msg(mei->cldev,
- SAP_MSG_NOTIF_WIFIDR_UP);
+ SAP_MSG_NOTIF_WIFIDR_UP,
+ false);
ops->rfkill(priv, mei->link_prot_state);
}
}
@@ -2111,7 +2112,7 @@ static void iwl_mei_remove(struct mei_cl_device *cldev)
spin_unlock_bh(&mei->data_q_lock);

if (iwl_mei_cache.ops)
- iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false);
+ iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false, false);

/*
* mei_cldev_disable will return only after all the MEI Rx is done.
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 26c3f00d6f7d..32625bfacaae 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1020,10 +1020,14 @@ static void iwl_mvm_me_conn_status(void *priv, const struct iwl_mei_conn_info *c
kfree_rcu(prev_conn_info, rcu_head);
}

-static void iwl_mvm_mei_rfkill(void *priv, bool blocked)
+static void iwl_mvm_mei_rfkill(void *priv, bool blocked,
+ bool csme_taking_ownership)
{
struct iwl_mvm *mvm = priv;

+ if (blocked && !csme_taking_ownership)
+ return;
+
mvm->mei_rfkill_blocked = blocked;
if (!mvm->hw_registered)
return;
--
2.38.1