wl12xx: add RX filters ACX commands
authorEyal Shapira <eyal@wizery.com>
Wed, 14 Mar 2012 04:32:08 +0000 (06:32 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 15 May 2012 21:53:23 +0000 (17:53 -0400)
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>
drivers/net/wireless/ti/wlcore/acx.c
drivers/net/wireless/ti/wlcore/acx.h
drivers/net/wireless/ti/wlcore/wl12xx.h

index 5912541..0fd78a0 100644 (file)
@@ -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;
+}
index b2f8883..8106b2e 100644 (file)
@@ -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__ */
index 8ca1fe0..12558cf 100644 (file)
@@ -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,