[02/12] iwlwifi: add support for version 2 of SOC_CONFIGURATION_CMD

Message ID iwlwifi.20200326145047.81b06bbae5ca.Ib68d4c821ebcce253b42ed0ea15881fb4e3e01da@changeid
State New
Headers show
Series
  • [01/12] iwlwifi: mvm: add support for non EDCA based measurements
Related show

Commit Message

Luca Coelho March 26, 2020, 12:55 p.m.
From: Luca Coelho <luciano.coelho@intel.com>

This new command is mostly backwards compatible, with the exception
that the device_type element was changed into a bitmask.  The device
type bit remains the same (because we only had 0 and 1 anyway), but
when using v1 we can't set any other bits, because that would change
the integer.

Other than that, the struct remains the same and the driver can set
the device_type bit in both cases, but it can only set the low_latency
bit if VER_2 is used.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
 .../net/wireless/intel/iwlwifi/fw/api/soc.h   | 24 +++++++++++--------
 .../net/wireless/intel/iwlwifi/iwl-config.h   |  2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   | 21 ++++++++++++----
 3 files changed, 32 insertions(+), 15 deletions(-)

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h b/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h
index 5d1fb98fe667..aadca78e9846 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/soc.h
@@ -8,6 +8,7 @@ 
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2019        Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@ 
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2019        Intel Deutschland GmbH
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,21 +65,23 @@ 
 #ifndef __iwl_fw_api_soc_h__
 #define __iwl_fw_api_soc_h__
 
-/* type of devices for defining SOC latency */
-enum iwl_soc_device_types {
-	SOC_CONFIG_CMD_INTEGRATED   = 0x0,
-	SOC_CONFIG_CMD_DISCRETE     = 0x1,
-};
+#define SOC_CONFIG_CMD_FLAGS_DISCRETE		BIT(0)
+#define SOC_CONFIG_CMD_FLAGS_LOW_LATENCY	BIT(1)
 
 /**
  * struct iwl_soc_configuration_cmd - Set device stabilization latency
  *
- * @device_type: the device type as defined in &enum iwl_soc_device_types
- * @soc_latency: time for SOC to ensure stable power & XTAL
+ * @flags: soc settings flags.  In VER_1, we can only set the DISCRETE
+ *	flag, because the FW treats the whole value as an integer. In
+ *	VER_2, we can set the bits independently.
+ * @latency: time for SOC to ensure stable power & XTAL
  */
 struct iwl_soc_configuration_cmd {
-	__le32 device_type;
-	__le32 soc_latency;
-} __packed; /* SOC_CONFIGURATION_CMD_S_VER_1 */
+	__le32 flags;
+	__le32 latency;
+} __packed; /*
+	     * SOC_CONFIGURATION_CMD_S_VER_1 (see description above)
+	     * SOC_CONFIGURATION_CMD_S_VER_2
+	     */
 
 #endif /* __iwl_fw_api_soc_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 8549e8a39705..3069a322ca75 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -303,6 +303,7 @@  struct iwl_pwr_tx_backoff {
  * @gen2: 22000 and on transport operation
  * @mq_rx_supported: multi-queue rx support
  * @integrated: discrete or integrated
+ * @low_latency_xtal: use the low latency xtal if supported
  */
 struct iwl_cfg_trans_params {
 	const struct iwl_base_params *base_params;
@@ -315,6 +316,7 @@  struct iwl_cfg_trans_params {
 	    gen2:1,
 	    mq_rx_supported:1,
 	    integrated:1,
+	    low_latency_xtal:1,
 	    bisr_workaround:1;
 };
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 98978a475d93..bc040e9ca55f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -90,13 +90,24 @@  struct iwl_mvm_alive_data {
 /* set device type and latency */
 static int iwl_set_soc_latency(struct iwl_mvm *mvm)
 {
-	struct iwl_soc_configuration_cmd cmd;
+	struct iwl_soc_configuration_cmd cmd = {};
 	int ret;
 
-	cmd.device_type = (mvm->trans->trans_cfg->integrated) ?
-		cpu_to_le32(SOC_CONFIG_CMD_INTEGRATED) :
-		cpu_to_le32(SOC_CONFIG_CMD_DISCRETE);
-	cmd.soc_latency = cpu_to_le32(mvm->trans->trans_cfg->xtal_latency);
+	/*
+	 * In VER_1 of this command, the discrete value is considered
+	 * an integer; In VER_2, it's a bitmask.  Since we have only 2
+	 * values in VER_1, this is backwards-compatible with VER_2,
+	 * as long as we don't set any other bits.
+	 */
+	if (!mvm->trans->trans_cfg->integrated)
+		cmd.flags = cpu_to_le32(SOC_CONFIG_CMD_FLAGS_DISCRETE);
+
+	if (iwl_mvm_lookup_cmd_ver(mvm->fw, IWL_ALWAYS_LONG_GROUP,
+				   SCAN_REQ_UMAC) >= 2 &&
+	    (mvm->trans->trans_cfg->low_latency_xtal))
+		cmd.flags |= cpu_to_le32(SOC_CONFIG_CMD_FLAGS_LOW_LATENCY);
+
+	cmd.latency = cpu_to_le32(mvm->trans->trans_cfg->xtal_latency);
 
 	ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SOC_CONFIGURATION_CMD,
 						   SYSTEM_GROUP, 0), 0,