Hi,
Thank you for your feedback. Answers inside.
Le mercredi 12 octobre 2011 à 23:44 -0500, Dan Williams a écrit :
> On Wed, 2011-10-12 at 13:22 +0200, Jean Parpaillon wrote:
> > From: Jean Parpaillon <jean parpaillon free fr>
>
> So what's the overall architecture here? This is the implementation,
> clearly, but what goes into the device's virtual functions like
> can_wake_up() and prepare_wake_up()?
>
I must admit that I sent this hoping to (re?)start a discussion on the
subject.
My understanding is the following:
- for ethernet (or ethernet-like) devices, there is a common interface
for wakeup capable devices. It mainly consist in enable/disable wakeup
and, for some devices, setting a 'secret'
- this interface have been (partly) generalized with the ACPI syfs
interface. Each (capable) device has a wakeup file in his sysfs
structure in where you can write enable/disable and this is suppose to
deal with power during S3 ACPI state and maybe more (rfkill ?, network
not disconnecting when calling kernel halt() ?) ?
My developments were stopped when I found that my laptop BIOS does not
support powering up mini PCIe device when in S3 state, as it was
supposed to be the case (thanks lenovo ;) )
So, in a first time, I needed to have this property to ensure
NetworkManager is not disconnecting the device when sleeping.
prepare_wakeup(), in my thoughts, must prepare the device for waking up
(!), which means, for instance, setting the secret for waking up. But
this is based on the device I use, which is ericsson F5521gw.
Nevertheless, I think that this architecture is pretty generic, as it is
also used by ethtool.
Of course, CanWakeUp should be consistent with ACPI wakeup property in
sysfs and prepare_wakeup() should just call a generic interface in the
kernel... which exists only in the (old ?) ethtool interface.
Does it make sense for you ? For what you can see, I have still a lot of
questions but I am really interested in discussing this subject to
provide a NM "standardized" way of dealing with wow.
> Also would be good to pull Matthew Garrett in here; we've had
> discussions about WOL/WOWLAN before.
>
Sure.
> Dan
>
Best regards,
Jean
> > ---
> > introspection/nm-device.xml | 5 ++++
> > libnm-glib/nm-device.c | 48 +++++++++++++++++++++++++++++++++++++++++++
> > libnm-glib/nm-device.h | 2 +
> > src/nm-device-interface.c | 7 ++++++
> > src/nm-device-interface.h | 2 +
> > src/nm-device.c | 23 ++++++++++++++++++++
> > src/nm-device.h | 4 +++
> > 7 files changed, 91 insertions(+), 0 deletions(-)
> >
> > diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml
> > index 5fdda96..2e29bb4 100644
> > --- a/introspection/nm-device.xml
> > +++ b/introspection/nm-device.xml
> > @@ -97,6 +97,11 @@
> > The general type of the network device; ie Ethernet, WiFi, etc.
> > </tp:docstring>
> > </property>
> > + <property name="CanWakeUp" type="b" access="readwrite" >
> > + <tp:docstring>
> > + If TRUE, the device can wake up the host when sleeping.
> > + </tp:docstring>
> > + </property>
> >
> > <method name="Disconnect">
> > <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_disconnect"/>
> > diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
> > index f06c1e4..9b832d3 100644
> > --- a/libnm-glib/nm-device.c
> > +++ b/libnm-glib/nm-device.c
> > @@ -55,6 +55,7 @@ typedef struct {
> > NMDeviceCapabilities capabilities;
> > gboolean managed;
> > gboolean firmware_missing;
> > + gboolean can_wake_up;
> > NMIP4Config *ip4_config;
> > gboolean got_ip4_config;
> > NMDHCP4Config *dhcp4_config;
> > @@ -81,6 +82,7 @@ enum {
> > PROP_CAPABILITIES,
> > PROP_MANAGED,
> > PROP_FIRMWARE_MISSING,
> > + PROP_CAN_WAKE_UP,
> > PROP_IP4_CONFIG,
> > PROP_DHCP4_CONFIG,
> > PROP_IP6_CONFIG,
> > @@ -304,6 +306,7 @@ register_for_property_changed (NMDevice *device)
> > { NM_DEVICE_CAPABILITIES, _nm_object_demarshal_generic, &priv->capabilities },
> > { NM_DEVICE_MANAGED, _nm_object_demarshal_generic, &priv->managed },
> > { NM_DEVICE_FIRMWARE_MISSING, _nm_object_demarshal_generic, &priv->firmware_missing },
> > + { NM_DEVICE_CAN_WAKE_UP, _nm_object_demarshal_generic, &priv->can_wake_up },
> > { NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config },
> > { NM_DEVICE_DHCP4_CONFIG, demarshal_dhcp4_config, &priv->dhcp4_config },
> > { NM_DEVICE_IP6_CONFIG, demarshal_ip6_config, &priv->ip6_config },
> > @@ -452,6 +455,9 @@ get_property (GObject *object,
> > case PROP_FIRMWARE_MISSING:
> > g_value_set_boolean (value, nm_device_get_firmware_missing (device));
> > break;
> > + case PROP_CAN_WAKE_UP:
> > + g_value_set_boolean (value, nm_device_get_can_wake_up (device));
> > + break;
> > case PROP_IP4_CONFIG:
> > g_value_set_object (value, nm_device_get_ip4_config (device));
> > break;
> > @@ -496,6 +502,9 @@ set_property (GObject *object,
> > /* Construct only */
> > priv->device_type = g_value_get_uint (value);
> > break;
> > + case PROP_CAN_WAKE_UP:
> > + priv->can_wake_up = g_value_get_boolean (value);
> > + break;
> > default:
> > G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
> > break;
> > @@ -629,6 +638,19 @@ nm_device_class_init (NMDeviceClass *device_class)
> > G_PARAM_READABLE));
> >
> > /**
> > + * NMDevice:can-wake-up:
> > + *
> > + * When %TRUE indicates the device can be used to wake up the machine.
> > + **/
> > + g_object_class_install_property
> > + (object_class, PROP_CAN_WAKE_UP,
> > + g_param_spec_boolean (NM_DEVICE_CAN_WAKE_UP,
> > + "CanWakeUp",
> > + "Device can WakeUp",
> > + FALSE,
> > + G_PARAM_READWRITE));
> > +
> > + /**
> > * NMDevice:ip4-config:
> > *
> > * The #NMIP4Config of the device.
> > @@ -1036,6 +1058,32 @@ nm_device_get_firmware_missing (NMDevice *device)
> > }
> >
> > /**
> > + * nm_device_get_can_wake_up:
> > + * @device: a #NMDevice
> > + *
> > + * Indicates that the device can be used to wake up the machine
> > + *
> > + * Returns: %TRUE if the device can be used to wake up the machine.
> > + **/
> > +gboolean
> > +nm_device_get_can_wake_up (NMDevice *device)
> > +{
> > + NMDevicePrivate *priv;
> > +
> > + g_return_val_if_fail (NM_IS_DEVICE (device), 0);
> > +
> > + priv = NM_DEVICE_GET_PRIVATE (device);
> > + if (!priv->can_wake_up) {
> > + priv->can_wake_up = _nm_object_get_boolean_property (NM_OBJECT (device),
> > + NM_DBUS_INTERFACE_DEVICE,
> > + "CanWakeUp",
> > + NULL);
> > + }
> > +
> > + return priv->can_wake_up;
> > +}
> > +
> > +/**
> > * nm_device_get_ip4_config:
> > * @device: a #NMDevice
> > *
> > diff --git a/libnm-glib/nm-device.h b/libnm-glib/nm-device.h
> > index e21e71b..df89869 100644
> > --- a/libnm-glib/nm-device.h
> > +++ b/libnm-glib/nm-device.h
> > @@ -53,6 +53,7 @@ G_BEGIN_DECLS
> > #define NM_DEVICE_CAPABILITIES "capabilities"
> > #define NM_DEVICE_MANAGED "managed"
> > #define NM_DEVICE_FIRMWARE_MISSING "firmware-missing"
> > +#define NM_DEVICE_CAN_WAKE_UP "can-wake-up"
> > #define NM_DEVICE_IP4_CONFIG "ip4-config"
> > #define NM_DEVICE_DHCP4_CONFIG "dhcp4-config"
> > #define NM_DEVICE_IP6_CONFIG "ip6-config"
> > @@ -99,6 +100,7 @@ const char * nm_device_get_driver (NMDevice *device);
> > NMDeviceCapabilities nm_device_get_capabilities (NMDevice *device);
> > gboolean nm_device_get_managed (NMDevice *device);
> > gboolean nm_device_get_firmware_missing (NMDevice *device);
> > +gboolean nm_device_get_can_wake_up (NMDevice *device);
> > NMIP4Config * nm_device_get_ip4_config (NMDevice *device);
> > NMDHCP4Config * nm_device_get_dhcp4_config (NMDevice *device);
> > NMIP6Config * nm_device_get_ip6_config (NMDevice *device);
> > diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c
> > index fb471f5..f1d6d7f 100644
> > --- a/src/nm-device-interface.c
> > +++ b/src/nm-device-interface.c
> > @@ -195,6 +195,13 @@ nm_device_interface_init (gpointer g_iface)
> > G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
> >
> > g_object_interface_install_property
> > + (g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_CAN_WAKE_UP,
> > + "CanWakeUp",
> > + "Can wake up machine",
> > + FALSE,
> > + G_PARAM_READWRITE));
> > +
> > + g_object_interface_install_property
> > (g_iface,
> > g_param_spec_string (NM_DEVICE_INTERFACE_TYPE_DESC,
> > "Type Description",
> > diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h
> > index 560cdfe..0c73001 100644
> > --- a/src/nm-device-interface.h
> > +++ b/src/nm-device-interface.h
> > @@ -62,6 +62,7 @@ typedef enum
> > #define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */
> > #define NM_DEVICE_INTERFACE_MANAGED "managed"
> > #define NM_DEVICE_INTERFACE_FIRMWARE_MISSING "firmware-missing"
> > +#define NM_DEVICE_INTERFACE_CAN_WAKE_UP "can-wake-up"
> > #define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */
> > #define NM_DEVICE_INTERFACE_RFKILL_TYPE "rfkill-type" /* Internal only */
> > #define NM_DEVICE_INTERFACE_IFINDEX "ifindex" /* Internal only */
> > @@ -84,6 +85,7 @@ typedef enum {
> > NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE,
> > NM_DEVICE_INTERFACE_PROP_MANAGED,
> > NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING,
> > + NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP,
> > NM_DEVICE_INTERFACE_PROP_TYPE_DESC,
> > NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE,
> > NM_DEVICE_INTERFACE_PROP_IFINDEX,
> > diff --git a/src/nm-device.c b/src/nm-device.c
> > index 559606c..31a73c1 100644
> > --- a/src/nm-device.c
> > +++ b/src/nm-device.c
> > @@ -96,6 +96,7 @@ typedef struct {
> > gboolean managed; /* whether managed by NM or not */
> > RfKillType rfkill_type;
> > gboolean firmware_missing;
> > + gboolean can_wake_up;
> >
> > guint32 ip4_address;
> >
> > @@ -2985,6 +2986,18 @@ nm_device_can_interrupt_activation (NMDevice *self)
> > return interrupt;
> > }
> >
> > +gboolean
> > +nm_device_can_wake_up (NMDevice *self)
> > +{
> > + gboolean wake_up = FALSE;
> > +
> > + g_return_val_if_fail (self != NULL, FALSE);
> > +
> > + if (NM_DEVICE_GET_CLASS (self)->can_wake_up)
> > + wake_up = NM_DEVICE_GET_CLASS (self)->can_wake_up (self);
> > + return wake_up;
> > +}
> > +
> > /* IP Configuration stuff */
> >
> > NMDHCP4Config *
> > @@ -3431,6 +3444,9 @@ set_property (GObject *object, guint prop_id,
> > case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING:
> > priv->firmware_missing = g_value_get_boolean (value);
> > break;
> > + case NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP:
> > + priv->can_wake_up = g_value_get_boolean (value);
> > + break;
> > case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE:
> > g_return_if_fail (priv->type == NM_DEVICE_TYPE_UNKNOWN);
> > priv->type = g_value_get_uint (value);
> > @@ -3531,6 +3547,9 @@ get_property (GObject *object, guint prop_id,
> > case NM_DEVICE_INTERFACE_PROP_FIRMWARE_MISSING:
> > g_value_set_boolean (value, priv->firmware_missing);
> > break;
> > + case NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP:
> > + g_value_set_boolean (value, priv->can_wake_up);
> > + break;
> > case NM_DEVICE_INTERFACE_PROP_TYPE_DESC:
> > g_value_set_string (value, priv->type_desc);
> > break;
> > @@ -3636,6 +3655,10 @@ nm_device_class_init (NMDeviceClass *klass)
> > NM_DEVICE_INTERFACE_FIRMWARE_MISSING);
> >
> > g_object_class_override_property (object_class,
> > + NM_DEVICE_INTERFACE_PROP_CAN_WAKE_UP,
> > + NM_DEVICE_INTERFACE_CAN_WAKE_UP);
> > +
> > + g_object_class_override_property (object_class,
> > NM_DEVICE_INTERFACE_PROP_TYPE_DESC,
> > NM_DEVICE_INTERFACE_TYPE_DESC);
> >
> > diff --git a/src/nm-device.h b/src/nm-device.h
> > index 1d080ed..b7273de 100644
> > --- a/src/nm-device.h
> > +++ b/src/nm-device.h
> > @@ -118,6 +118,9 @@ typedef struct {
> >
> > gboolean (* can_interrupt_activation) (NMDevice *self);
> >
> > + /* true if device must be kept on when sleeping */
> > + gboolean (* can_wake_up) (NMDevice *self);
> > +
> > gboolean (* spec_match_list) (NMDevice *self, const GSList *specs);
> >
> > NMConnection * (* connection_match_config) (NMDevice *self, const GSList *connections);
> > @@ -176,6 +179,7 @@ void nm_device_activate_schedule_stage4_ip6_config_get (NMDevice *device);
> > void nm_device_activate_schedule_stage4_ip6_config_timeout (NMDevice *device);
> > gboolean nm_device_is_activating (NMDevice *dev);
> > gboolean nm_device_can_interrupt_activation (NMDevice *self);
> > +gboolean nm_device_can_wake_up (NMDevice *self);
> > gboolean nm_device_autoconnect_allowed (NMDevice *self);
> >
> > NMDeviceState nm_device_get_state (NMDevice *device);
>
>
>
--
Jean Parpaillon
Pulse2 project leader
Mandriva SA - http://mandriva.com
Rennes - FR
Phone: +33 6 30 10 92 86
email: jparpaillon mandriva com
jabber: jean parpaillon gmail com
skype: jean.parpaillon
Attachment:
signature.asc
Description: This is a digitally signed message part