diff options
author | Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com> | 2024-01-22 16:28:36 +0200 |
---|---|---|
committer | iwlwifi publisher <> | 2024-04-17 12:52:17 +0000 |
commit | c1d95050c7aea32bb0e954902c127a13914181bf (patch) | |
tree | 4247ca1a7a5a7da6bf73c5d3e56c09e5f8312101 | |
parent | 186c86921c01a9b1ca4f7d5561bd0869c9b46a61 (diff) | |
download | backport-iwlwifi-c1d95050c7aea32bb0e954902c127a13914181bf.tar.gz |
wifi: iwlwifi: mvm: rfi: Add support for rfi config cmd resp notification v2
Version 2 notification will add ability to get DLVR table from firmware.
While on it rename iwl_rfi_lut_entry to iwl_rfi_ddr_lut_entry.
type=feature
ticket=jira:WIFI-341600
Signed-off-by: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Change-Id: Ife09acc4f745e934c9bdda7b1869b9fe5d72613e
Reviewed-on: https://gerritwcs.ir.intel.com/c/iwlwifi-stack-dev/+/92981
tested: iil_jenkins iil_jenkins <EC.GER.UNIX.IIL.JENKINS@INTEL.COM>
Tested-by: iil_jenkins iil_jenkins <EC.GER.UNIX.IIL.JENKINS@INTEL.COM>
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
x-iwlwifi-stack-dev: 53524793fa441ae6692719380b8abf05ce162e1c
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/fw/api/rfi.h | 62 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c | 64 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rfi.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c | 16 | ||||
-rw-r--r-- | versions | 2 |
6 files changed, 133 insertions, 52 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/rfi.h b/drivers/net/wireless/intel/iwlwifi/fw/api/rfi.h index daf0ebf6ee..78647d3448 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/rfi.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/rfi.h @@ -5,21 +5,38 @@ #ifndef __iwl_fw_api_rfi_h__ #define __iwl_fw_api_rfi_h__ -#define IWL_RFI_LUT_ENTRY_CHANNELS_NUM 15 +#define IWL_RFI_DDR_LUT_ENTRY_CHANNELS_NUM 15 #define IWL_RFI_DDR_LUT_SIZE 44 -#define IWL_RFI_LUT_INSTALLED_SIZE 4 +#define IWL_RFI_DDR_LUT_INSTALLED_SIZE 4 +#define IWL_RFI_DLVR_LUT_ENTRY_CHANNELS_NUM 36 +#define IWL_RFI_DLVR_LUT_INSTALLED_SIZE 4 /** - * struct iwl_rfi_lut_entry - an entry in the RFI frequency LUT. + * struct iwl_rfi_ddr_lut_entry - an entry in the RFI DDR frequency LUT. * * @freq: frequency * @channels: channels that can be interfered at frequency freq (at most 15) * @bands: the corresponding bands */ -struct iwl_rfi_lut_entry { +struct iwl_rfi_ddr_lut_entry { __le16 freq; - u8 channels[IWL_RFI_LUT_ENTRY_CHANNELS_NUM]; - u8 bands[IWL_RFI_LUT_ENTRY_CHANNELS_NUM]; + u8 channels[IWL_RFI_DDR_LUT_ENTRY_CHANNELS_NUM]; + u8 bands[IWL_RFI_DDR_LUT_ENTRY_CHANNELS_NUM]; +} __packed; + +/** + * struct iwl_rfi_dlvr_lut_entry - an entry in the RFI DLVR frequency LUT. + * + * @freq: DLVR frequency + * @channels: channels that can be interfered at frequency freq (at most 36) + * @bands: the corresponding bands + * @reserved: reserved for DW alignment + */ +struct iwl_rfi_dlvr_lut_entry { + __le16 freq; + u8 channels[IWL_RFI_DLVR_LUT_ENTRY_CHANNELS_NUM]; + u8 bands[IWL_RFI_DLVR_LUT_ENTRY_CHANNELS_NUM]; + u8 reserved[2]; } __packed; /** @@ -37,13 +54,13 @@ enum rfi_memory_support_mask { * struct iwl_rfi_config_cmd - RFI configuration table * * @rfi_memory_support: memory support mask @enum rfi_memory_support_mask - * @table: a table can have 44 frequency/channel mappings + * @ddr_table: a table can have 44 frequency/channel mappings * @oem: specifies if this is the default table or set by OEM * @reserved: (reserved/padding) */ struct iwl_rfi_config_cmd { __le32 rfi_memory_support; - struct iwl_rfi_lut_entry table[IWL_RFI_DDR_LUT_SIZE]; + struct iwl_rfi_ddr_lut_entry ddr_table[IWL_RFI_DDR_LUT_SIZE]; u8 oem; u8 reserved[3]; } __packed; /* RFI_CONFIG_CMD_API_S_VER_3 */ @@ -52,26 +69,43 @@ struct iwl_rfi_config_cmd { * enum iwl_rfi_freq_table_status - status of the frequency table query * @RFI_FREQ_TABLE_OK: can be used * @RFI_FREQ_TABLE_DVFS_NOT_READY: DVFS is not ready yet, should try later - * @RFI_FREQ_TABLE_DISABLED: the feature is disabled in FW + * @RFI_FREQ_DDR_TABLE_DISABLED: DDR feature is disabled in FW + * @RFI_FREQ_DLVR_TABLE_DISABLED: DLVR feature is disabled in FW + * @RFI_FREQ_ALL_TABLES_DISABLED: DDR, DLVR features are disabled in FW */ enum iwl_rfi_freq_table_status { RFI_FREQ_TABLE_OK, RFI_FREQ_TABLE_DVFS_NOT_READY, - RFI_FREQ_TABLE_DISABLED, + RFI_FREQ_DDR_TABLE_DISABLED, + RFI_FREQ_DLVR_TABLE_DISABLED, + RFI_FREQ_ALL_TABLES_DISABLED, }; /** - * struct iwl_rfi_freq_table_resp_cmd - get the rfi freq table used by FW + * struct iwl_rfi_freq_table_resp_cmd_v1 - get the rfi freq table used by FW * - * @table: table used by FW + * @ddr_table: DDR table used by FW &iwl_rfi_ddr_lut_entry. * @status: see &iwl_rfi_freq_table_status */ -struct iwl_rfi_freq_table_resp_cmd { - struct iwl_rfi_lut_entry table[IWL_RFI_LUT_INSTALLED_SIZE]; +struct iwl_rfi_freq_table_resp_cmd_v1 { + struct iwl_rfi_ddr_lut_entry ddr_table[IWL_RFI_DDR_LUT_INSTALLED_SIZE]; __le32 status; } __packed; /* RFI_CONFIG_CMD_API_S_VER_1 */ /** + * struct iwl_rfi_freq_table_resp_cmd - get the rfi freq tables used by FW + * + * @ddr_table: DDR table used by FW &iwl_rfi_ddr_lut_entry. + * @status: see &iwl_rfi_freq_table_status + * @dlvr_table: DLVR table used by FW &iwl_rfi_dlvr_lut_entry. + */ +struct iwl_rfi_freq_table_resp_cmd { + struct iwl_rfi_ddr_lut_entry ddr_table[IWL_RFI_DDR_LUT_INSTALLED_SIZE]; + __le32 status; + struct iwl_rfi_dlvr_lut_entry dlvr_table[IWL_RFI_DLVR_LUT_INSTALLED_SIZE]; +} __packed; /* RFI_CONFIG_CMD_API_S_VER_2 */ + +/** * enum iwl_rfi_support_reason - indicate error or pmc supported * * @IWL_RFI_RESET_FAILURE_SEND_TO_PEER: Failure due to send to peer diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 3119ad1fc4..825f75523e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -2615,8 +2615,14 @@ static ssize_t iwl_dbgfs_rfi_freq_table_write(struct iwl_mvm *mvm, char *buf, * the table; So, need 5 chars for the "freq: " part and each tuple afterwards * needs 6 characters for numbers and 5 for the punctuation around. */ -#define IWL_RFI_BUF_SIZE (IWL_RFI_LUT_INSTALLED_SIZE *\ - (5 + IWL_RFI_LUT_ENTRY_CHANNELS_NUM * (6 + 5))) +#define IWL_RFI_DDR_BUF_SIZE (IWL_RFI_DDR_LUT_INSTALLED_SIZE *\ + (5 + IWL_RFI_DDR_LUT_ENTRY_CHANNELS_NUM *\ + (6 + 5))) +#define IWL_RFI_DLVR_BUF_SIZE (IWL_RFI_DLVR_LUT_INSTALLED_SIZE *\ + (5 + IWL_RFI_DLVR_LUT_ENTRY_CHANNELS_NUM *\ + (6 + 5))) +/* Extra 32 for "DDR and DLVR table" message */ +#define IWL_RFI_BUF_SIZE (IWL_RFI_DDR_BUF_SIZE + IWL_RFI_DLVR_BUF_SIZE + 32) static ssize_t iwl_dbgfs_rfi_freq_table_read(struct file *file, char __user *user_buf, @@ -2625,34 +2631,62 @@ static ssize_t iwl_dbgfs_rfi_freq_table_read(struct file *file, struct iwl_mvm *mvm = file->private_data; struct iwl_rfi_freq_table_resp_cmd *resp; u32 status; - char buf[IWL_RFI_BUF_SIZE]; - int i, j, pos = 0; + char *buf; + int i, j, pos = 0, bufsz = IWL_RFI_BUF_SIZE; + size_t ret; + u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, SYSTEM_GROUP, + RFI_GET_FREQ_TABLE_CMD, 0); resp = iwl_rfi_get_freq_table(mvm); if (IS_ERR(resp)) return PTR_ERR(resp); + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + kfree(resp); + return -ENOMEM; + } + status = le32_to_cpu(resp->status); if (status != RFI_FREQ_TABLE_OK) { - scnprintf(buf, IWL_RFI_BUF_SIZE, "status = %d\n", status); + pos = scnprintf(buf, bufsz, "status = %d\n", status); goto out; } - for (i = 0; i < ARRAY_SIZE(resp->table); i++) { - pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "%d: ", - resp->table[i].freq); + pos = scnprintf(buf + pos, bufsz - pos, "DDR table:\n"); + for (i = 0; i < ARRAY_SIZE(resp->ddr_table); i++) { + pos += scnprintf(buf + pos, bufsz - pos, "%u: ", + le16_to_cpu(resp->ddr_table[i].freq)); + + for (j = 0; j < ARRAY_SIZE(resp->ddr_table[0].channels); j++) + pos += scnprintf(buf + pos, bufsz - pos, + "(%u, %u) ", + resp->ddr_table[i].channels[j], + resp->ddr_table[i].bands[j]); + pos += scnprintf(buf + pos, bufsz - pos, "\n"); + } - for (j = 0; j < ARRAY_SIZE(resp->table[i].channels); j++) - pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, - "(%d, %d) ", - resp->table[i].channels[j], - resp->table[i].bands[j]); - pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "\n"); + if (notif_ver < 2) + goto out; + + pos += scnprintf(buf + pos, bufsz - pos, "DLVR table:\n"); + for (i = 0; i < ARRAY_SIZE(resp->dlvr_table); i++) { + pos += scnprintf(buf + pos, bufsz - pos, "%u: ", + le16_to_cpu(resp->dlvr_table[i].freq)); + + for (j = 0; j < ARRAY_SIZE(resp->dlvr_table[0].channels); j++) + pos += scnprintf(buf + pos, bufsz - pos, + "(%u, %u) ", + resp->dlvr_table[i].channels[j], + resp->dlvr_table[i].bands[j]); + pos += scnprintf(buf + pos, bufsz - pos, "\n"); } out: kfree(resp); - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; } MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 49f136cdf8..7b3991fdce 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2516,9 +2516,9 @@ u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm, bool iwl_rfi_supported(struct iwl_mvm *mvm, bool so_rfi_mode, bool is_ddr); int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, - struct iwl_rfi_lut_entry *rfi_table, + struct iwl_rfi_ddr_lut_entry *rfi_table, bool is_set_master_cmd, bool force_send_table); -struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm); +void *iwl_rfi_get_freq_table(struct iwl_mvm *mvm); void iwl_rfi_support_notif_handler(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c index 56bcfc807e..b0d464576c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rfi.c @@ -11,7 +11,7 @@ * frequency values in the adjusted format. */ static const -struct iwl_rfi_lut_entry iwl_rfi_ddr_table[IWL_RFI_DDR_LUT_SIZE] = { +struct iwl_rfi_ddr_lut_entry iwl_rfi_ddr_table[IWL_RFI_DDR_LUT_SIZE] = { /* frequency 2600MHz */ {cpu_to_le16(156), {34, 36, 38, 40, 42, 50}, {PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, PHY_BAND_5, @@ -186,7 +186,7 @@ bool iwl_rfi_supported(struct iwl_mvm *mvm, bool so_rfi_mode, bool is_ddr) } int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, - struct iwl_rfi_lut_entry *rfi_ddr_table, + struct iwl_rfi_ddr_lut_entry *rfi_ddr_table, bool is_set_master_cmd, bool force_send_table) { struct iwl_rfi_config_cmd *cmd = NULL; @@ -265,14 +265,16 @@ int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, */ if (!force_send_table && rfi_ddr_table && mvm->iwl_prev_rfi_config_cmd && - !memcmp(rfi_ddr_table, mvm->iwl_prev_rfi_config_cmd->table, - sizeof(mvm->iwl_prev_rfi_config_cmd->table))) { + !memcmp(rfi_ddr_table, + mvm->iwl_prev_rfi_config_cmd->ddr_table, + sizeof(mvm->iwl_prev_rfi_config_cmd->ddr_table))) { IWL_DEBUG_FW(mvm, "Skip RFI_CONFIG_CMD sending\n"); goto out; /* send RFI_CONFIG_CMD to FW with OEM ddr table */ } else if (rfi_ddr_table) { IWL_DEBUG_FW(mvm, "Sending oem DDR superset table\n"); - memcpy(cmd->table, rfi_ddr_table, sizeof(cmd->table)); + memcpy(cmd->ddr_table, rfi_ddr_table, + sizeof(cmd->ddr_table)); /* notify FW the table is not the default one */ cmd->oem = 1; /* send previous RFI_CONFIG_CMD once again as FW lost RFI DDR @@ -283,8 +285,9 @@ int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, "Sending buffered %s DDR superset table\n", mvm->iwl_prev_rfi_config_cmd->oem ? "oem" : "default"); - memcpy(cmd->table, mvm->iwl_prev_rfi_config_cmd->table, - sizeof(cmd->table)); + memcpy(cmd->ddr_table, + mvm->iwl_prev_rfi_config_cmd->ddr_table, + sizeof(cmd->ddr_table)); cmd->oem = mvm->iwl_prev_rfi_config_cmd->oem; /* don't send previous RFI_CONFIG_CMD as FW has same table */ } else if (mvm->iwl_prev_rfi_config_cmd) { @@ -294,8 +297,8 @@ int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm, } else { IWL_DEBUG_FW(mvm, "Sending default DDR superset table\n"); - memcpy(cmd->table, iwl_rfi_ddr_table, - sizeof(cmd->table)); + memcpy(cmd->ddr_table, iwl_rfi_ddr_table, + sizeof(cmd->ddr_table)); } } @@ -318,15 +321,25 @@ out: return ret; } -struct iwl_rfi_freq_table_resp_cmd *iwl_rfi_get_freq_table(struct iwl_mvm *mvm) +void *iwl_rfi_get_freq_table(struct iwl_mvm *mvm) { - struct iwl_rfi_freq_table_resp_cmd *resp; - int resp_size = sizeof(*resp); + void *resp; + int resp_size; int ret; struct iwl_host_cmd cmd = { .id = WIDE_ID(SYSTEM_GROUP, RFI_GET_FREQ_TABLE_CMD), .flags = CMD_WANT_SKB, }; + u8 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, SYSTEM_GROUP, + RFI_GET_FREQ_TABLE_CMD, + IWL_FW_CMD_VER_UNKNOWN); + + if (notif_ver == 1) + resp_size = sizeof(struct iwl_rfi_freq_table_resp_cmd_v1); + else if (notif_ver == 2) + resp_size = sizeof(struct iwl_rfi_freq_table_resp_cmd); + else + return ERR_PTR(-EOPNOTSUPP); if (!iwl_rfi_supported(mvm, mvm->force_enable_rfi, true)) return ERR_PTR(-EOPNOTSUPP); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c b/drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c index 210142e766..a92e8a0c40 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c @@ -446,7 +446,7 @@ static int iwl_vendor_rfi_ddr_get_table(struct wiphy *wiphy, { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - struct iwl_rfi_freq_table_resp_cmd *resp; + struct iwl_rfi_freq_table_resp_cmd_v1 *resp; struct sk_buff *skb = NULL; struct nlattr *rfim_info; int i, ret; @@ -474,15 +474,15 @@ static int iwl_vendor_rfi_ddr_get_table(struct wiphy *wiphy, goto err; } - for (i = 0; i < 4; i++) { + for (i = 0; i < ARRAY_SIZE(resp->ddr_table); i++) { if (nla_put_u16(skb, IWL_MVM_VENDOR_ATTR_RFIM_FREQ, - le16_to_cpu(resp->table[i].freq)) || + le16_to_cpu(resp->ddr_table[i].freq)) || nla_put(skb, IWL_MVM_VENDOR_ATTR_RFIM_CHANNELS, - sizeof(resp->table[i].channels), - resp->table[i].channels) || + sizeof(resp->ddr_table[i].channels), + resp->ddr_table[i].channels) || nla_put(skb, IWL_MVM_VENDOR_ATTR_RFIM_BANDS, - sizeof(resp->table[i].bands), - resp->table[i].bands)) { + sizeof(resp->ddr_table[i].bands), + resp->ddr_table[i].bands)) { ret = -ENOBUFS; goto err; } @@ -505,7 +505,7 @@ static int iwl_vendor_rfi_ddr_set_table(struct wiphy *wiphy, { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - struct iwl_rfi_lut_entry *rfi_ddr_table = NULL; + struct iwl_rfi_ddr_lut_entry *rfi_ddr_table = NULL; struct nlattr **tb; struct nlattr *attr; int rem, err = 0; @@ -2,4 +2,4 @@ BACKPORTS_VERSION="(see git)" BACKPORTED_KERNEL_VERSION="(see git)" BACKPORTED_KERNEL_NAME="iwlwifi" BACKPORTS_BUILD_TSTAMP=__DATE__ \" \" __TIME__ -BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:11912:05bb6244" +BACKPORTS_GIT_TRACKED="iwlwifi-stack-public:master:11913:53524793" |