summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-02-10 16:46:34 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2016-02-12 14:07:13 +0100
commita9078cd3cce35f2f55566fc3c157a82fd8d45f8d (patch)
tree36dadd7aec10e07b14557e6fd401133b496925fa
parent0bfe70c57401b3867f71e31096bb8ee546f27eb0 (diff)
downloadNetworkManager-bg/wifi-powersave-bgo760125.tar.gz
wifi: don't touch by default current powersave settingbg/wifi-powersave-bgo760125
Some drivers (or things outside NM like 'powertop') may turn powersave on, so don't touch it unless explicitly configured by user. To achieve this, add new 'default' and 'ignore' options; the former can be used to fall back to a globally configured setting, while the latter tells NM not to touch the current setting. When 'default' is specified, a missing global default configuration is equivalent to 'ignore'. It is possible to enable Wi-Fi power saving for all connections by dropping a file in /etc/NetworkManager/conf.d with the following content: [connection] wifi.powersave=3 https://bugzilla.gnome.org/show_bug.cgi?id=760125
-rw-r--r--clients/cli/settings.c50
-rw-r--r--libnm-core/nm-setting-wireless.c15
-rw-r--r--libnm-core/nm-setting-wireless.h19
-rw-r--r--libnm/libnm.ver1
-rw-r--r--man/NetworkManager.conf.xml.in5
-rw-r--r--src/devices/wifi/nm-device-wifi.c41
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c23
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c17
8 files changed, 139 insertions, 32 deletions
diff --git a/clients/cli/settings.c b/clients/cli/settings.c
index 5809a0fc88..0c164f0c8e 100644
--- a/clients/cli/settings.c
+++ b/clients/cli/settings.c
@@ -1855,14 +1855,19 @@ static char *
nmc_property_wireless_get_powersave (NMSetting *setting, NmcPropertyGetType get_type)
{
NMSettingWireless *s_wireless = NM_SETTING_WIRELESS (setting);
- guint powersave = nm_setting_wireless_get_powersave (s_wireless);
+ NMSettingWirelessPowersave powersave;
+ gs_free char *str = NULL;
+ char *ret;
- if (powersave == 0)
- return g_strdup (_("no"));
- else if (powersave == 1)
- return g_strdup (_("yes"));
- else
- return g_strdup_printf (_("yes (%u)"), powersave);
+ powersave = nm_setting_wireless_get_powersave (s_wireless);
+ str = nm_utils_enum_to_str (nm_setting_wireless_powersave_get_type (), powersave);
+
+ if (get_type == NMC_PROPERTY_GET_PARSABLE) {
+ ret = str;
+ str = NULL;
+ return ret;
+ } else
+ return g_strdup_printf ("%s (%u)", str, powersave);
}
static char *
@@ -4919,20 +4924,33 @@ DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_wireless_remove_mac_address_blacklis
static gboolean
nmc_property_wireless_set_powersave (NMSetting *setting, const char *prop, const char *val, GError **error)
{
- unsigned long powersave_int;
- gboolean val_bool = FALSE;
-
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ NMSettingWirelessPowersave powersave;
+ gs_free const char **options = NULL;
+ gs_free char *options_str = NULL;
+ long int t;
+ gboolean ret;
- if (!nmc_string_to_uint (val, TRUE, 0, G_MAXUINT32, &powersave_int)) {
- if (!nmc_string_to_bool (val, &val_bool, NULL)) {
- g_set_error (error, 1, 0, _("'%s' is not a valid powersave value"), val);
+ if (nmc_string_to_int_base (val, 0, TRUE,
+ NM_SETTING_WIRELESS_POWERSAVE_DEFAULT,
+ NM_SETTING_WIRELESS_POWERSAVE_LAST,
+ &t))
+ powersave = (NMSettingWirelessPowersave) t;
+ else {
+ ret = nm_utils_enum_from_str (nm_setting_wireless_powersave_get_type (),
+ val,
+ (int *) &powersave,
+ NULL);
+ if (!ret) {
+ options = nm_utils_enum_get_values (nm_setting_wireless_powersave_get_type (),
+ NM_SETTING_WIRELESS_POWERSAVE_DEFAULT,
+ NM_SETTING_WIRELESS_POWERSAVE_LAST);
+ options_str = g_strjoinv (",", (char **) options);
+ g_set_error (error, 1, 0, _("invalid option '%s', use one of [%s]"), val, options_str);
return FALSE;
}
- powersave_int = val_bool ? 1 : 0;
}
- g_object_set (setting, prop, (guint32) powersave_int, NULL);
+ g_object_set (setting, prop, (guint) powersave, NULL);
return TRUE;
}
diff --git a/libnm-core/nm-setting-wireless.c b/libnm-core/nm-setting-wireless.c
index 3b27893350..6b9ad0ba13 100644
--- a/libnm-core/nm-setting-wireless.c
+++ b/libnm-core/nm-setting-wireless.c
@@ -1365,25 +1365,26 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
/**
* NMSettingWireless:powersave:
*
- * If set to %FALSE, Wi-Fi power saving behavior is disabled. If set to
- * %TRUE, Wi-Fi power saving behavior is enabled. All other values are
- * reserved. Note that even though only boolean values are allowed, the
- * property type is an unsigned integer to allow for future expansion.
+ * One of %NM_SETTING_WIRELESS_POWERSAVE_DISABLE (disable Wi-Fi power
+ * saving), %NM_SETTING_WIRELESS_POWERSAVE_ENABLE (enable Wi-Fi power
+ * saving), %NM_SETTING_WIRELESS_POWERSAVE_IGNORE (don't touch currently
+ * configure setting) or %NM_SETTING_WIRELESS_POWERSAVE_DEFAULT (use the
+ * globally configured value). All other values are reserved.
*
* Since: 1.2
**/
/* ---ifcfg-rh---
* property: powersave
* variable: POWERSAVE(+)
- * default: no
+ * values: default, ignore, enable, disable
* description: Enables or disables Wi-Fi power saving.
- * example: POWERSAVE=yes
+ * example: POWERSAVE=enable
* ---end---
*/
g_object_class_install_property
(object_class, PROP_POWERSAVE,
g_param_spec_uint (NM_SETTING_WIRELESS_POWERSAVE, "", "",
- 0, G_MAXUINT32, 0,
+ 0, G_MAXUINT32, NM_SETTING_WIRELESS_POWERSAVE_DEFAULT,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
diff --git a/libnm-core/nm-setting-wireless.h b/libnm-core/nm-setting-wireless.h
index a4c0147f40..606733fa91 100644
--- a/libnm-core/nm-setting-wireless.h
+++ b/libnm-core/nm-setting-wireless.h
@@ -80,6 +80,25 @@ G_BEGIN_DECLS
*/
#define NM_SETTING_WIRELESS_MODE_INFRA "infrastructure"
+/**
+ * NMSettingWirelessPowersave:
+ * @NM_SETTING_WIRELESS_POWERSAVE_DEFAULT: use the default value
+ * @NM_SETTING_WIRELESS_POWERSAVE_IGNORE: don't touch existing setting
+ * @NM_SETTING_WIRELESS_POWERSAVE_DISABLE: disable powersave
+ * @NM_SETTING_WIRELESS_POWERSAVE_ENABLE: enable powersave
+ *
+ * These flags indicate whether wireless powersave must be enabled.
+ **/
+typedef enum {
+ NM_SETTING_WIRELESS_POWERSAVE_DEFAULT = 0,
+ NM_SETTING_WIRELESS_POWERSAVE_IGNORE = 1,
+ NM_SETTING_WIRELESS_POWERSAVE_DISABLE = 2,
+ NM_SETTING_WIRELESS_POWERSAVE_ENABLE = 3,
+ _NM_SETTING_WIRELESS_POWERSAVE_NUM, /*< skip >*/
+ NM_SETTING_WIRELESS_POWERSAVE_LAST = _NM_SETTING_WIRELESS_POWERSAVE_NUM - 1, /*< skip >*/
+} NMSettingWirelessPowersave;
+
+
struct _NMSettingWireless {
NMSetting parent;
};
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 8e01a310fb..3867c3df0e 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1014,6 +1014,7 @@ global:
nm_setting_wired_wake_on_lan_get_type;
nm_setting_wireless_get_powersave;
nm_setting_wireless_get_mac_address_randomization;
+ nm_setting_wireless_powersave_get_type;
nm_utils_bond_mode_int_to_string;
nm_utils_bond_mode_string_to_int;
nm_utils_enum_from_str;
diff --git a/man/NetworkManager.conf.xml.in b/man/NetworkManager.conf.xml.in
index a2bd36e056..75e1d93807 100644
--- a/man/NetworkManager.conf.xml.in
+++ b/man/NetworkManager.conf.xml.in
@@ -563,6 +563,11 @@ ipv6.ip6-privacy=0
<term><varname>wifi.mac-address-randomization</varname></term>
<listitem><para>If left unspecified, MAC address randomization is disabled.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>wifi.powersave</varname></term>
+ <listitem><para>If left unspecified, the default value
+ "<literal>ignore</literal>" will be used.</para></listitem>
+ </varlistentry>
</variablelist>
</para>
</refsect2>
diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c
index 63aa6d22bd..e4640786b6 100644
--- a/src/devices/wifi/nm-device-wifi.c
+++ b/src/devices/wifi/nm-device-wifi.c
@@ -489,8 +489,6 @@ deactivate (NMDevice *device)
if (nm_device_get_initial_hw_address (device))
nm_device_set_hw_addr (device, nm_device_get_initial_hw_address (device), "reset", LOGD_WIFI);
- nm_platform_wifi_set_powersave (NM_PLATFORM_GET, ifindex, 0);
-
/* Ensure we're in infrastructure mode after deactivation; some devices
* (usually older ones) don't scan well in adhoc mode.
*/
@@ -2388,6 +2386,38 @@ ensure_hotspot_frequency (NMDeviceWifi *self,
nm_ap_set_freq (ap, freq);
}
+static void
+set_powersave (NMDevice *device)
+{
+ NMDeviceWifi *self = NM_DEVICE_WIFI (device);
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessPowersave powersave;
+ gs_free char *value = NULL;
+
+ s_wireless = (NMSettingWireless *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS);
+ g_return_if_fail (s_wireless);
+
+ powersave = nm_setting_wireless_get_powersave (s_wireless);
+ if (powersave == NM_SETTING_WIRELESS_POWERSAVE_DEFAULT) {
+ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA,
+ "wifi.powersave",
+ device);
+ powersave = _nm_utils_ascii_str_to_int64 (value, 10,
+ NM_SETTING_WIRELESS_POWERSAVE_IGNORE,
+ NM_SETTING_WIRELESS_POWERSAVE_ENABLE,
+ NM_SETTING_WIRELESS_POWERSAVE_IGNORE);
+ }
+
+ _LOGT (LOGD_WIFI, "powersave is set to %u", (unsigned int) powersave);
+
+ if (powersave == NM_SETTING_WIRELESS_POWERSAVE_IGNORE)
+ return;
+
+ nm_platform_wifi_set_powersave (NM_PLATFORM_GET,
+ nm_device_get_ifindex (device),
+ powersave == NM_SETTING_WIRELESS_POWERSAVE_ENABLE);
+}
+
static NMActStageReturn
act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
{
@@ -2454,11 +2484,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
if ((nm_ap_get_mode (ap) == NM_802_11_MODE_ADHOC) || nm_ap_is_hotspot (ap))
ensure_hotspot_frequency (self, s_wireless, ap);
- if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA) {
- nm_platform_wifi_set_powersave (NM_PLATFORM_GET,
- nm_device_get_ifindex (device),
- nm_setting_wireless_get_powersave (s_wireless));
- }
+ if (nm_ap_get_mode (ap) == NM_802_11_MODE_INFRA)
+ set_powersave (device);
/* Build up the supplicant configuration */
config = build_supplicant_config (self, connection, nm_ap_get_freq (ap), &error);
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index 1da55c5ae0..add589dc70 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -3332,6 +3332,7 @@ make_wireless_setting (shvarFile *ifcfg,
char *value = NULL;
gint64 chan = 0;
NMSettingMacRandomization mac_randomization = NM_SETTING_MAC_RANDOMIZATION_NEVER;
+ NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT;
s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
@@ -3509,9 +3510,28 @@ make_wireless_setting (shvarFile *ifcfg,
svGetValueBoolean (ifcfg, "SSID_HIDDEN", FALSE),
NULL);
+ value = svGetValueFull (ifcfg, "POWERSAVE", FALSE);
+ if (value) {
+ if (!strcmp (value, "default"))
+ powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT;
+ else if (!strcmp (value, "ignore"))
+ powersave = NM_SETTING_WIRELESS_POWERSAVE_IGNORE;
+ else if (!strcmp (value, "disable") || !strcmp (value, "no"))
+ powersave = NM_SETTING_WIRELESS_POWERSAVE_DISABLE;
+ else if (!strcmp (value, "enable") || !strcmp (value, "yes"))
+ powersave = NM_SETTING_WIRELESS_POWERSAVE_ENABLE;
+ else {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ "Invalid POWERSAVE value '%s'", value);
+ g_free (value);
+ goto error;
+ }
+ g_free (value);
+ }
+
g_object_set (s_wireless,
NM_SETTING_WIRELESS_POWERSAVE,
- svGetValueBoolean (ifcfg, "POWERSAVE", FALSE) ? 1 : 0,
+ powersave,
NULL);
value = svGetValueFull (ifcfg, "MAC_ADDRESS_RANDOMIZATION", FALSE);
@@ -3525,6 +3545,7 @@ make_wireless_setting (shvarFile *ifcfg,
else {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid MAC_ADDRESS_RANDOMIZATION value '%s'", value);
+ g_free (value);
goto error;
}
g_free (value);
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index c16d7ab291..3f63425942 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -981,7 +981,22 @@ write_wireless_setting (NMConnection *connection,
}
svSetValue (ifcfg, "SSID_HIDDEN", nm_setting_wireless_get_hidden (s_wireless) ? "yes" : NULL, TRUE);
- svSetValue (ifcfg, "POWERSAVE", nm_setting_wireless_get_powersave (s_wireless) ? "yes" : NULL, TRUE);
+
+ switch (nm_setting_wireless_get_powersave (s_wireless)) {
+ case NM_SETTING_WIRELESS_POWERSAVE_IGNORE:
+ svSetValue (ifcfg, "POWERSAVE", "ignore", TRUE);
+ break;
+ case NM_SETTING_WIRELESS_POWERSAVE_DISABLE:
+ svSetValue (ifcfg, "POWERSAVE", "disable", TRUE);
+ break;
+ case NM_SETTING_WIRELESS_POWERSAVE_ENABLE:
+ svSetValue (ifcfg, "POWERSAVE", "enable", TRUE);
+ break;
+ default:
+ case NM_SETTING_WIRELESS_POWERSAVE_DEFAULT:
+ svSetValue (ifcfg, "POWERSAVE", NULL, TRUE);
+ break;
+ }
svSetValue (ifcfg, "MAC_ADDRESS_RANDOMIZATION", NULL, TRUE);
switch (nm_setting_wireless_get_mac_address_randomization (s_wireless)) {