Skip to content

Commit

Permalink
wlcore: add RX filters util functions
Browse files Browse the repository at this point in the history
This is prep work for the support of wowlan patterns
using the FW data rx filters mechanism.
Added an rx filter struct and some util functions
required to manipulate it.

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 fd492ed commit a6eab0c
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
78 changes: 78 additions & 0 deletions drivers/net/wireless/ti/wlcore/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,84 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)


#ifdef CONFIG_PM
struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void)
{
return kzalloc(sizeof(struct wl12xx_rx_filter), GFP_KERNEL);
}

void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter)
{
int i;

if (filter == NULL)
return;

for (i = 0; i < filter->num_fields; i++)
kfree(filter->fields[i].pattern);

kfree(filter);
}

int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter,
u16 offset, u8 flags,
u8 *pattern, u8 len)
{
struct wl12xx_rx_filter_field *field;

if (filter->num_fields == WL1271_RX_FILTER_MAX_FIELDS) {
wl1271_warning("Max fields per RX filter. can't alloc another");
return -EINVAL;
}

field = &filter->fields[filter->num_fields];

field->pattern = kzalloc(len, GFP_KERNEL);
if (!field->pattern) {
wl1271_warning("Failed to allocate RX filter pattern");
return -ENOMEM;
}

filter->num_fields++;

field->offset = cpu_to_le16(offset);
field->flags = flags;
field->len = len;
memcpy(field->pattern, pattern, len);

return 0;
}

int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter)
{
int i, fields_size = 0;

for (i = 0; i < filter->num_fields; i++)
fields_size += filter->fields[i].len +
sizeof(struct wl12xx_rx_filter_field) -
sizeof(u8 *);

return fields_size;
}

void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
u8 *buf)
{
int i;
struct wl12xx_rx_filter_field *field;

for (i = 0; i < filter->num_fields; i++) {
field = (struct wl12xx_rx_filter_field *)buf;

field->offset = filter->fields[i].offset;
field->flags = filter->fields[i].flags;
field->len = filter->fields[i].len;

memcpy(&field->pattern, filter->fields[i].pattern, field->len);
buf += sizeof(struct wl12xx_rx_filter_field) -
sizeof(u8 *) + field->len;
}
}

static int wl1271_configure_suspend_sta(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{
Expand Down
28 changes: 28 additions & 0 deletions drivers/net/wireless/ti/wlcore/wl12xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,26 @@ struct wl1271_link {
u8 ba_bitmap;
};

#define WL1271_RX_FILTER_MAX_FIELDS 8
enum rx_filter_action {
FILTER_DROP = 0,
FILTER_SIGNAL = 1,
FILTER_FW_HANDLE = 2
};

struct wl12xx_rx_filter_field {
__le16 offset;
u8 len;
u8 flags;
u8 *pattern;
} __packed;

struct wl12xx_rx_filter {
u8 action;
int num_fields;
struct wl12xx_rx_filter_field fields[WL1271_RX_FILTER_MAX_FIELDS];
};

struct wl1271_station {
u8 hlid;
};
Expand Down Expand Up @@ -439,6 +459,14 @@ int wl1271_plt_stop(struct wl1271 *wl);
int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif);
void wl12xx_queue_recovery_work(struct wl1271 *wl);
size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter,
u16 offset, u8 flags,
u8 *pattern, u8 len);
void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter);
struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void);
int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter);
void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
u8 *buf);

#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */

Expand Down

0 comments on commit a6eab0c

Please sign in to comment.