summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnjaneyulu <pagadala.yesu.anjaneyulu@intel.com>2024-01-22 16:28:36 +0200
committeriwlwifi publisher <>2024-04-17 12:52:17 +0000
commitc1d95050c7aea32bb0e954902c127a13914181bf (patch)
tree4247ca1a7a5a7da6bf73c5d3e56c09e5f8312101
parent186c86921c01a9b1ca4f7d5561bd0869c9b46a61 (diff)
downloadbackport-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.h62
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c64
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rfi.c37
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/vendor-cmd.c16
-rw-r--r--versions2
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;
diff --git a/versions b/versions
index 8fa4910514..014a01c81c 100644
--- a/versions
+++ b/versions
@@ -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"