Commit 0791c2fc authored by Haim Dreyfuss's avatar Haim Dreyfuss Committed by Luca Coelho

iwlwifi: mvm: support new reduce tx power FW API.

Update reduce tx power command API to be compatible with new FW API.
Signed-off-by: default avatarHaim Dreyfuss <haim.dreyfuss@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 4c2f445c
...@@ -436,7 +436,8 @@ enum iwl_legacy_cmds { ...@@ -436,7 +436,8 @@ enum iwl_legacy_cmds {
/** /**
* @REDUCE_TX_POWER_CMD: * @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, REDUCE_TX_POWER_CMD = 0x9f,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2017 Intel Deutschland 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 * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -316,7 +318,9 @@ enum iwl_dev_tx_power_cmd_mode { ...@@ -316,7 +318,9 @@ enum iwl_dev_tx_power_cmd_mode {
IWL_TX_POWER_MODE_SET_DEVICE = 1, IWL_TX_POWER_MODE_SET_DEVICE = 1,
IWL_TX_POWER_MODE_SET_CHAINS = 2, IWL_TX_POWER_MODE_SET_CHAINS = 2,
IWL_TX_POWER_MODE_SET_ACK = 3, 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_CHAIN_LIMITS 2
#define IWL_NUM_SUB_BANDS 5 #define IWL_NUM_SUB_BANDS 5
...@@ -350,13 +354,35 @@ struct iwl_dev_tx_power_cmd_v3 { ...@@ -350,13 +354,35 @@ struct iwl_dev_tx_power_cmd_v3 {
* reduction. * reduction.
* @reserved: reserved (padding) * @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 */ /* v4 is just an extension of v3 - keep this here */
struct iwl_dev_tx_power_cmd_v3 v3; struct iwl_dev_tx_power_cmd_v3 v3;
u8 enable_ack_reduction; u8 enable_ack_reduction;
u8 reserved[3]; u8 reserved[3];
} __packed; /* TX_REDUCED_POWER_API_S_VER_4 */ } __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 #define IWL_NUM_GEO_PROFILES 3
/** /**
......
...@@ -259,6 +259,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; ...@@ -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 * @IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2: This ucode supports version 8
* of scan request: SCAN_REQUEST_CMD_UMAC_API_S_VER_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_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 * @NUM_IWL_UCODE_TLV_API: number of bits used
*/ */
...@@ -282,6 +284,7 @@ enum iwl_ucode_tlv_api { ...@@ -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_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_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_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 NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__ #ifdef __CHECKER__
......
...@@ -773,19 +773,28 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm) ...@@ -773,19 +773,28 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b) int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
{ {
struct iwl_dev_tx_power_cmd cmd = { union {
.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS), struct iwl_dev_tx_power_cmd v5;
}; struct iwl_dev_tx_power_cmd_v4 v4;
} cmd;
int i, j, idx; int i, j, idx;
int profs[ACPI_SAR_NUM_CHAIN_LIMITS] = { prof_a, prof_b }; 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 < 2);
BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS * ACPI_SAR_NUM_SUB_BANDS != BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS * ACPI_SAR_NUM_SUB_BANDS !=
ACPI_SAR_TABLE_SIZE); ACPI_SAR_TABLE_SIZE);
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK)) cmd.v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS);
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);
for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) { for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) {
struct iwl_mvm_sar_profile *prof; 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) ...@@ -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); IWL_DEBUG_RADIO(mvm, " Chain[%d]:\n", i);
for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) { for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) {
idx = (i * 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]); cpu_to_le16(prof->table[idx]);
IWL_DEBUG_RADIO(mvm, " Band[%d] = %d * .125dBm\n", IWL_DEBUG_RADIO(mvm, " Band[%d] = %d * .125dBm\n",
j, prof->table[idx]); j, prof->table[idx]);
......
...@@ -1313,19 +1313,28 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm) ...@@ -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, static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
s16 tx_power) s16 tx_power)
{ {
struct iwl_dev_tx_power_cmd cmd = { int len;
.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC), union {
.v3.mac_context_id = 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), 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) 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)) if (fw_has_api(&mvm->fw->ucode_capa,
len = sizeof(cmd.v3); 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); return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment