@@ -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__ */
@@ -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;
};
@@ -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,