Commit 92883a52 authored by Luca Coelho's avatar Luca Coelho Committed by Kalle Valo
Browse files

iwlwifi: remove deprecated broadcast filtering feature

This feature has been deprecated and should not be used anymore.  With
newer firmwares, namely *-67.ucode and above, trying to use it causes an
assertion failure in the FW, similar to this:

[Tue Jan 11 20:05:24 2022] iwlwifi 0000:04:00.0: 0x00001062 | ADVANCED_SYSASSERT

In order to prevent this feature from being used, remove it entirely
and get rid of the Kconfig option that
enables it (IWLWIFI_BCAST_FILTERING).

Fixes: cbaa6aee ("iwlwifi: bump FW API to 67 for AX devices")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215488


Cc: stable@vger.kernel.org # 5.16.x
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/iwlwifi.20220128144623.9241e049f13e.Ia4f282813ca2ddd24c13427823519113f2bbebf2@changeid
parent 30de48b4
Loading
Loading
Loading
Loading
+0 −13
Original line number Diff line number Diff line
@@ -80,19 +80,6 @@ config IWLWIFI_OPMODE_MODULAR
comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM"
	depends on IWLDVM=n && IWLMVM=n

config IWLWIFI_BCAST_FILTERING
	bool "Enable broadcast filtering"
	depends on IWLMVM
	help
	  Say Y here to enable default bcast filtering configuration.

	  Enabling broadcast filtering will drop any incoming wireless
	  broadcast frames, except some very specific predefined
	  patterns (e.g. incoming arp requests).

	  If unsure, don't enable this option, as some programs might
	  expect incoming broadcasts for their normal operations.

menu "Debugging Options"

config IWLWIFI_DEBUG
+0 −5
Original line number Diff line number Diff line
@@ -501,11 +501,6 @@ enum iwl_legacy_cmds {
	 */
	DEBUG_LOG_MSG = 0xf7,

	/**
	 * @BCAST_FILTER_CMD: &struct iwl_bcast_filter_cmd
	 */
	BCAST_FILTER_CMD = 0xcf,

	/**
	 * @MCAST_FILTER_CMD: &struct iwl_mcast_filter_cmd
	 */
+0 −88
Original line number Diff line number Diff line
@@ -36,92 +36,4 @@ struct iwl_mcast_filter_cmd {
	u8 addr_list[0];
} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */

#define MAX_BCAST_FILTERS 8
#define MAX_BCAST_FILTER_ATTRS 2

/**
 * enum iwl_mvm_bcast_filter_attr_offset - written by fw for each Rx packet
 * @BCAST_FILTER_OFFSET_PAYLOAD_START: offset is from payload start.
 * @BCAST_FILTER_OFFSET_IP_END: offset is from ip header end (i.e.
 *	start of ip payload).
 */
enum iwl_mvm_bcast_filter_attr_offset {
	BCAST_FILTER_OFFSET_PAYLOAD_START = 0,
	BCAST_FILTER_OFFSET_IP_END = 1,
};

/**
 * struct iwl_fw_bcast_filter_attr - broadcast filter attribute
 * @offset_type:	&enum iwl_mvm_bcast_filter_attr_offset.
 * @offset:	starting offset of this pattern.
 * @reserved1:	reserved
 * @val:	value to match - big endian (MSB is the first
 *		byte to match from offset pos).
 * @mask:	mask to match (big endian).
 */
struct iwl_fw_bcast_filter_attr {
	u8 offset_type;
	u8 offset;
	__le16 reserved1;
	__be32 val;
	__be32 mask;
} __packed; /* BCAST_FILTER_ATT_S_VER_1 */

/**
 * enum iwl_mvm_bcast_filter_frame_type - filter frame type
 * @BCAST_FILTER_FRAME_TYPE_ALL: consider all frames.
 * @BCAST_FILTER_FRAME_TYPE_IPV4: consider only ipv4 frames
 */
enum iwl_mvm_bcast_filter_frame_type {
	BCAST_FILTER_FRAME_TYPE_ALL = 0,
	BCAST_FILTER_FRAME_TYPE_IPV4 = 1,
};

/**
 * struct iwl_fw_bcast_filter - broadcast filter
 * @discard: discard frame (1) or let it pass (0).
 * @frame_type: &enum iwl_mvm_bcast_filter_frame_type.
 * @reserved1: reserved
 * @num_attrs: number of valid attributes in this filter.
 * @attrs: attributes of this filter. a filter is considered matched
 *	only when all its attributes are matched (i.e. AND relationship)
 */
struct iwl_fw_bcast_filter {
	u8 discard;
	u8 frame_type;
	u8 num_attrs;
	u8 reserved1;
	struct iwl_fw_bcast_filter_attr attrs[MAX_BCAST_FILTER_ATTRS];
} __packed; /* BCAST_FILTER_S_VER_1 */

/**
 * struct iwl_fw_bcast_mac - per-mac broadcast filtering configuration.
 * @default_discard: default action for this mac (discard (1) / pass (0)).
 * @reserved1: reserved
 * @attached_filters: bitmap of relevant filters for this mac.
 */
struct iwl_fw_bcast_mac {
	u8 default_discard;
	u8 reserved1;
	__le16 attached_filters;
} __packed; /* BCAST_MAC_CONTEXT_S_VER_1 */

/**
 * struct iwl_bcast_filter_cmd - broadcast filtering configuration
 * @disable: enable (0) / disable (1)
 * @max_bcast_filters: max number of filters (MAX_BCAST_FILTERS)
 * @max_macs: max number of macs (NUM_MAC_INDEX_DRIVER)
 * @reserved1: reserved
 * @filters: broadcast filters
 * @macs: broadcast filtering configuration per-mac
 */
struct iwl_bcast_filter_cmd {
	u8 disable;
	u8 max_bcast_filters;
	u8 max_macs;
	u8 reserved1;
	struct iwl_fw_bcast_filter filters[MAX_BCAST_FILTERS];
	struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER];
} __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */

#endif /* __iwl_fw_api_filter_h__ */
+0 −2
Original line number Diff line number Diff line
@@ -181,7 +181,6 @@ struct iwl_ucode_capa {
 * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
 * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
 * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
 * @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
 */
enum iwl_ucode_tlv_flag {
@@ -196,7 +195,6 @@ enum iwl_ucode_tlv_flag {
	IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT	= BIT(24),
	IWL_UCODE_TLV_FLAGS_EBS_SUPPORT		= BIT(25),
	IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD	= BIT(26),
	IWL_UCODE_TLV_FLAGS_BCAST_FILTERING	= BIT(29),
};

typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
+0 −203
Original line number Diff line number Diff line
@@ -1369,189 +1369,6 @@ static ssize_t iwl_dbgfs_dbg_time_point_write(struct iwl_mvm *mvm,
	return count;
}

#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
					    char __user *user_buf,
					    size_t count, loff_t *ppos)
{
	struct iwl_mvm *mvm = file->private_data;
	struct iwl_bcast_filter_cmd cmd;
	const struct iwl_fw_bcast_filter *filter;
	char *buf;
	int bufsz = 1024;
	int i, j, pos = 0;
	ssize_t ret;

	buf = kzalloc(bufsz, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	mutex_lock(&mvm->mutex);
	if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
		ADD_TEXT("None\n");
		mutex_unlock(&mvm->mutex);
		goto out;
	}
	mutex_unlock(&mvm->mutex);

	for (i = 0; cmd.filters[i].attrs[0].mask; i++) {
		filter = &cmd.filters[i];

		ADD_TEXT("Filter [%d]:\n", i);
		ADD_TEXT("\tDiscard=%d\n", filter->discard);
		ADD_TEXT("\tFrame Type: %s\n",
			 filter->frame_type ? "IPv4" : "Generic");

		for (j = 0; j < ARRAY_SIZE(filter->attrs); j++) {
			const struct iwl_fw_bcast_filter_attr *attr;

			attr = &filter->attrs[j];
			if (!attr->mask)
				break;

			ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n",
				 j, attr->offset,
				 attr->offset_type ? "IP End" :
						     "Payload Start",
				 be32_to_cpu(attr->mask),
				 be32_to_cpu(attr->val),
				 le16_to_cpu(attr->reserved1));
		}
	}
out:
	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
	kfree(buf);
	return ret;
}

static ssize_t iwl_dbgfs_bcast_filters_write(struct iwl_mvm *mvm, char *buf,
					     size_t count, loff_t *ppos)
{
	int pos, next_pos;
	struct iwl_fw_bcast_filter filter = {};
	struct iwl_bcast_filter_cmd cmd;
	u32 filter_id, attr_id, mask, value;
	int err = 0;

	if (sscanf(buf, "%d %hhi %hhi %n", &filter_id, &filter.discard,
		   &filter.frame_type, &pos) != 3)
		return -EINVAL;

	if (filter_id >= ARRAY_SIZE(mvm->dbgfs_bcast_filtering.cmd.filters) ||
	    filter.frame_type > BCAST_FILTER_FRAME_TYPE_IPV4)
		return -EINVAL;

	for (attr_id = 0; attr_id < ARRAY_SIZE(filter.attrs);
	     attr_id++) {
		struct iwl_fw_bcast_filter_attr *attr =
				&filter.attrs[attr_id];

		if (pos >= count)
			break;

		if (sscanf(&buf[pos], "%hhi %hhi %i %i %n",
			   &attr->offset, &attr->offset_type,
			   &mask, &value, &next_pos) != 4)
			return -EINVAL;

		attr->mask = cpu_to_be32(mask);
		attr->val = cpu_to_be32(value);
		if (mask)
			filter.num_attrs++;

		pos += next_pos;
	}

	mutex_lock(&mvm->mutex);
	memcpy(&mvm->dbgfs_bcast_filtering.cmd.filters[filter_id],
	       &filter, sizeof(filter));

	/* send updated bcast filtering configuration */
	if (iwl_mvm_firmware_running(mvm) &&
	    mvm->dbgfs_bcast_filtering.override &&
	    iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
		err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
					   sizeof(cmd), &cmd);
	mutex_unlock(&mvm->mutex);

	return err ?: count;
}

static ssize_t iwl_dbgfs_bcast_filters_macs_read(struct file *file,
						 char __user *user_buf,
						 size_t count, loff_t *ppos)
{
	struct iwl_mvm *mvm = file->private_data;
	struct iwl_bcast_filter_cmd cmd;
	char *buf;
	int bufsz = 1024;
	int i, pos = 0;
	ssize_t ret;

	buf = kzalloc(bufsz, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	mutex_lock(&mvm->mutex);
	if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
		ADD_TEXT("None\n");
		mutex_unlock(&mvm->mutex);
		goto out;
	}
	mutex_unlock(&mvm->mutex);

	for (i = 0; i < ARRAY_SIZE(cmd.macs); i++) {
		const struct iwl_fw_bcast_mac *mac = &cmd.macs[i];

		ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n",
			 i, mac->default_discard, mac->attached_filters);
	}
out:
	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
	kfree(buf);
	return ret;
}

static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
						  char *buf, size_t count,
						  loff_t *ppos)
{
	struct iwl_bcast_filter_cmd cmd;
	struct iwl_fw_bcast_mac mac = {};
	u32 mac_id, attached_filters;
	int err = 0;

	if (!mvm->bcast_filters)
		return -ENOENT;

	if (sscanf(buf, "%d %hhi %i", &mac_id, &mac.default_discard,
		   &attached_filters) != 3)
		return -EINVAL;

	if (mac_id >= ARRAY_SIZE(cmd.macs) ||
	    mac.default_discard > 1 ||
	    attached_filters >= BIT(ARRAY_SIZE(cmd.filters)))
		return -EINVAL;

	mac.attached_filters = cpu_to_le16(attached_filters);

	mutex_lock(&mvm->mutex);
	memcpy(&mvm->dbgfs_bcast_filtering.cmd.macs[mac_id],
	       &mac, sizeof(mac));

	/* send updated bcast filtering configuration */
	if (iwl_mvm_firmware_running(mvm) &&
	    mvm->dbgfs_bcast_filtering.override &&
	    iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
		err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
					   sizeof(cmd), &cmd);
	mutex_unlock(&mvm->mutex);

	return err ?: count;
}
#endif

#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
	_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -1881,11 +1698,6 @@ MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);

MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);

#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
#endif

#ifdef CONFIG_ACPI
MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
#endif
@@ -2097,21 +1909,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)

	MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR);

#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
	if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
		bcast_dir = debugfs_create_dir("bcast_filtering",
					       mvm->debugfs_dir);

		debugfs_create_bool("override", 0600, bcast_dir,
				    &mvm->dbgfs_bcast_filtering.override);

		MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters,
					   bcast_dir, 0600);
		MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs,
					   bcast_dir, 0600);
	}
#endif

#ifdef CONFIG_PM_SLEEP
	MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
	debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
Loading