Skip to content

Commit

Permalink
wl12xx: add RX filters ACX commands
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Eyal Shapira authored and John W. Linville committed May 15, 2012
1 parent a6eab0c commit c21eebb
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
79 changes: 79 additions & 0 deletions drivers/net/wireless/ti/wlcore/acx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1714,3 +1714,82 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl)
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 changes: 30 additions & 0 deletions drivers/net/wireless/ti/wlcore/acx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 change: 1 addition & 0 deletions drivers/net/wireless/ti/wlcore/wl12xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit c21eebb

Please sign in to comment.