wl1251: change wake_up_conditions config
authorGrazvydas Ignotas <notasas@gmail.com>
Sat, 14 Feb 2015 01:21:38 +0000 (03:21 +0200)
committerGrazvydas Ignotas <notasas@gmail.com>
Fri, 20 Feb 2015 22:05:30 +0000 (00:05 +0200)
Setting BEACON_BITMAP (or never sending wake_up_conditions at all) reduces
ping times from external device from jumping between to 20-230ms to 20-100ms
and gives better ssh experience.
The power usage increase was measured to be ~8mA@4.1V, so I consider it
worth it (in comparison, connected and idle USB wifi dongle draws ~150mA
from the battery).

There is a new sysfs file to enable old behavior:
/sys/bus/mmc/devices/mmc2\:0001/mmc2\:0001\:1/long_doze_mode
but the command is only sent once.

Hopefully this will improve router compatibility too.
note: WAKE_UP_EVENT_DTIM_BITMAP is called "long doze mode" by TI driver.

drivers/net/wireless/wl1251/main.c
drivers/net/wireless/wl1251/ps.c
drivers/net/wireless/wl1251/sdio.c
drivers/net/wireless/wl1251/wl1251.h

index 24e7aac..6077432 100644 (file)
@@ -510,6 +510,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
        wl->channel = WL1251_DEFAULT_CHANNEL;
        wl->monitor_present = false;
        wl->joined = false;
+       wl->long_doze_mode_set = false;
 
        wl1251_debugfs_reset(wl);
 
index a52ff7a..5c5c3ff 100644 (file)
@@ -112,11 +112,13 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode)
        case STATION_POWER_SAVE_MODE:
                wl1251_debug(DEBUG_PSM, "entering psm");
 
-               ret = wl1251_acx_wake_up_conditions(wl,
-                                                   WAKE_UP_EVENT_DTIM_BITMAP,
-                                                   wl->listen_int);
-               if (ret < 0)
-                       return ret;
+               if (wl->long_doze_mode != wl->long_doze_mode_set) {
+                       wl1251_acx_wake_up_conditions(wl, wl->long_doze_mode
+                               ? WAKE_UP_EVENT_DTIM_BITMAP
+                               : WAKE_UP_EVENT_BEACON_BITMAP,
+                               wl->listen_int);
+                       wl->long_doze_mode_set = wl->long_doze_mode;
+               }
 
 #if 0 /* problems seen on one router */
                ret = wl1251_acx_bet_enable(wl, WL1251_ACX_BET_ENABLE,
@@ -165,12 +167,6 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode)
                if (ret < 0)
                        return ret;
 
-               ret = wl1251_acx_wake_up_conditions(wl,
-                                                   WAKE_UP_EVENT_DTIM_BITMAP,
-                                                   wl->listen_int);
-               if (ret < 0)
-                       return ret;
-
                ret = wl1251_cmd_ps_mode(wl, CHIP_ACTIVE_MODE);
                if (ret < 0)
                        return ret;
index 9b8461b..7c55b3e 100644 (file)
@@ -217,6 +217,31 @@ static struct wl1251_if_operations wl1251_sdio_ops = {
        .power = wl1251_sdio_set_power,
 };
 
+static ssize_t
+wl1251_show_long_doze(struct device *dev, struct device_attribute *attr,
+       char *buf)
+{
+       struct wl1251 *wl = dev_get_drvdata(dev);
+       return sprintf(buf, "%d\n", wl->long_doze_mode);
+}
+
+static ssize_t
+wl1251_set_long_doze(struct device *dev, struct device_attribute *attr,
+       const char *buf, size_t count)
+{
+       struct wl1251 *wl = dev_get_drvdata(dev);
+       int val, ret;
+
+       ret = kstrtoint(buf, 10, &val);
+       if (ret < 0)
+               return ret;
+
+       wl->long_doze_mode = !!val;
+       return count;
+}
+static DEVICE_ATTR(long_doze_mode, S_IRUGO | S_IWUSR,
+       wl1251_show_long_doze, wl1251_set_long_doze);
+
 static int wl1251_sdio_probe(struct sdio_func *func,
                             const struct sdio_device_id *id)
 {
@@ -291,6 +316,10 @@ static int wl1251_sdio_probe(struct sdio_func *func,
 
        sdio_set_drvdata(func, wl);
 
+       ret = device_create_file(&func->dev, &dev_attr_long_doze_mode);
+       if (ret)
+               goto out_free_irq;
+
        /* Tell PM core that we don't need the card to be powered now */
        pm_runtime_put_noidle(&func->dev);
 
@@ -318,6 +347,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
        /* Undo decrement done above in wl1251_probe */
        pm_runtime_get_noresume(&func->dev);
 
+       device_remove_file(&func->dev, &dev_attr_long_doze_mode);
+
        if (wl->irq)
                free_irq(wl->irq, wl);
        wl1251_free_hw(wl);
index bcd2b4f..f839e9b 100644 (file)
@@ -284,6 +284,8 @@ struct wl1251 {
        int irq;
        bool use_eeprom;
        bool dump_eeprom;
+       bool long_doze_mode;
+       bool long_doze_mode_set;
 
        spinlock_t wl_lock;