* [PATCH 0/7] wl12xx: add some psm/suspend features
@ 2012-01-30 14:58 Eliad Peller
2012-01-30 14:58 ` [PATCH 1/7] wl12xx: Set different wake up conditions in case of suspend Eliad Peller
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
Add some psm / suspend features:
* Add the ability to force psm (by default, the fw uses dynamic ps)
* Use differnet wake up conditions on suspend
* Add pattern support to wowlan triggers
Eyal Shapira (4):
wl12xx: Set different wake up conditions in case of suspend
wl12xx: add suspend_listen_interval debugfs file
wl12xx: add forced_ps mode
wl12xx: add forced_ps debugfs file
Pontus Fuchs (3):
wl12xx: Add rx data filter commands
wl12xx: Add functions for managing rx data filters
wl12xx: Add support for WoWLAN packet pattern trigger
drivers/net/wireless/wl12xx/acx.c | 100 ++++++++++++++++++-
drivers/net/wireless/wl12xx/acx.h | 45 ++++++++-
drivers/net/wireless/wl12xx/conf.h | 19 ++++
drivers/net/wireless/wl12xx/debugfs.c | 131 ++++++++++++++++++++++++-
drivers/net/wireless/wl12xx/main.c | 178 ++++++++++++++++++++++++++++++---
drivers/net/wireless/wl12xx/ps.c | 12 ++-
drivers/net/wireless/wl12xx/rx.c | 105 +++++++++++++++++++
drivers/net/wireless/wl12xx/rx.h | 14 +++-
drivers/net/wireless/wl12xx/wl12xx.h | 38 +++++++-
9 files changed, 616 insertions(+), 26 deletions(-)
--
1.7.6.401.g6a319
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/7] wl12xx: Set different wake up conditions in case of suspend
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
@ 2012-01-30 14:58 ` Eliad Peller
2012-01-30 14:58 ` [PATCH 2/7] wl12xx: add suspend_listen_interval debugfs file Eliad Peller
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Eyal Shapira <eyal@wizery.com>
Added ability to set different wake up conditions for suspend/resume.
Set default values to wake up every 3 DTIMs while suspended
and every 1 DTIM while resumed
Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/acx.c | 10 ++++---
drivers/net/wireless/wl12xx/acx.h | 3 +-
drivers/net/wireless/wl12xx/conf.h | 13 +++++++++
drivers/net/wireless/wl12xx/main.c | 51 +++++++++++++++++++++++++++++++++--
drivers/net/wireless/wl12xx/ps.c | 4 ++-
5 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index af2c312..bc96db0 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -34,12 +34,14 @@
#include "reg.h"
#include "ps.h"
-int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
+int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ u8 wake_up_event, u8 listen_interval)
{
struct acx_wake_up_condition *wake_up;
int ret;
- wl1271_debug(DEBUG_ACX, "acx wake up conditions");
+ wl1271_debug(DEBUG_ACX, "acx wake up conditions (wake_up_event %d listen_interval %d)",
+ wake_up_event, listen_interval);
wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
if (!wake_up) {
@@ -48,8 +50,8 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif)
}
wake_up->role_id = wlvif->role_id;
- wake_up->wake_up_event = wl->conf.conn.wake_up_event;
- wake_up->listen_interval = wl->conf.conn.listen_interval;
+ wake_up->wake_up_event = wake_up_event;
+ wake_up->listen_interval = listen_interval;
ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
wake_up, sizeof(*wake_up));
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 0749df5..a28fc04 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1226,7 +1226,8 @@ enum {
int wl1271_acx_wake_up_conditions(struct wl1271 *wl,
- struct wl12xx_vif *wlvif);
+ struct wl12xx_vif *wlvif,
+ u8 wake_up_event, u8 listen_interval);
int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif,
int power);
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index 10e5e3d..d97aad6 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -810,6 +810,19 @@ struct conf_conn_settings {
u8 listen_interval;
/*
+ * Firmware wakeup conditions during suspend
+ * Range: CONF_WAKE_UP_EVENT_*
+ */
+ u8 suspend_wake_up_event;
+
+ /*
+ * Listen interval during suspend.
+ * Currently will be in DTIMs (1-10)
+ *
+ */
+ u8 suspend_listen_interval;
+
+ /*
* Enable or disable the beacon filtering.
*
* Range: CONF_BCN_FILT_MODE_*
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 2bb1c24..29a00fc 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -218,6 +218,8 @@ static struct conf_drv_settings default_conf = {
.conn = {
.wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
.listen_interval = 1,
+ .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
+ .suspend_listen_interval = 3,
.bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
.bcn_filt_ie_count = 2,
.bcn_filt_ie = {
@@ -1561,6 +1563,35 @@ static struct notifier_block wl1271_dev_notifier = {
};
#ifdef CONFIG_PM
+static int wl1271_configure_suspend_sta(struct wl1271 *wl,
+ struct wl12xx_vif *wlvif)
+{
+ int ret = 0;
+
+ mutex_lock(&wl->mutex);
+
+ if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
+ goto out_unlock;
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out_unlock;
+
+ ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+ wl->conf.conn.suspend_wake_up_event,
+ wl->conf.conn.suspend_listen_interval);
+
+ if (ret < 0)
+ wl1271_error("suspend: set wake up conditions failed: %d", ret);
+
+
+ wl1271_ps_elp_sleep(wl);
+
+out_unlock:
+ mutex_unlock(&wl->mutex);
+ return ret;
+
+}
static int wl1271_configure_suspend_ap(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
@@ -1588,6 +1619,8 @@ out_unlock:
static int wl1271_configure_suspend(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{
+ if (wlvif->bss_type == BSS_TYPE_STA_BSS)
+ return wl1271_configure_suspend_sta(wl, wlvif);
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
return wl1271_configure_suspend_ap(wl, wlvif);
return 0;
@@ -1596,10 +1629,11 @@ static int wl1271_configure_suspend(struct wl1271 *wl,
static void wl1271_configure_resume(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{
- int ret;
+ int ret = 0;
bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
+ bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
- if (!is_ap)
+ if ((!is_ap) && (!is_sta))
return;
mutex_lock(&wl->mutex);
@@ -1607,7 +1641,18 @@ static void wl1271_configure_resume(struct wl1271 *wl,
if (ret < 0)
goto out;
- wl1271_acx_beacon_filter_opt(wl, wlvif, false);
+ if (is_sta) {
+ ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+ wl->conf.conn.wake_up_event,
+ wl->conf.conn.listen_interval);
+
+ if (ret < 0)
+ wl1271_error("resume: wake up conditions failed: %d",
+ ret);
+
+ } else if (is_ap) {
+ ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
+ }
wl1271_ps_elp_sleep(wl);
out:
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index e209e29..d197922 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -170,7 +170,9 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)",
mode, timeout);
- ret = wl1271_acx_wake_up_conditions(wl, wlvif);
+ ret = wl1271_acx_wake_up_conditions(wl, wlvif,
+ wl->conf.conn.wake_up_event,
+ wl->conf.conn.listen_interval);
if (ret < 0) {
wl1271_error("couldn't set wake up conditions");
return ret;
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/7] wl12xx: add suspend_listen_interval debugfs file
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
2012-01-30 14:58 ` [PATCH 1/7] wl12xx: Set different wake up conditions in case of suspend Eliad Peller
@ 2012-01-30 14:58 ` Eliad Peller
2012-01-30 14:58 ` [PATCH 3/7] wl12xx: add forced_ps mode Eliad Peller
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Eyal Shapira <eyal@wizery.com>
Add read/write to suspend_dtim_interval file which
controls the number of DTIM periods between wakeups
while the host is suspended.
The value while the host is resumed is controlled
by the file dtim_interval which existed previously.
Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/debugfs.c | 59 +++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 4dcb3f7..15353fa 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -625,6 +625,64 @@ static const struct file_operations dtim_interval_ops = {
.llseek = default_llseek,
};
+
+
+static ssize_t suspend_dtim_interval_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ u8 value;
+
+ if (wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
+ wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
+ value = wl->conf.conn.suspend_listen_interval;
+ else
+ value = 0;
+
+ return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
+}
+
+static ssize_t suspend_dtim_interval_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ unsigned long value;
+ int ret;
+
+ ret = kstrtoul_from_user(user_buf, count, 10, &value);
+ if (ret < 0) {
+ wl1271_warning("illegal value for suspend_dtim_interval");
+ return -EINVAL;
+ }
+
+ if (value < 1 || value > 10) {
+ wl1271_warning("suspend_dtim value is not in valid range");
+ return -ERANGE;
+ }
+
+ mutex_lock(&wl->mutex);
+
+ wl->conf.conn.suspend_listen_interval = value;
+ /* for some reason there are different event types for 1 and >1 */
+ if (value == 1)
+ wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
+ else
+ wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
+
+ mutex_unlock(&wl->mutex);
+ return count;
+}
+
+
+static const struct file_operations suspend_dtim_interval_ops = {
+ .read = suspend_dtim_interval_read,
+ .write = suspend_dtim_interval_write,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
static ssize_t beacon_interval_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -949,6 +1007,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD(driver_state, rootdir);
DEBUGFS_ADD(vifs_state, rootdir);
DEBUGFS_ADD(dtim_interval, rootdir);
+ DEBUGFS_ADD(suspend_dtim_interval, rootdir);
DEBUGFS_ADD(beacon_interval, rootdir);
DEBUGFS_ADD(beacon_filtering, rootdir);
DEBUGFS_ADD(dynamic_ps_timeout, rootdir);
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7] wl12xx: add forced_ps mode
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
2012-01-30 14:58 ` [PATCH 1/7] wl12xx: Set different wake up conditions in case of suspend Eliad Peller
2012-01-30 14:58 ` [PATCH 2/7] wl12xx: add suspend_listen_interval debugfs file Eliad Peller
@ 2012-01-30 14:58 ` Eliad Peller
2012-01-30 14:58 ` [PATCH 4/7] wl12xx: add forced_ps debugfs file Eliad Peller
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Eyal Shapira <eyal@wizery.com>
For certain WiFi certification tests forcing PS
is necessary. Since DPS is now enabled in the FW
and this can't be achieved by using netlatency
this required a new config option.
Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/conf.h | 6 ++++++
drivers/net/wireless/wl12xx/debugfs.c | 2 +-
drivers/net/wireless/wl12xx/main.c | 25 +++++++++++++++++++------
drivers/net/wireless/wl12xx/ps.c | 8 ++++----
drivers/net/wireless/wl12xx/wl12xx.h | 2 +-
5 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index d97aad6..f29fbfd 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -934,6 +934,12 @@ struct conf_conn_settings {
u16 dynamic_ps_timeout;
/*
+ * Specifies whether dynamic PS should be disabled and PSM forced.
+ * This is required for certain WiFi certification tests.
+ */
+ u8 forced_ps;
+
+ /*
*
* Specifies the interval of the connection keep-alive null-func
* frame in ms.
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 15353fa..02da445 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -358,7 +358,7 @@ static ssize_t dynamic_ps_timeout_write(struct file *file,
*/
wl12xx_for_each_wlvif_sta(wl, wlvif) {
- if (test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags))
+ if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE);
}
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 29a00fc..f2960df 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -244,6 +244,7 @@ static struct conf_drv_settings default_conf = {
.psm_exit_retries = 16,
.psm_entry_nullfunc_retries = 3,
.dynamic_ps_timeout = 100,
+ .forced_ps = false,
.keep_alive_interval = 55000,
.max_listen_interval = 20,
},
@@ -2481,17 +2482,29 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if ((conf->flags & IEEE80211_CONF_PS) &&
test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
- !test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) {
+ !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
- wl1271_debug(DEBUG_PSM, "auto ps enabled");
+ int ps_mode;
+ char *ps_mode_str;
+
+ if (wl->conf.conn.forced_ps) {
+ ps_mode = STATION_POWER_SAVE_MODE;
+ ps_mode_str = "forced";
+ } else {
+ ps_mode = STATION_AUTO_PS_MODE;
+ ps_mode_str = "auto";
+ }
+
+ wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);
+
+ ret = wl1271_ps_set_mode(wl, wlvif, ps_mode);
- ret = wl1271_ps_set_mode(wl, wlvif,
- STATION_AUTO_PS_MODE);
if (ret < 0)
- wl1271_warning("enter auto ps failed %d", ret);
+ wl1271_warning("enter %s ps failed %d",
+ ps_mode_str, ret);
} else if (!(conf->flags & IEEE80211_CONF_PS) &&
- test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) {
+ test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
wl1271_debug(DEBUG_PSM, "auto ps disabled");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index d197922..fa993c2 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -56,7 +56,7 @@ void wl1271_elp_work(struct work_struct *work)
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
goto out;
- if (!test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags) &&
+ if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
goto out;
}
@@ -84,7 +84,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
return;
- if (!test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags) &&
+ if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
return;
}
@@ -182,7 +182,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if (ret < 0)
return ret;
- set_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags);
+ set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
/* enable beacon early termination. Not relevant for 5GHz */
if (wlvif->band == IEEE80211_BAND_2GHZ) {
@@ -205,7 +205,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
if (ret < 0)
return ret;
- clear_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags);
+ clear_bit(WLVIF_FLAG_IN_PS, &wlvif->flags);
break;
case STATION_POWER_SAVE_MODE:
default:
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 9cc7051..1463341 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -254,7 +254,7 @@ enum wl12xx_vif_flags {
WLVIF_FLAG_STA_ASSOCIATED,
WLVIF_FLAG_IBSS_JOINED,
WLVIF_FLAG_AP_STARTED,
- WLVIF_FLAG_IN_AUTO_PS,
+ WLVIF_FLAG_IN_PS,
WLVIF_FLAG_STA_STATE_SENT,
WLVIF_FLAG_RX_STREAMING_STARTED,
WLVIF_FLAG_PSPOLL_FAILURE,
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7] wl12xx: add forced_ps debugfs file
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
` (2 preceding siblings ...)
2012-01-30 14:58 ` [PATCH 3/7] wl12xx: add forced_ps mode Eliad Peller
@ 2012-01-30 14:58 ` Eliad Peller
2012-01-30 14:58 ` [PATCH 5/7] wl12xx: Add rx data filter commands Eliad Peller
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Eyal Shapira <eyal@wizery.com>
Added control over forced_ps option through debugfs.
This can be either 1 or 0.
Signed-off-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/debugfs.c | 70 +++++++++++++++++++++++++++++++++
1 files changed, 70 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 02da445..1c26238 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -376,6 +376,75 @@ static const struct file_operations dynamic_ps_timeout_ops = {
.llseek = default_llseek,
};
+static ssize_t forced_ps_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+
+ return wl1271_format_buffer(user_buf, count,
+ ppos, "%d\n",
+ wl->conf.conn.forced_ps);
+}
+
+static ssize_t forced_ps_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct wl1271 *wl = file->private_data;
+ struct wl12xx_vif *wlvif;
+ unsigned long value;
+ int ret, ps_mode;
+
+ ret = kstrtoul_from_user(user_buf, count, 10, &value);
+ if (ret < 0) {
+ wl1271_warning("illegal value in forced_ps");
+ return -EINVAL;
+ }
+
+ if (value != 1 && value != 0) {
+ wl1271_warning("forced_ps should be either 0 or 1");
+ return -ERANGE;
+ }
+
+ mutex_lock(&wl->mutex);
+
+ if (wl->conf.conn.forced_ps == value)
+ goto out;
+
+ wl->conf.conn.forced_ps = value;
+
+ if (wl->state == WL1271_STATE_OFF)
+ goto out;
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ /* In case we're already in PSM, trigger it again to switch mode
+ * immediately without waiting for re-association
+ */
+
+ ps_mode = value ? STATION_POWER_SAVE_MODE : STATION_AUTO_PS_MODE;
+
+ wl12xx_for_each_wlvif_sta(wl, wlvif) {
+ if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags))
+ wl1271_ps_set_mode(wl, wlvif, ps_mode);
+ }
+
+ wl1271_ps_elp_sleep(wl);
+
+out:
+ mutex_unlock(&wl->mutex);
+ return count;
+}
+
+static const struct file_operations forced_ps_ops = {
+ .read = forced_ps_read,
+ .write = forced_ps_write,
+ .open = wl1271_open_file_generic,
+ .llseek = default_llseek,
+};
+
static ssize_t driver_state_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1011,6 +1080,7 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
DEBUGFS_ADD(beacon_interval, rootdir);
DEBUGFS_ADD(beacon_filtering, rootdir);
DEBUGFS_ADD(dynamic_ps_timeout, rootdir);
+ DEBUGFS_ADD(forced_ps, rootdir);
streaming = debugfs_create_dir("rx_streaming", rootdir);
if (!streaming || IS_ERR(streaming))
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7] wl12xx: Add rx data filter commands
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
` (3 preceding siblings ...)
2012-01-30 14:58 ` [PATCH 4/7] wl12xx: add forced_ps debugfs file Eliad Peller
@ 2012-01-30 14:58 ` Eliad Peller
2012-01-30 14:58 ` [PATCH 6/7] wl12xx: Add functions for managing rx data filters Eliad Peller
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Pontus Fuchs <pontus.fuchs@gmail.com>
Add acx command, structs and definitions needed for the rx data
filter commands.
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: Ido Reis <idor@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/acx.c | 90 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/acx.h | 42 ++++++++++++++++
drivers/net/wireless/wl12xx/wl12xx.h | 15 ++++++
3 files changed, 147 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index bc96db0..05bd79c 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1740,3 +1740,93 @@ 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, bool add, u8 index,
+ u8 action, u8 *pattern, u8 length, u16 offset)
+{
+ struct acx_rx_data_filter_cfg *acx;
+ int ret;
+
+ wl1271_debug(DEBUG_ACX, "acx set rx data filter add: %d idx: %d "
+ "act: %d pat_len: %d offset: %d", add, index, action,
+ length, offset);
+
+ acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+ if (!acx) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (index >= WL1271_MAX_RX_DATA_FILTERS ||
+ length > WL1271_RX_DATA_FILTER_MAX_PATTERN_SIZE ||
+ (add && !pattern)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ acx->add_filter = add ? 1 : 0;
+ acx->index = index;
+ acx->num_fields = 1;
+ acx->action = action;
+
+ if (add) {
+ /* pattern description */
+ acx->length = length;
+ memcpy(acx->pattern, pattern, length);
+
+ if (offset + length <= WL1271_RX_DATA_FILTER_ETH_HEADER_SIZE) {
+ acx->flag = WL1271_RX_DATA_FILTER_FLAG_ETHERNET_HEADER;
+ acx->offset = cpu_to_le16(offset);
+ } else if (offset >= WL1271_RX_DATA_FILTER_ETH_HEADER_SIZE) {
+ acx->flag = WL1271_RX_DATA_FILTER_FLAG_IP_HEADER;
+ acx->offset = cpu_to_le16(offset -
+ WL1271_RX_DATA_FILTER_ETH_HEADER_SIZE);
+ } else {
+ wl1271_error("header boundry crossing filters not "
+ "supported currently");
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ ret = wl1271_cmd_configure(wl, ACX_SET_RX_DATA_FILTER, acx,
+ sizeof(*acx));
+ 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..d68cfd2 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1152,6 +1152,43 @@ 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 add_filter;
+
+ /* range 0 - MAX_DATA_FILTERS */
+ u8 index;
+
+ /* action of type FILTER_XXX */
+ u8 action;
+
+ /* number of fields in this filter */
+ u8 num_fields;
+
+ /*
+ * currently we only support a single filtering field in the driver, so
+ * spell it out directly here
+ */
+
+ /* The offset is taken from the start of the first MAC addr */
+ __le16 offset;
+ u8 length;
+ u8 flag;
+ u8 pattern[WL1271_RX_DATA_FILTER_MAX_PATTERN_SIZE];
+} __packed;
+
enum {
ACX_WAKE_UP_CONDITIONS = 0x0000,
ACX_MEM_CFG = 0x0001,
@@ -1310,5 +1347,10 @@ 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, bool add, u8 index,
+ u8 action, u8 *pattern, u8 length,
+ u16 offset);
#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 1463341..d29de3f 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -277,6 +277,21 @@ struct wl1271_link {
u8 ba_bitmap;
};
+#define WL1271_MAX_RX_DATA_FILTERS 4
+#define WL1271_MAX_RX_DATA_FILTER_SIZE 98
+#define WL1271_RX_DATA_FILTER_MAX_FIELD_PATTERNS 8
+#define WL1271_RX_DATA_FILTER_MAX_PATTERN_SIZE 64
+#define WL1271_RX_DATA_FILTER_ETH_HEADER_SIZE 14
+
+#define WL1271_RX_DATA_FILTER_FLAG_IP_HEADER 0
+#define WL1271_RX_DATA_FILTER_FLAG_ETHERNET_HEADER 2
+
+enum rx_data_filter_action {
+ FILTER_DROP = 0,
+ FILTER_SIGNAL = 1,
+ FILTER_FW_HANDLE = 2
+};
+
struct wl1271 {
struct ieee80211_hw *hw;
bool mac80211_registered;
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7] wl12xx: Add functions for managing rx data filters
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
` (4 preceding siblings ...)
2012-01-30 14:58 ` [PATCH 5/7] wl12xx: Add rx data filter commands Eliad Peller
@ 2012-01-30 14:58 ` Eliad Peller
2012-01-30 14:58 ` [PATCH 7/7] wl12xx: Add support for WoWLAN packet pattern trigger Eliad Peller
2012-01-31 7:43 ` [PATCH 0/7] wl12xx: add some psm/suspend features Luciano Coelho
7 siblings, 0 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Pontus Fuchs <pontus.fuchs@gmail.com>
These functions will make sure filters are set according to what the
firmware expects. It also stores the filter state in the driver.
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: Ido Reis <idor@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/rx.c | 105 ++++++++++++++++++++++++++++++++++
drivers/net/wireless/wl12xx/rx.h | 14 ++++-
drivers/net/wireless/wl12xx/wl12xx.h | 21 +++++++
3 files changed, 139 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 4fbd2a7..3468db3 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -282,3 +282,108 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
wl12xx_rearm_rx_streaming(wl, active_hlids);
}
+
+/*
+ * Global on / off for RX packet filtering in firmware
+ */
+int wl1271_rx_data_filtering_enable(struct wl1271 *wl, bool enable,
+ enum rx_data_filter_action policy)
+{
+ int ret;
+
+ if (policy < FILTER_DROP || policy > FILTER_FW_HANDLE) {
+ wl1271_warning("filter policy value is not in valid range");
+ return -ERANGE;
+ }
+
+ if (enable < 0 || enable > 1) {
+ wl1271_warning("filter enable value is not in valid range");
+ return -ERANGE;
+ }
+
+ ret = wl1271_acx_toggle_rx_data_filter(wl, enable, policy);
+
+ if (ret)
+ return ret;
+
+ wl->rx_data_filter_enabled = enable;
+ wl->rx_data_filter_policy = policy;
+ return 0;
+}
+
+int wl1271_rx_data_filter_enable(struct wl1271 *wl,
+ struct wl12xx_rx_data_filter *f, int nr,
+ bool enable)
+{
+ int ret;
+
+ if (f->enabled == enable)
+ return 0;
+
+ ret = wl1271_acx_set_rx_data_filter(wl, enable, nr, f->action,
+ f->pattern, f->len, f->offset);
+ if (ret) {
+ wl1271_error("Failed to enable/disable rx data filter");
+ return ret;
+ }
+
+ f->enabled = enable;
+ return 0;
+}
+
+int wl1271_rx_data_filter_set_action(struct wl12xx_rx_data_filter *f,
+ enum rx_data_filter_action action)
+{
+ if (f->enabled)
+ return -EBUSY;
+
+ if (action < FILTER_DROP || action > FILTER_FW_HANDLE) {
+ wl1271_warning("filter action is not in valid range");
+ return -ERANGE;
+ }
+
+ f->action = action;
+ return 0;
+}
+
+int wl1271_rx_data_filter_set_offset(struct wl12xx_rx_data_filter *f,
+ u16 offset)
+{
+ if (f->enabled)
+ return -EBUSY;
+
+ if (offset > USHRT_MAX-1) {
+ wl1271_warning("illegal value for filter offset");
+ return -ERANGE;
+ }
+
+ f->offset = offset;
+ return 0;
+}
+
+int wl1271_rx_data_filter_set_pattern(struct wl12xx_rx_data_filter *f, u8 *buf,
+ u8 len)
+{
+ if (f->enabled)
+ return -EBUSY;
+ if (len > WL1271_RX_DATA_FILTER_MAX_PATTERN_SIZE)
+ return -E2BIG;
+
+ memcpy(f->pattern, buf, len);
+ f->len = len;
+ return 0;
+}
+
+/* Unset any active filters */
+void wl1271_rx_data_filters_clear_all(struct wl1271 *wl)
+{
+ int i;
+ struct wl12xx_rx_data_filter *f;
+
+ for (i = 0; i < WL1271_MAX_RX_DATA_FILTERS; i++) {
+ f = &wl->rx_data_filters[i];
+ if (!f->enabled)
+ continue;
+ wl1271_rx_data_filter_enable(wl, f, i, 0);
+ }
+}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
index 86ba6b1..019d6ce 100644
--- a/drivers/net/wireless/wl12xx/rx.h
+++ b/drivers/net/wireless/wl12xx/rx.h
@@ -128,5 +128,17 @@ struct wl1271_rx_descriptor {
void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status);
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
-
+void wl1271_set_default_filters(struct wl1271 *wl);
+int wl1271_rx_data_filtering_enable(struct wl1271 *wl, bool enable,
+ enum rx_data_filter_action policy);
+int wl1271_rx_data_filter_enable(struct wl1271 *wl,
+ struct wl12xx_rx_data_filter *f, int nr,
+ bool enable);
+int wl1271_rx_data_filter_set_action(struct wl12xx_rx_data_filter *f,
+ enum rx_data_filter_action action);
+int wl1271_rx_data_filter_set_offset(struct wl12xx_rx_data_filter *f,
+ u16 offset);
+int wl1271_rx_data_filter_set_pattern(struct wl12xx_rx_data_filter *f, u8 *buf,
+ u8 len);
+void wl1271_rx_data_filters_clear_all(struct wl1271 *wl);
#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index d29de3f..66bda55 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -292,6 +292,14 @@ enum rx_data_filter_action {
FILTER_FW_HANDLE = 2
};
+struct wl12xx_rx_data_filter {
+ bool enabled;
+ enum rx_data_filter_action action;
+ u8 len;
+ u16 offset;
+ u8 pattern[WL1271_MAX_RX_DATA_FILTER_SIZE];
+};
+
struct wl1271 {
struct ieee80211_hw *hw;
bool mac80211_registered;
@@ -491,6 +499,19 @@ struct wl1271 {
/* last wlvif we transmitted from */
struct wl12xx_vif *last_wlvif;
+
+ /* AP-mode - work to add stations back on AP reconfig */
+ struct work_struct ap_start_work;
+
+ /* Global on/off switch for rx all rx filters */
+ bool rx_data_filter_enabled;
+
+ /* Default action for packets not matching any rule */
+ enum rx_data_filter_action rx_data_filter_policy;
+
+ /* RX Data filter rule descriptors */
+ struct wl12xx_rx_data_filter
+ rx_data_filters[WL1271_MAX_RX_DATA_FILTERS];
};
struct wl1271_station {
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7] wl12xx: Add support for WoWLAN packet pattern trigger
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
` (5 preceding siblings ...)
2012-01-30 14:58 ` [PATCH 6/7] wl12xx: Add functions for managing rx data filters Eliad Peller
@ 2012-01-30 14:58 ` Eliad Peller
2012-01-31 7:43 ` [PATCH 0/7] wl12xx: add some psm/suspend features Luciano Coelho
7 siblings, 0 replies; 9+ messages in thread
From: Eliad Peller @ 2012-01-30 14:58 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Pontus Fuchs <pontus.fuchs@gmail.com>
Add support for waking up if a pattern in a incoming packet is found.
Up to 4 patterns are supported.
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: Ido Reis <idor@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/wl12xx/main.c | 106 ++++++++++++++++++++++++++++++++++--
1 files changed, 100 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index f2960df..34bb277 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1564,8 +1564,88 @@ static struct notifier_block wl1271_dev_notifier = {
};
#ifdef CONFIG_PM
+/* Count number of 1->0 or 0->1 transitions in a bit mask */
+static int wl1271_count_bit_flips(void *bitmap, int len)
+{
+ int i, flips = 0;
+ int b, bt;
+
+ if (!len)
+ return 0;
+
+ b = test_bit(0, bitmap);
+
+ for (i = 0; i < len; i++) {
+ bt = test_bit(i, bitmap);
+ if (bt != b)
+ flips++;
+ b = bt;
+ }
+
+ return flips;
+}
+
+static int wl1271_configure_wowlan(struct wl1271 *wl,
+ struct cfg80211_wowlan *wow)
+{
+ int i, ret;
+
+ if (!wow) {
+ wl1271_rx_data_filtering_enable(wl, 0, FILTER_SIGNAL);
+ return 0;
+ }
+
+ WARN_ON(wow->n_patterns > WL1271_MAX_RX_DATA_FILTERS);
+ if (wow->any || !wow->n_patterns)
+ return 0;
+
+ wl1271_rx_data_filters_clear_all(wl);
+
+ /* Translate WoWLAN patterns into filters */
+ for (i = 0; i < wow->n_patterns; i++) {
+ struct cfg80211_wowlan_trig_pkt_pattern *p;
+ struct wl12xx_rx_data_filter *f;
+ int offset, len;
+
+ p = &wow->patterns[i];
+ f = &wl->rx_data_filters[i];
+
+ /* WoWLAN triggers as defined by nl80211 does not match wl12xx's
+ capabilities 1:1 so it's possible to get a pattern that
+ FW cannot handle */
+ if (wl1271_count_bit_flips(p->mask, p->pattern_len) > 1) {
+ wl1271_warning("WoWLAN pattern too advanced\n");
+ goto err;
+ }
+ offset = find_first_bit((const unsigned long *) p->mask,
+ p->pattern_len);
+ len = p->pattern_len - offset;
+
+ ret = wl1271_rx_data_filter_set_action(f, FILTER_SIGNAL);
+ if (ret)
+ goto err;
+ ret = wl1271_rx_data_filter_set_offset(f, offset);
+ if (ret)
+ goto err;
+ ret = wl1271_rx_data_filter_set_pattern(f, &p->pattern[offset],
+ len);
+ if (ret)
+ goto err;
+ ret = wl1271_rx_data_filter_enable(wl, f, i, 1);
+ if (ret)
+ goto err;
+ }
+ ret = wl1271_rx_data_filtering_enable(wl, 1, FILTER_DROP);
+ if (ret)
+ goto err;
+ return 0;
+err:
+ return ret;
+}
+
static int wl1271_configure_suspend_sta(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
+ struct wl12xx_vif *wlvif,
+ struct cfg80211_wowlan *wow)
{
int ret = 0;
@@ -1578,6 +1658,10 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
if (ret < 0)
goto out_unlock;
+ ret = wl1271_configure_wowlan(wl, wow);
+ if (ret < 0)
+ wl1271_error("suspend: Could not configure WoWLAN: %d", ret);
+
ret = wl1271_acx_wake_up_conditions(wl, wlvif,
wl->conf.conn.suspend_wake_up_event,
wl->conf.conn.suspend_listen_interval);
@@ -1618,10 +1702,11 @@ out_unlock:
}
static int wl1271_configure_suspend(struct wl1271 *wl,
- struct wl12xx_vif *wlvif)
+ struct wl12xx_vif *wlvif,
+ struct cfg80211_wowlan *wow)
{
if (wlvif->bss_type == BSS_TYPE_STA_BSS)
- return wl1271_configure_suspend_sta(wl, wlvif);
+ return wl1271_configure_suspend_sta(wl, wlvif, wow);
if (wlvif->bss_type == BSS_TYPE_AP_BSS)
return wl1271_configure_suspend_ap(wl, wlvif);
return 0;
@@ -1643,6 +1728,9 @@ static void wl1271_configure_resume(struct wl1271 *wl,
goto out;
if (is_sta) {
+ /* Remove WoWLAN filtering */
+ wl1271_configure_wowlan(wl, NULL);
+
ret = wl1271_acx_wake_up_conditions(wl, wlvif,
wl->conf.conn.wake_up_event,
wl->conf.conn.listen_interval);
@@ -1668,11 +1756,11 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
int ret;
wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
- WARN_ON(!wow || !wow->any);
+ WARN_ON(!wow);
wl->wow_enabled = true;
wl12xx_for_each_wlvif(wl, wlvif) {
- ret = wl1271_configure_suspend(wl, wlvif);
+ ret = wl1271_configure_suspend(wl, wlvif, wow);
if (ret < 0) {
wl1271_warning("couldn't prepare device to suspend");
return ret;
@@ -5172,8 +5260,14 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
if (!ret) {
wl->irq_wake_enabled = true;
device_init_wakeup(wl->dev, 1);
- if (pdata->pwr_in_suspend)
+ if (pdata->pwr_in_suspend) {
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
+ hw->wiphy->wowlan.n_patterns =
+ WL1271_MAX_RX_DATA_FILTERS;
+ hw->wiphy->wowlan.pattern_min_len = 1;
+ hw->wiphy->wowlan.pattern_max_len =
+ WL1271_RX_DATA_FILTER_MAX_PATTERN_SIZE;
+ }
}
disable_irq(wl->irq);
--
1.7.6.401.g6a319
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/7] wl12xx: add some psm/suspend features
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
` (6 preceding siblings ...)
2012-01-30 14:58 ` [PATCH 7/7] wl12xx: Add support for WoWLAN packet pattern trigger Eliad Peller
@ 2012-01-31 7:43 ` Luciano Coelho
7 siblings, 0 replies; 9+ messages in thread
From: Luciano Coelho @ 2012-01-31 7:43 UTC (permalink / raw)
To: Eliad Peller; +Cc: linux-wireless
On Mon, 2012-01-30 at 16:58 +0200, Eliad Peller wrote:
> Add some psm / suspend features:
> * Add the ability to force psm (by default, the fw uses dynamic ps)
> * Use differnet wake up conditions on suspend
> * Add pattern support to wowlan triggers
>
> Eyal Shapira (4):
> wl12xx: Set different wake up conditions in case of suspend
> wl12xx: add suspend_listen_interval debugfs file
> wl12xx: add forced_ps mode
> wl12xx: add forced_ps debugfs file
>
> Pontus Fuchs (3):
> wl12xx: Add rx data filter commands
> wl12xx: Add functions for managing rx data filters
> wl12xx: Add support for WoWLAN packet pattern trigger
Skipping this patchset on Eliad's request. He will send a v2 with some
squashes and new patches soon.
--
Cheers,
Luca.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-01-31 7:43 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-30 14:58 [PATCH 0/7] wl12xx: add some psm/suspend features Eliad Peller
2012-01-30 14:58 ` [PATCH 1/7] wl12xx: Set different wake up conditions in case of suspend Eliad Peller
2012-01-30 14:58 ` [PATCH 2/7] wl12xx: add suspend_listen_interval debugfs file Eliad Peller
2012-01-30 14:58 ` [PATCH 3/7] wl12xx: add forced_ps mode Eliad Peller
2012-01-30 14:58 ` [PATCH 4/7] wl12xx: add forced_ps debugfs file Eliad Peller
2012-01-30 14:58 ` [PATCH 5/7] wl12xx: Add rx data filter commands Eliad Peller
2012-01-30 14:58 ` [PATCH 6/7] wl12xx: Add functions for managing rx data filters Eliad Peller
2012-01-30 14:58 ` [PATCH 7/7] wl12xx: Add support for WoWLAN packet pattern trigger Eliad Peller
2012-01-31 7:43 ` [PATCH 0/7] wl12xx: add some psm/suspend features Luciano Coelho
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).