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: Eyal Shapira <eyal@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
Родитель
a6eab0c8c0
Коммит
c21eebb503
|
@ -1714,3 +1714,82 @@ out:
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1147,6 +1147,32 @@ struct wl12xx_acx_config_hangover {
|
||||||
u8 padding[2];
|
u8 padding[2];
|
||||||
} __packed;
|
} __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 {
|
enum {
|
||||||
ACX_WAKE_UP_CONDITIONS = 0x0000,
|
ACX_WAKE_UP_CONDITIONS = 0x0000,
|
||||||
ACX_MEM_CFG = 0x0001,
|
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 wl1271_acx_fm_coex(struct wl1271 *wl);
|
||||||
int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
|
int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl);
|
||||||
int wl12xx_acx_config_hangover(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__ */
|
#endif /* __WL1271_ACX_H__ */
|
||||||
|
|
|
@ -279,6 +279,7 @@ struct wl1271_link {
|
||||||
u8 ba_bitmap;
|
u8 ba_bitmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define WL1271_MAX_RX_FILTERS 5
|
||||||
#define WL1271_RX_FILTER_MAX_FIELDS 8
|
#define WL1271_RX_FILTER_MAX_FIELDS 8
|
||||||
enum rx_filter_action {
|
enum rx_filter_action {
|
||||||
FILTER_DROP = 0,
|
FILTER_DROP = 0,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче