Commit c21eebb5 authored by Eyal Shapira's avatar Eyal Shapira Committed by John W. Linville
Browse files

wl12xx: add RX filters ACX commands



More prep work for wowlan patterns.
Added ACXs to set global RX filter behavior and
enable or disable a specific filter.

Signed-off-by: default avatarEyal Shapira <eyal@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent a6eab0c8
Loading
Loading
Loading
Loading
+79 −0
Original line number Diff line number Diff line
@@ -1714,3 +1714,82 @@ out:
	return ret;

}

/* Set the global behaviour of RX filters - On/Off + default action */
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
					enum rx_filter_action action)
{
	struct acx_default_rx_filter *acx;
	int ret;

	wl1271_debug(DEBUG_ACX, "acx default rx filter en: %d act: %d",
		     enable, action);

	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
	if (!acx)
		return -ENOMEM;

	acx->enable = enable;
	acx->default_action = action;

	ret = wl1271_cmd_configure(wl, ACX_ENABLE_RX_DATA_FILTER, acx,
				   sizeof(*acx));
	if (ret < 0) {
		wl1271_warning("acx default rx filter enable failed: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}

/* Configure or disable a specific RX filter pattern */
int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
			     struct wl12xx_rx_filter *filter)
{
	struct acx_rx_filter_cfg *acx;
	int fields_size = 0;
	int acx_size;
	int ret;

	WARN_ON(enable && !filter);
	WARN_ON(index >= WL1271_MAX_RX_FILTERS);

	wl1271_debug(DEBUG_ACX, "acx set rx filter idx: %d enable: %d"
		     "filter: 0x%x", index, enable, (unsigned int)filter);

	if (enable) {
		fields_size = wl1271_rx_filter_get_fields_size(filter);

		wl1271_debug(DEBUG_ACX, "act: %d num_fields: %d field_size: %d",
		      filter->action, filter->num_fields, fields_size);
	}

	acx_size = ALIGN(sizeof(*acx) + fields_size, 4);
	acx = kzalloc(acx_size, GFP_KERNEL);

	if (!acx)
		return -ENOMEM;

	acx->enable = enable;
	acx->index = index;

	if (enable) {
		acx->num_fields = filter->num_fields;
		acx->action = filter->action;
		wl1271_rx_filter_flatten_fields(filter, acx->fields);
	}

	wl1271_dump(DEBUG_ACX, "RX_FILTER: ", acx, acx_size);

	ret = wl1271_cmd_configure(wl, ACX_SET_RX_DATA_FILTER, acx, acx_size);
	if (ret < 0) {
		wl1271_warning("setting rx filter failed: %d", ret);
		goto out;
	}

out:
	kfree(acx);
	return ret;
}
+30 −0
Original line number Diff line number Diff line
@@ -1147,6 +1147,32 @@ struct wl12xx_acx_config_hangover {
	u8 padding[2];
} __packed;


struct acx_default_rx_filter {
	struct acx_header header;
	u8 enable;

	/* action of type FILTER_XXX */
	u8 default_action;

	u8 pad[2];
} __packed;


struct acx_rx_filter_cfg {
	struct acx_header header;

	u8 enable;

	/* 0 - WL1271_MAX_RX_FILTERS-1 */
	u8 index;

	u8 action;

	u8 num_fields;
	u8 fields[0];
} __packed;

enum {
	ACX_WAKE_UP_CONDITIONS           = 0x0000,
	ACX_MEM_CFG                      = 0x0001,
@@ -1304,5 +1330,9 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
int wl1271_acx_fm_coex(struct wl1271 *wl);
int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
int wl12xx_acx_config_hangover(struct wl1271 *wl);
int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable,
					enum rx_filter_action action);
int wl1271_acx_set_rx_filter(struct wl1271 *wl, u8 index, bool enable,
			     struct wl12xx_rx_filter *filter);

#endif /* __WL1271_ACX_H__ */
+1 −0
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ struct wl1271_link {
	u8 ba_bitmap;
};

#define WL1271_MAX_RX_FILTERS 5
#define WL1271_RX_FILTER_MAX_FIELDS 8
enum rx_filter_action {
	FILTER_DROP = 0,