From: Grazvydas Ignotas Date: Sat, 14 Feb 2015 01:21:38 +0000 (+0200) Subject: wl1251: change wake_up_conditions config X-Git-Tag: sz_173~61 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc9d1882a7b4ca1182f1b6f12aa87281a2a54f17;p=pandora-kernel.git wl1251: change wake_up_conditions config 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. --- diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 24e7aac4669e..607743202162 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -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); diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/wl1251/ps.c index a52ff7aa131e..5c5c3ff76f95 100644 --- a/drivers/net/wireless/wl1251/ps.c +++ b/drivers/net/wireless/wl1251/ps.c @@ -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; diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index 9b8461b14ed5..7c55b3e32791 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -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); diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index bcd2b4fd4b31..f839e9b6b5f1 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -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;