From: Eliad Peller <eliad@wizery.com>
To: Luciano Coelho <coelho@ti.com>
Cc: <linux-wireless@vger.kernel.org>
Subject: [PATCH v2 5/7] wl12xx: add RX data filter ACX commands
Date: Tue, 31 Jan 2012 16:44:06 +0200 [thread overview]
Message-ID: <1328021048-8944-6-git-send-email-eliad@wizery.com> (raw)
In-Reply-To: <1328021048-8944-1-git-send-email-eliad@wizery.com>
From: Eyal Shapira <eyal@wizery.com>
(based on Pontus' patch)
Added commands for setting a specific filter
and controlling the behaviour RX data filters
implemented by the FW.
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: Ido Reis <idor@ti.com>
Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/acx.c | 105 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/acx.h | 31 ++++++++++-
drivers/net/wireless/wl12xx/wl12xx.h | 33 +++++++++++
3 files changed, 168 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index bc96db0..668d337 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1740,3 +1740,108 @@ out:
return ret;
}
+
+int wl1271_acx_toggle_rx_data_filter(struct wl1271 *wl, bool enable,
+ u8 default_action)
+{
+ struct acx_rx_data_filter_state *acx;
+ int ret;
+
+ wl1271_debug(DEBUG_ACX, "acx toggle rx data filter en: %d act: %d",
+ enable, default_action);
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ acx->enable = enable ? 1 : 0;
+ acx->default_action = default_action;
+
+ ret = wl1271_cmd_configure(wl, ACX_ENABLE_RX_DATA_FILTER, acx,
+ sizeof(*acx));
+ if (ret < 0) {
+ wl1271_warning("toggling rx data 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_DATA_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;
+ }
+
+ if (filter->num_fields != 1 &&
+ filter->num_fields != 2) {
+ wl1271_warning("invalid filter num_fields (%d)",
+ filter->num_fields);
+ return -EINVAL;
+ }
+ }
+
+ wl1271_debug(DEBUG_ACX, "acx set rx data filter idx: %d, enable: %d",
+ index, enable);
+
+ if (enable) {
+ fields_size = filter->fields_size;
+
+ 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;
+
+ memcpy(acx->fields, filter->fields, filter->fields_size);
+ }
+
+ 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;
+}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index a28fc04..9d0d30b 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1152,6 +1152,32 @@ struct wl12xx_acx_config_hangover {
u8 padding[2];
} __packed;
+
+struct acx_rx_data_filter_state {
+ struct acx_header header;
+ u8 enable;
+
+ /* action of type FILTER_XXX */
+ u8 default_action;
+ u8 pad[2];
+} __packed;
+
+
+struct acx_rx_data_filter_cfg {
+ struct acx_header header;
+
+ u8 enable;
+
+ /* range 0 - MAX_DATA_FILTERS */
+ u8 index;
+
+ u8 action;
+
+ u8 num_fields;
+
+ struct wl12xx_rx_data_filter_field fields[0];
+} __packed;
+
enum {
ACX_WAKE_UP_CONDITIONS = 0x0000,
ACX_MEM_CFG = 0x0001,
@@ -1310,5 +1336,8 @@ 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_toggle_rx_data_filter(struct wl1271 *wl, bool enable,
+ u8 default_action);
+int wl1271_acx_set_rx_data_filter(struct wl1271 *wl, u8 index, bool enable,
+ struct wl12xx_rx_data_filter *filter);
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 1463341..c18ad0a 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -277,6 +277,39 @@ struct wl1271_link {
u8 ba_bitmap;
};
+#define WL1271_MAX_RX_DATA_FILTERS 4
+#define WL1271_RX_DATA_FILTER_MAX_FIELD_PATTERNS 8
+
+/* FW MAX FILTER SIZE is 98 bytes. The MAX_PATTERN_SIZE is imposed
+ * after taking into account the mask bytes and other structs members
+ */
+#define WL1271_RX_DATA_FILTER_MAX_PATTERN_SIZE 43
+#define WL1271_RX_DATA_FILTER_ETH_HEADER_SIZE 14
+
+#define WL1271_RX_DATA_FILTER_FLAG_MASK BIT(0)
+#define WL1271_RX_DATA_FILTER_FLAG_IP_HEADER 0
+#define WL1271_RX_DATA_FILTER_FLAG_ETHERNET_HEADER BIT(1)
+
+enum rx_data_filter_action {
+ FILTER_DROP = 0,
+ FILTER_SIGNAL = 1,
+ FILTER_FW_HANDLE = 2
+};
+
+struct wl12xx_rx_data_filter_field {
+ __le16 offset;
+ u8 len;
+ u8 flags;
+ u8 pattern[0];
+} __packed;
+
+struct wl12xx_rx_data_filter {
+ u8 action;
+ int num_fields;
+ int fields_size;
+ struct wl12xx_rx_data_filter_field fields[0];
+} __packed;
+
struct wl1271 {
struct ieee80211_hw *hw;
bool mac80211_registered;
--
1.7.6.401.g6a319
next prev parent reply other threads:[~2012-01-31 14:40 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-31 14:44 [PATCH v2 0/7] wl12xx: add some psm/suspend features Eliad Peller
2012-01-31 14:44 ` [PATCH v2 1/7] wl12xx: Set different wake up conditions in case of suspend Eliad Peller
2012-01-31 14:44 ` [PATCH v2 2/7] wl12xx: add suspend_listen_interval debugfs file Eliad Peller
2012-01-31 14:44 ` [PATCH v2 3/7] wl12xx: add forced_ps mode Eliad Peller
2012-02-02 7:43 ` Luciano Coelho
2012-01-31 14:44 ` [PATCH v2 4/7] wl12xx: add forced_ps debugfs file Eliad Peller
2012-02-02 7:44 ` Luciano Coelho
2012-02-02 8:09 ` Luciano Coelho
2012-01-31 14:44 ` Eliad Peller [this message]
2012-02-02 8:23 ` [PATCH v2 5/7] wl12xx: add RX data filter ACX commands Luciano Coelho
2012-02-06 14:07 ` Kalle Valo
2012-02-06 14:32 ` Luciano Coelho
2012-02-07 16:05 ` Kalle Valo
2012-02-07 16:11 ` Luciano Coelho
2012-01-31 14:44 ` [PATCH v2 6/7] wl12xx: add RX data filters management functions Eliad Peller
2012-02-02 8:39 ` Luciano Coelho
2012-01-31 14:44 ` [PATCH v2 7/7] wl12xx: support wowlan wakeup patterns Eliad Peller
2012-02-02 9:31 ` [PATCH v2 0/7] wl12xx: add some psm/suspend features Luciano Coelho
2012-02-02 9:45 ` Eliad Peller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1328021048-8944-6-git-send-email-eliad@wizery.com \
--to=eliad@wizery.com \
--cc=coelho@ti.com \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).