/* 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: %p", index, enable, 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; }
int wl1271_acx_set_rx_data_filter(struct wl1271 *wl, u8 index, bool enable, struct wl12xx_rx_data_filter *filter) { struct acx_rx_data_filter_cfg *acx; int fields_size = 0; int acx_size; int ret; if (enable && !filter) { wl1271_warning("acx_set_rx_data_filter: enable but no filter"); return -EINVAL; } if (index >= WL1271_MAX_RX_FILTERS) { wl1271_warning("acx_set_rx_data_filter: invalid filter idx(%d)", index); return -EINVAL; } if (filter) { if (filter->action < FILTER_DROP || filter->action > FILTER_FW_HANDLE) { wl1271_warning("invalid filter action (%d)", filter->action); return -EINVAL; } } wl1271_debug(DEBUG_ACX, "acx set rx data filter idx: %d, enable: %d", index, enable); 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 = roundup(sizeof(*acx) + fields_size, 4); acx = kzalloc(acx_size, GFP_KERNEL); if (!acx) return -ENOMEM; acx->enable = enable ? 1 : 0; 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 data filter failed: %d", ret); goto out; } out: kfree(acx); return ret; }