iwlwifi: mvm: support new reduce tx power FW API.
authorHaim Dreyfuss <haim.dreyfuss@intel.com>
Thu, 29 Mar 2018 11:13:54 +0000 (14:13 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Fri, 31 Aug 2018 08:38:27 +0000 (11:38 +0300)
Update reduce tx power command API to be compatible with new FW API.

Signed-off-by: Haim Dreyfuss <haim.dreyfuss@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
drivers/net/wireless/intel/iwlwifi/fw/api/power.h
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

index 6dad748..8b4922b 100644 (file)
@@ -436,7 +436,8 @@ enum iwl_legacy_cmds {
 
        /**
         * @REDUCE_TX_POWER_CMD:
-        * &struct iwl_dev_tx_power_cmd_v3 or &struct iwl_dev_tx_power_cmd
+        * &struct iwl_dev_tx_power_cmd_v3 or &struct iwl_dev_tx_power_cmd_v4
+        * or &struct iwl_dev_tx_power_cmd
         */
        REDUCE_TX_POWER_CMD = 0x9f,
 
index a3c77e0..286a22d 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright (C) 2018 Intel Corporation
  *
  * 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 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright (C) 2018 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -316,7 +318,9 @@ enum iwl_dev_tx_power_cmd_mode {
        IWL_TX_POWER_MODE_SET_DEVICE = 1,
        IWL_TX_POWER_MODE_SET_CHAINS = 2,
        IWL_TX_POWER_MODE_SET_ACK = 3,
-}; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_4 */;
+       IWL_TX_POWER_MODE_SET_SAR_TIMER = 4,
+       IWL_TX_POWER_MODE_SET_SAR_TIMER_DEFAULT_TABLE = 5,
+}; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_5 */;
 
 #define IWL_NUM_CHAIN_LIMITS   2
 #define IWL_NUM_SUB_BANDS      5
@@ -350,13 +354,35 @@ struct iwl_dev_tx_power_cmd_v3 {
  *     reduction.
  * @reserved: reserved (padding)
  */
-struct iwl_dev_tx_power_cmd {
+struct iwl_dev_tx_power_cmd_v4 {
        /* v4 is just an extension of v3 - keep this here */
        struct iwl_dev_tx_power_cmd_v3 v3;
        u8 enable_ack_reduction;
        u8 reserved[3];
 } __packed; /* TX_REDUCED_POWER_API_S_VER_4 */
 
+/**
+ * struct iwl_dev_tx_power_cmd - TX power reduction command
+ * @v3: version 3 of the command, embedded here for easier software handling
+ * @enable_ack_reduction: enable or disable close range ack TX power
+ *     reduction.
+ * @per_chain_restriction_changed: is per_chain_restriction has changed
+ *     from last command. used if set_mode is
+ *     IWL_TX_POWER_MODE_SET_SAR_TIMER.
+ *     note: if not changed, the command is used for keep alive only.
+ * @reserved: reserved (padding)
+ * @timer_period: timer in milliseconds. if expires FW will change to default
+ *     BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER
+ */
+struct iwl_dev_tx_power_cmd {
+       /* v5 is just an extension of v3 - keep this here */
+       struct iwl_dev_tx_power_cmd_v3 v3;
+       u8 enable_ack_reduction;
+       u8 per_chain_restriction_changed;
+       u8 reserved[2];
+       __le32 timer_period;
+} __packed; /* TX_REDUCED_POWER_API_S_VER_5 */
+
 #define IWL_NUM_GEO_PROFILES   3
 
 /**
index c7e296a..fce52ee 100644 (file)
@@ -259,6 +259,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
  * @IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2: This ucode supports version 8
  *     of scan request: SCAN_REQUEST_CMD_UMAC_API_S_VER_8
  * @IWL_UCODE_TLV_API_FRAG_EBS: This ucode supports fragmented EBS
+ * @IWL_UCODE_TLV_API_REDUCE_TX_POWER: This ucode supports v5 of
+ *     the REDUCE_TX_POWER_CMD.
  *
  * @NUM_IWL_UCODE_TLV_API: number of bits used
  */
@@ -282,6 +284,7 @@ enum iwl_ucode_tlv_api {
        IWL_UCODE_TLV_API_DEPRECATE_TTAK        = (__force iwl_ucode_tlv_api_t)41,
        IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2     = (__force iwl_ucode_tlv_api_t)42,
        IWL_UCODE_TLV_API_FRAG_EBS              = (__force iwl_ucode_tlv_api_t)44,
+       IWL_UCODE_TLV_API_REDUCE_TX_POWER       = (__force iwl_ucode_tlv_api_t)45,
 
        NUM_IWL_UCODE_TLV_API
 #ifdef __CHECKER__
index 6bb1a99..878dc29 100644 (file)
@@ -773,19 +773,28 @@ out_free:
 
 int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
 {
-       struct iwl_dev_tx_power_cmd cmd = {
-               .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
-       };
+       union {
+               struct iwl_dev_tx_power_cmd v5;
+               struct iwl_dev_tx_power_cmd_v4 v4;
+       } cmd;
        int i, j, idx;
        int profs[ACPI_SAR_NUM_CHAIN_LIMITS] = { prof_a, prof_b };
-       int len = sizeof(cmd);
+       int len;
 
        BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS < 2);
        BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS * ACPI_SAR_NUM_SUB_BANDS !=
                     ACPI_SAR_TABLE_SIZE);
 
-       if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
-               len = sizeof(cmd.v3);
+       cmd.v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS);
+
+       if (fw_has_api(&mvm->fw->ucode_capa,
+                      IWL_UCODE_TLV_API_REDUCE_TX_POWER))
+               len = sizeof(cmd.v5);
+       else if (fw_has_capa(&mvm->fw->ucode_capa,
+                            IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
+               len = sizeof(cmd.v4);
+       else
+               len = sizeof(cmd.v4.v3);
 
        for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) {
                struct iwl_mvm_sar_profile *prof;
@@ -812,7 +821,7 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
                IWL_DEBUG_RADIO(mvm, "  Chain[%d]:\n", i);
                for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) {
                        idx = (i * ACPI_SAR_NUM_SUB_BANDS) + j;
-                       cmd.v3.per_chain_restriction[i][j] =
+                       cmd.v5.v3.per_chain_restriction[i][j] =
                                cpu_to_le16(prof->table[idx]);
                        IWL_DEBUG_RADIO(mvm, "    Band[%d] = %d * .125dBm\n",
                                        j, prof->table[idx]);
index 3a502ea..d1bbafe 100644 (file)
@@ -1313,19 +1313,28 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
 static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                                s16 tx_power)
 {
-       struct iwl_dev_tx_power_cmd cmd = {
-               .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
-               .v3.mac_context_id =
+       int len;
+       union {
+               struct iwl_dev_tx_power_cmd v5;
+               struct iwl_dev_tx_power_cmd_v4 v4;
+       } cmd = {
+               .v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
+               .v5.v3.mac_context_id =
                        cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
-               .v3.pwr_restriction = cpu_to_le16(8 * tx_power),
+               .v5.v3.pwr_restriction = cpu_to_le16(8 * tx_power),
        };
-       int len = sizeof(cmd);
 
        if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
-               cmd.v3.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
+               cmd.v5.v3.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
 
-       if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
-               len = sizeof(cmd.v3);
+       if (fw_has_api(&mvm->fw->ucode_capa,
+                      IWL_UCODE_TLV_API_REDUCE_TX_POWER))
+               len = sizeof(cmd.v5);
+       else if (fw_has_capa(&mvm->fw->ucode_capa,
+                            IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
+               len = sizeof(cmd.v4);
+       else
+               len = sizeof(cmd.v4.v3);
 
        return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
 }