summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
diff options
context:
space:
mode:
authorHaim Dreyfuss <haim.dreyfuss@intel.com>2017-03-30 11:16:17 +0300
committerLuca Coelho <luciano.coelho@intel.com>2017-06-29 13:26:23 +0300
commit7fe90e0e3d603844657e8361aa4686c6ee4a8c9d (patch)
tree5a7be9d60363854e4dfc1a9fb495fe3a198a5ca1 /drivers/net/wireless/intel/iwlwifi/mvm/fw.c
parentfdcbe65d618af080ee23229f0137ffd37f2de36b (diff)
iwlwifi: mvm: refactor geo init
We are going to add debugfs entry to retrieve the current geographic profile being used in the FW. Currently the driver reads those tables from the BIOS and passes them to the FW. To prepare for this retrieving we want to store those tables in the driver. Signed-off-by: Haim Dreyfuss <haim.dreyfuss@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/fw.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 24cc406d87ef..273e19460016 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -1243,15 +1243,15 @@ out_free:
return ret;
}
-static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm,
- struct iwl_mvm_geo_table *geo_table)
+static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
{
union acpi_object *wifi_pkg;
acpi_handle root_handle;
acpi_handle handle;
struct acpi_buffer wgds = {ACPI_ALLOCATE_BUFFER, NULL};
acpi_status status;
- int i, ret;
+ int i, j, ret;
+ int idx = 1;
root_handle = ACPI_HANDLE(mvm->dev);
if (!root_handle) {
@@ -1282,15 +1282,17 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm,
goto out_free;
}
- for (i = 0; i < ACPI_WGDS_WIFI_DATA_SIZE; i++) {
- union acpi_object *entry;
+ for (i = 0; i < IWL_NUM_GEO_PROFILES; i++) {
+ for (j = 0; j < IWL_MVM_GEO_TABLE_SIZE; j++) {
+ union acpi_object *entry;
- entry = &wifi_pkg->package.elements[i + 1];
- if ((entry->type != ACPI_TYPE_INTEGER) ||
- (entry->integer.value > U8_MAX))
- return -EINVAL;
+ entry = &wifi_pkg->package.elements[idx++];
+ if ((entry->type != ACPI_TYPE_INTEGER) ||
+ (entry->integer.value > U8_MAX))
+ return -EINVAL;
- geo_table->values[i] = entry->integer.value;
+ mvm->geo_profiles[i].values[j] = entry->integer.value;
+ }
}
ret = 0;
out_free:
@@ -1351,16 +1353,47 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
}
+int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
+{
+ struct iwl_geo_tx_power_profiles_resp *resp;
+ int ret;
+
+ struct iwl_geo_tx_power_profiles_cmd geo_cmd = {
+ .ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_GET_CURRENT_TABLE),
+ };
+ struct iwl_host_cmd cmd = {
+ .id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT),
+ .len = { sizeof(geo_cmd), },
+ .flags = CMD_WANT_SKB,
+ .data = { &geo_cmd },
+ };
+
+ ret = iwl_mvm_send_cmd(mvm, &cmd);
+ if (ret) {
+ IWL_ERR(mvm, "Failed to get geographic profile info %d\n", ret);
+ return ret;
+ }
+
+ resp = (void *)cmd.resp_pkt->data;
+ ret = le32_to_cpu(resp->profile_idx);
+ if (WARN_ON(ret > IWL_NUM_GEO_PROFILES)) {
+ ret = -EIO;
+ IWL_WARN(mvm, "Invalid geographic profile idx (%d)\n", ret);
+ }
+
+ iwl_free_resp(&cmd);
+ return ret;
+}
+
static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
{
- struct iwl_mvm_geo_table geo_table;
struct iwl_geo_tx_power_profiles_cmd cmd = {
.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES),
};
- int ret, i, j, idx;
+ int ret, i, j;
u16 cmd_wide_id = WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT);
- ret = iwl_mvm_sar_get_wgds_table(mvm, &geo_table);
+ ret = iwl_mvm_sar_get_wgds_table(mvm);
if (ret < 0) {
IWL_DEBUG_RADIO(mvm,
"Geo SAR BIOS table invalid or unavailable. (%d)\n",
@@ -1381,9 +1414,8 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
for (j = 0; j < ACPI_WGDS_NUM_BANDS; j++) {
u8 *value;
- idx = i * ACPI_WGDS_NUM_BANDS * ACPI_WGDS_TABLE_SIZE +
- j * ACPI_WGDS_TABLE_SIZE;
- value = &geo_table.values[idx];
+ value = &mvm->geo_profiles[i].values[j *
+ IWL_GEO_PER_CHAIN_SIZE];
chain[j].max_tx_power = cpu_to_le16(value[0]);
chain[j].chain_a = value[1];
chain[j].chain_b = value[2];