mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-05-05 09:57:21 +02:00
wifi: iwlwifi: mld: add support for iwl_mcc_allowed_ap_type_cmd v2
There is a new version of this command to indicate which AP type in UNII-9 is supported per country. This adds support for a new UEFI table that will include that data to be filled in the new AP type table. Rename the uats_table field in firmware_runtime structure since it includes now the UATS and the new UNEB table coming from UEFI. For the same reason, rename iwl_mld_init_uats. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20260319110722.b839655712c5.I3dfca54bd19d6bd5f7ca385ea63be086ece9c1d0@changeid
This commit is contained in:
committed by
Miri Korenblit
parent
bb0c0aa30f
commit
078df640ef
@@ -701,13 +701,23 @@ struct iwl_pnvm_init_complete_ntfy {
|
||||
#define UATS_TABLE_COL_SIZE 13
|
||||
|
||||
/**
|
||||
* struct iwl_mcc_allowed_ap_type_cmd - struct for MCC_ALLOWED_AP_TYPE_CMD
|
||||
* struct iwl_mcc_allowed_ap_type_cmd_v1 - struct for MCC_ALLOWED_AP_TYPE_CMD
|
||||
* @mcc_to_ap_type_map: mapping an MCC to 6 GHz AP type support (UATS)
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_mcc_allowed_ap_type_cmd {
|
||||
struct iwl_mcc_allowed_ap_type_cmd_v1 {
|
||||
u8 mcc_to_ap_type_map[UATS_TABLE_ROW_SIZE][UATS_TABLE_COL_SIZE];
|
||||
__le16 reserved;
|
||||
} __packed; /* MCC_ALLOWED_AP_TYPE_CMD_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mcc_allowed_ap_type_cmd - struct for MCC_ALLOWED_AP_TYPE_CMD
|
||||
* @mcc_to_ap_type_map: mapping an MCC to 6 GHz AP type support (UATS)
|
||||
* @mcc_to_ap_type_unii9_map: mapping an MCC to UNII-9 AP type support allowed
|
||||
*/
|
||||
struct iwl_mcc_allowed_ap_type_cmd {
|
||||
u8 mcc_to_ap_type_map[UATS_TABLE_ROW_SIZE][UATS_TABLE_COL_SIZE];
|
||||
u8 mcc_to_ap_type_unii9_map[UATS_TABLE_ROW_SIZE][UATS_TABLE_COL_SIZE];
|
||||
} __packed; /* MCC_ALLOWED_AP_TYPE_CMD_API_S_VER_2 */
|
||||
|
||||
#endif /* __iwl_fw_api_nvm_reg_h__ */
|
||||
|
||||
@@ -106,8 +106,8 @@ struct iwl_txf_iter_data {
|
||||
* @cur_fw_img: current firmware image, must be maintained by
|
||||
* the driver by calling &iwl_fw_set_current_image()
|
||||
* @dump: debug dump data
|
||||
* @uats_table: AP type table
|
||||
* @uats_valid: is AP type table valid
|
||||
* @ap_type_cmd: AP type tables (for enablement on 6 GHz)
|
||||
* @ap_type_cmd_valid: if &ap_type_cmd is valid
|
||||
* @uefi_tables_lock_status: The status of the WIFI GUID UEFI variables lock:
|
||||
* 0: Unlocked, 1 and 2: Locked.
|
||||
* Only read the UEFI variables if locked.
|
||||
@@ -213,8 +213,8 @@ struct iwl_fw_runtime {
|
||||
u8 ppag_bios_source;
|
||||
struct iwl_sar_offset_mapping_cmd sgom_table;
|
||||
bool sgom_enabled;
|
||||
struct iwl_mcc_allowed_ap_type_cmd uats_table;
|
||||
bool uats_valid;
|
||||
struct iwl_mcc_allowed_ap_type_cmd ap_type_cmd;
|
||||
bool ap_type_cmd_valid;
|
||||
u8 uefi_tables_lock_status;
|
||||
struct iwl_phy_specific_cfg phy_filters;
|
||||
enum bios_source dsm_source;
|
||||
|
||||
@@ -402,11 +402,11 @@ static int iwl_uefi_uats_parse(struct uefi_cnv_wlan_uats_data *uats_data,
|
||||
if (uats_data->revision != 1)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(fwrt->uats_table.mcc_to_ap_type_map,
|
||||
memcpy(fwrt->ap_type_cmd.mcc_to_ap_type_map,
|
||||
uats_data->mcc_to_ap_type_map,
|
||||
sizeof(fwrt->uats_table.mcc_to_ap_type_map));
|
||||
sizeof(fwrt->ap_type_cmd.mcc_to_ap_type_map));
|
||||
|
||||
fwrt->uats_valid = true;
|
||||
fwrt->ap_type_cmd_valid = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -429,6 +429,36 @@ void iwl_uefi_get_uats_table(struct iwl_trans *trans,
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_uefi_get_uats_table);
|
||||
|
||||
void iwl_uefi_get_uneb_table(struct iwl_trans *trans,
|
||||
struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct uefi_cnv_wlan_uneb_data *data;
|
||||
|
||||
data = iwl_uefi_get_verified_variable(trans, IWL_UEFI_UNEB_NAME,
|
||||
"UNEB", sizeof(*data), NULL);
|
||||
if (IS_ERR(data))
|
||||
return;
|
||||
|
||||
if (data->revision != 1) {
|
||||
IWL_DEBUG_RADIO(fwrt,
|
||||
"Cannot read UNEB table. rev is invalid\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
BUILD_BUG_ON(sizeof(data->mcc_to_ap_type_map) !=
|
||||
sizeof(fwrt->ap_type_cmd.mcc_to_ap_type_unii9_map));
|
||||
|
||||
memcpy(fwrt->ap_type_cmd.mcc_to_ap_type_unii9_map,
|
||||
data->mcc_to_ap_type_map,
|
||||
sizeof(fwrt->ap_type_cmd.mcc_to_ap_type_unii9_map));
|
||||
|
||||
fwrt->ap_type_cmd_valid = true;
|
||||
|
||||
out:
|
||||
kfree(data);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_uefi_get_uneb_table);
|
||||
|
||||
static void iwl_uefi_set_sar_profile(struct iwl_fw_runtime *fwrt,
|
||||
struct uefi_sar_profile *uefi_sar_prof,
|
||||
u8 prof_index, bool enabled)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define IWL_UEFI_PUNCTURING_NAME L"UefiCnvWlanPuncturing"
|
||||
#define IWL_UEFI_DSBR_NAME L"UefiCnvCommonDSBR"
|
||||
#define IWL_UEFI_WPFC_NAME L"WPFC"
|
||||
#define IWL_UEFI_UNEB_NAME L"CnvUefiWlanUNEB"
|
||||
|
||||
|
||||
#define IWL_SGOM_MAP_SIZE 339
|
||||
@@ -63,6 +64,9 @@ struct uefi_cnv_wlan_uats_data {
|
||||
u8 mcc_to_ap_type_map[IWL_UATS_MAP_SIZE - 1];
|
||||
} __packed;
|
||||
|
||||
/* UNEB's layout is identical to UATS's */
|
||||
#define uefi_cnv_wlan_uneb_data uefi_cnv_wlan_uats_data
|
||||
|
||||
struct uefi_cnv_common_step_data {
|
||||
u8 revision;
|
||||
u8 step_mode;
|
||||
@@ -274,6 +278,8 @@ int iwl_uefi_get_dsm(struct iwl_fw_runtime *fwrt, enum iwl_dsm_funcs func,
|
||||
void iwl_uefi_get_sgom_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt);
|
||||
void iwl_uefi_get_uats_table(struct iwl_trans *trans,
|
||||
struct iwl_fw_runtime *fwrt);
|
||||
void iwl_uefi_get_uneb_table(struct iwl_trans *trans,
|
||||
struct iwl_fw_runtime *fwrt);
|
||||
int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt);
|
||||
int iwl_uefi_get_dsbr(struct iwl_fw_runtime *fwrt, u32 *value);
|
||||
int iwl_uefi_get_phy_filters(struct iwl_fw_runtime *fwrt);
|
||||
@@ -373,6 +379,11 @@ iwl_uefi_get_uats_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
iwl_uefi_get_uneb_table(struct iwl_trans *trans, struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
int iwl_uefi_get_puncturing(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
|
||||
@@ -513,7 +513,7 @@ static int iwl_mld_config_fw(struct iwl_mld *mld)
|
||||
return ret;
|
||||
|
||||
iwl_mld_init_tas(mld);
|
||||
iwl_mld_init_uats(mld);
|
||||
iwl_mld_init_ap_type_tables(mld);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ void iwl_mld_get_bios_tables(struct iwl_mld *mld)
|
||||
}
|
||||
|
||||
iwl_uefi_get_uats_table(mld->trans, &mld->fwrt);
|
||||
iwl_uefi_get_uneb_table(mld->trans, &mld->fwrt);
|
||||
|
||||
iwl_bios_get_phy_filters(&mld->fwrt);
|
||||
}
|
||||
@@ -352,21 +353,42 @@ void iwl_mld_configure_lari(struct iwl_mld *mld)
|
||||
ret);
|
||||
}
|
||||
|
||||
void iwl_mld_init_uats(struct iwl_mld *mld)
|
||||
void iwl_mld_init_ap_type_tables(struct iwl_mld *mld)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
MCC_ALLOWED_AP_TYPE_CMD),
|
||||
.data[0] = &mld->fwrt.uats_table,
|
||||
.len[0] = sizeof(mld->fwrt.uats_table),
|
||||
.data[0] = &mld->fwrt.ap_type_cmd,
|
||||
.len[0] = sizeof(mld->fwrt.ap_type_cmd),
|
||||
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
|
||||
};
|
||||
|
||||
if (!mld->fwrt.uats_valid)
|
||||
if (!mld->fwrt.ap_type_cmd_valid)
|
||||
return;
|
||||
|
||||
ret = iwl_mld_send_cmd(mld, &cmd);
|
||||
if (iwl_fw_lookup_cmd_ver(mld->fw, cmd.id, 1) == 1) {
|
||||
struct iwl_mcc_allowed_ap_type_cmd_v1 *cmd_v1 =
|
||||
kzalloc(sizeof(*cmd_v1), GFP_KERNEL);
|
||||
|
||||
if (!cmd_v1)
|
||||
return;
|
||||
|
||||
BUILD_BUG_ON(sizeof(mld->fwrt.ap_type_cmd.mcc_to_ap_type_map) !=
|
||||
sizeof(cmd_v1->mcc_to_ap_type_map));
|
||||
|
||||
memcpy(cmd_v1->mcc_to_ap_type_map,
|
||||
mld->fwrt.ap_type_cmd.mcc_to_ap_type_map,
|
||||
sizeof(mld->fwrt.ap_type_cmd.mcc_to_ap_type_map));
|
||||
|
||||
cmd.data[0] = cmd_v1;
|
||||
cmd.len[0] = sizeof(*cmd_v1);
|
||||
ret = iwl_mld_send_cmd(mld, &cmd);
|
||||
kfree(cmd_v1);
|
||||
} else {
|
||||
ret = iwl_mld_send_cmd(mld, &cmd);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
IWL_ERR(mld, "failed to send MCC_ALLOWED_AP_TYPE_CMD (%d)\n",
|
||||
ret);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
void iwl_mld_get_bios_tables(struct iwl_mld *mld);
|
||||
void iwl_mld_configure_lari(struct iwl_mld *mld);
|
||||
void iwl_mld_init_uats(struct iwl_mld *mld);
|
||||
void iwl_mld_init_ap_type_tables(struct iwl_mld *mld);
|
||||
void iwl_mld_init_tas(struct iwl_mld *mld);
|
||||
|
||||
int iwl_mld_init_ppag(struct iwl_mld *mld);
|
||||
|
||||
@@ -459,23 +459,18 @@ static void iwl_mvm_phy_filter_init(struct iwl_mvm *mvm,
|
||||
|
||||
static void iwl_mvm_uats_init(struct iwl_mvm *mvm)
|
||||
{
|
||||
int cmd_id = WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
MCC_ALLOWED_AP_TYPE_CMD);
|
||||
struct iwl_mcc_allowed_ap_type_cmd_v1 cmd = {};
|
||||
u8 cmd_ver;
|
||||
int ret;
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
MCC_ALLOWED_AP_TYPE_CMD),
|
||||
.flags = 0,
|
||||
.data[0] = &mvm->fwrt.uats_table,
|
||||
.len[0] = sizeof(mvm->fwrt.uats_table),
|
||||
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
|
||||
};
|
||||
|
||||
if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
|
||||
IWL_DEBUG_RADIO(mvm, "UATS feature is not supported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
|
||||
cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd_id,
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
if (cmd_ver != 1) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
@@ -486,10 +481,17 @@ static void iwl_mvm_uats_init(struct iwl_mvm *mvm)
|
||||
|
||||
iwl_uefi_get_uats_table(mvm->trans, &mvm->fwrt);
|
||||
|
||||
if (!mvm->fwrt.uats_valid)
|
||||
if (!mvm->fwrt.ap_type_cmd_valid)
|
||||
return;
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &cmd);
|
||||
BUILD_BUG_ON(sizeof(mvm->fwrt.ap_type_cmd.mcc_to_ap_type_map) !=
|
||||
sizeof(cmd.mcc_to_ap_type_map));
|
||||
|
||||
memcpy(cmd.mcc_to_ap_type_map,
|
||||
mvm->fwrt.ap_type_cmd.mcc_to_ap_type_map,
|
||||
sizeof(mvm->fwrt.ap_type_cmd.mcc_to_ap_type_map));
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cmd), &cmd);
|
||||
if (ret < 0)
|
||||
IWL_ERR(mvm, "failed to send MCC_ALLOWED_AP_TYPE_CMD (%d)\n",
|
||||
ret);
|
||||
|
||||
Reference in New Issue
Block a user