|
@@ -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];
|