iwlwifi: convert flat GEO profile table to a struct version

The GEO profiles have been stored in single-dimension arrays and the
access has been done via a single index.  We will soon need to support
different revisions of this table, which will make the flat array even
harder to handle.  To prepare for that, convert the single-dimension
array to a struct with substructures.

Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210805141826.56f3506411a2.I600ed3708d19f2263a5a8d143f6711d08499bbb0@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
Luca Coelho 2021-08-05 14:21:51 +03:00
parent de95c9288a
commit 5bf7a9eddd
3 changed files with 44 additions and 27 deletions

View File

@ -700,8 +700,8 @@ IWL_EXPORT_SYMBOL(iwl_sar_get_ewrd_table);
int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt) int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
{ {
union acpi_object *wifi_pkg, *data; union acpi_object *wifi_pkg, *data;
int i, j, ret, tbl_rev; int i, j, k, ret, tbl_rev;
int idx = 1; int idx = 1; /* start from one to skip the domain */
data = iwl_acpi_get_object(fwrt->dev, ACPI_WGDS_METHOD); data = iwl_acpi_get_object(fwrt->dev, ACPI_WGDS_METHOD);
if (IS_ERR(data)) if (IS_ERR(data))
@ -722,7 +722,7 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
fwrt->geo_rev = tbl_rev; fwrt->geo_rev = tbl_rev;
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) { for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
for (j = 0; j < ACPI_GEO_TABLE_SIZE; j++) { for (j = 0; j < ACPI_GEO_NUM_BANDS_REV0; j++) {
union acpi_object *entry; union acpi_object *entry;
entry = &wifi_pkg->package.elements[idx++]; entry = &wifi_pkg->package.elements[idx++];
@ -732,9 +732,23 @@ int iwl_sar_get_wgds_table(struct iwl_fw_runtime *fwrt)
goto out_free; goto out_free;
} }
fwrt->geo_profiles[i].values[j] = entry->integer.value; fwrt->geo_profiles[i].bands[j].max =
entry->integer.value;
for (k = 0; k < ACPI_GEO_NUM_CHAINS; k++) {
entry = &wifi_pkg->package.elements[idx++];
if (entry->type != ACPI_TYPE_INTEGER ||
entry->integer.value > U8_MAX) {
ret = -EINVAL;
goto out_free;
}
fwrt->geo_profiles[i].bands[j].chains[k] =
entry->integer.value;
}
} }
} }
ret = 0; ret = 0;
out_free: out_free:
kfree(data); kfree(data);
@ -784,25 +798,17 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
for (j = 0; j < n_bands; j++) { for (j = 0; j < n_bands; j++) {
struct iwl_per_chain_offset *chain = struct iwl_per_chain_offset *chain =
&table[i * n_bands + j]; &table[i * n_bands + j];
u8 *value;
if (j * ACPI_GEO_PER_CHAIN_SIZE >= chain->max_tx_power =
ARRAY_SIZE(fwrt->geo_profiles[0].values)) cpu_to_le16(fwrt->geo_profiles[i].bands[j].max);
/* chain->chain_a = fwrt->geo_profiles[i].bands[j].chains[0];
* Currently we only store lb an hb values, and chain->chain_b = fwrt->geo_profiles[i].bands[j].chains[1];
* don't have any special ones for uhb. So leave
* those empty for the time being
*/
break;
value = &fwrt->geo_profiles[i].values[j *
ACPI_GEO_PER_CHAIN_SIZE];
chain->max_tx_power = cpu_to_le16(value[0]);
chain->chain_a = value[1];
chain->chain_b = value[2];
IWL_DEBUG_RADIO(fwrt, IWL_DEBUG_RADIO(fwrt,
"SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n", "SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n",
i, j, value[1], value[2], value[0]); i, j,
fwrt->geo_profiles[i].bands[j].chains[0],
fwrt->geo_profiles[i].bands[j].chains[1],
fwrt->geo_profiles[i].bands[j].max);
} }
} }

View File

@ -28,7 +28,6 @@
#define ACPI_SAR_PROFILE_NUM 4 #define ACPI_SAR_PROFILE_NUM 4
#define ACPI_GEO_TABLE_SIZE 6
#define ACPI_NUM_GEO_PROFILES 3 #define ACPI_NUM_GEO_PROFILES 3
#define ACPI_GEO_PER_CHAIN_SIZE 3 #define ACPI_GEO_PER_CHAIN_SIZE 3
@ -39,6 +38,11 @@
#define ACPI_SAR_NUM_SUB_BANDS_REV1 11 #define ACPI_SAR_NUM_SUB_BANDS_REV1 11
#define ACPI_SAR_NUM_SUB_BANDS_REV2 11 #define ACPI_SAR_NUM_SUB_BANDS_REV2 11
#define ACPI_GEO_NUM_CHAINS 2
#define ACPI_GEO_NUM_BANDS_REV0 2
#define ACPI_GEO_NUM_BANDS_REV1 2
#define ACPI_GEO_NUM_BANDS_REV2 3
#define ACPI_WRDS_WIFI_DATA_SIZE_REV0 (ACPI_SAR_NUM_CHAINS_REV0 * \ #define ACPI_WRDS_WIFI_DATA_SIZE_REV0 (ACPI_SAR_NUM_CHAINS_REV0 * \
ACPI_SAR_NUM_SUB_BANDS_REV0 + 2) ACPI_SAR_NUM_SUB_BANDS_REV0 + 2)
#define ACPI_WRDS_WIFI_DATA_SIZE_REV1 (ACPI_SAR_NUM_CHAINS_REV1 * \ #define ACPI_WRDS_WIFI_DATA_SIZE_REV1 (ACPI_SAR_NUM_CHAINS_REV1 * \
@ -90,8 +94,14 @@ struct iwl_sar_profile {
struct iwl_sar_profile_chain chains[ACPI_SAR_NUM_CHAINS_REV2]; struct iwl_sar_profile_chain chains[ACPI_SAR_NUM_CHAINS_REV2];
}; };
/* Same thing as with SAR, all revisions fit in revision 2 */
struct iwl_geo_profile_band {
u8 max;
u8 chains[ACPI_GEO_NUM_CHAINS];
};
struct iwl_geo_profile { struct iwl_geo_profile {
u8 values[ACPI_GEO_TABLE_SIZE]; struct iwl_geo_profile_band bands[ACPI_GEO_NUM_BANDS_REV2];
}; };
enum iwl_dsm_funcs_rev_0 { enum iwl_dsm_funcs_rev_0 {

View File

@ -305,7 +305,6 @@ static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file,
int pos = 0; int pos = 0;
int bufsz = sizeof(buf); int bufsz = sizeof(buf);
int tbl_idx; int tbl_idx;
u8 *value;
if (!iwl_mvm_firmware_running(mvm)) if (!iwl_mvm_firmware_running(mvm))
return -EIO; return -EIO;
@ -321,16 +320,18 @@ static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file,
pos = scnprintf(buf, bufsz, pos = scnprintf(buf, bufsz,
"SAR geographic profile disabled\n"); "SAR geographic profile disabled\n");
} else { } else {
value = &mvm->fwrt.geo_profiles[tbl_idx - 1].values[0];
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"Use geographic profile %d\n", tbl_idx); "Use geographic profile %d\n", tbl_idx);
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"2.4GHz:\n\tChain A offset: %hhu dBm\n\tChain B offset: %hhu dBm\n\tmax tx power: %hhu dBm\n", "2.4GHz:\n\tChain A offset: %hhu dBm\n\tChain B offset: %hhu dBm\n\tmax tx power: %hhu dBm\n",
value[1], value[2], value[0]); mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].chains[0],
mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].chains[1],
mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].max);
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"5.2GHz:\n\tChain A offset: %hhu dBm\n\tChain B offset: %hhu dBm\n\tmax tx power: %hhu dBm\n", "5.2GHz:\n\tChain A offset: %hhu dBm\n\tChain B offset: %hhu dBm\n\tmax tx power: %hhu dBm\n",
value[4], value[5], value[3]); mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].chains[0],
mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].chains[1],
mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].max);
} }
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);