From 9f75f91f3a033e4f6faa5538e8f581664eeaf946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 17 Jan 2012 14:30:45 +0100 Subject: [PATCH] wired: emit Speed value in PropertiesChanged signal, when changed (bgo #667091) Speed is gotten via ethtool on 'carrier on' event. If there is a more suitable netlink event we should use it instead. Nonetheless, it appears to be working fine with carrier change, because interface speed change does emit carrier offi and on events. --- src/nm-device-ethernet.c | 47 +-------------------- src/nm-device-wired.c | 89 +++++++++++++++++++++++++++++++++++++++- src/nm-device-wired.h | 3 +- 3 files changed, 92 insertions(+), 47 deletions(-) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 51e397c6a..215e02511 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -24,11 +24,8 @@ #include #include #include -#include #include -#include #include -#include #include #include #include @@ -407,46 +404,6 @@ nm_device_ethernet_new (const char *udi, NULL); } -/* Returns speed in Mb/s */ -static guint32 -nm_device_ethernet_get_speed (NMDeviceEthernet *self) -{ - int fd; - struct ifreq ifr; - struct ethtool_cmd edata = { - .cmd = ETHTOOL_GSET, - }; - guint32 speed = 0; - - g_return_val_if_fail (self != NULL, 0); - - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); - return 0; - } - - memset (&ifr, 0, sizeof (struct ifreq)); - strncpy (ifr.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); - ifr.ifr_data = (char *) &edata; - - if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) - goto out; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) - speed = edata.speed; -#else - speed = ethtool_cmd_speed (&edata); -#endif - - if (speed == G_MAXUINT16 || speed == G_MAXUINT32) - speed = 0; - -out: - close (fd); - return speed; -} - static void _update_hw_addr (NMDeviceEthernet *self, const guint8 *addr) { @@ -1541,7 +1498,7 @@ get_property (GObject *object, guint prop_id, g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); break; case PROP_SPEED: - g_value_set_uint (value, nm_device_ethernet_get_speed (self)); + g_value_set_uint (value, nm_device_wired_get_speed (NM_DEVICE_WIRED (self))); break; case PROP_CARRIER: g_value_set_boolean (value, nm_device_wired_get_carrier (NM_DEVICE_WIRED (self))); diff --git a/src/nm-device-wired.c b/src/nm-device-wired.c index 918a2773b..224940df6 100644 --- a/src/nm-device-wired.c +++ b/src/nm-device-wired.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -25,6 +25,11 @@ #include #include #include +#include +#include +#include +#include +#include #include "nm-device-wired.h" #include "nm-device-private.h" @@ -48,6 +53,7 @@ typedef struct { guint hw_addr_type; guint hw_addr_len; gboolean carrier; + guint32 speed; NMNetlinkMonitor * monitor; gulong link_connected_id; @@ -56,6 +62,67 @@ typedef struct { } NMDeviceWiredPrivate; + +/* Returns speed in Mb/s */ +static guint32 +ethtool_get_speed (NMDeviceWired *self) +{ + int fd; + struct ifreq ifr; + struct ethtool_cmd edata = { + .cmd = ETHTOOL_GSET, + }; + guint32 speed = 0; + + g_return_val_if_fail (self != NULL, 0); + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + nm_log_warn (LOGD_HW, "couldn't open control socket."); + return 0; + } + + memset (&ifr, 0, sizeof (struct ifreq)); + strncpy (ifr.ifr_name, nm_device_get_iface (NM_DEVICE (self)), IFNAMSIZ); + ifr.ifr_data = (char *) &edata; + + if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) + goto out; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + speed = edata.speed; +#else + speed = ethtool_cmd_speed (&edata); +#endif + + if (speed == G_MAXUINT16 || speed == G_MAXUINT32) + speed = 0; + +out: + close (fd); + return speed; +} + +static void +set_speed (NMDeviceWired *self, const guint32 speed) +{ + NMDeviceWiredPrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (self); + if (priv->speed == speed) + return; + + priv->speed = speed; + g_object_notify (G_OBJECT (self), "speed"); + + nm_log_dbg (LOGD_HW | NM_DEVICE_WIRED_LOG_LEVEL (NM_DEVICE (self)), + "(%s): speed is now %d Mb/s", + nm_device_get_iface (NM_DEVICE (self)), + speed); +} + static void carrier_action_defer_clear (NMDeviceWired *self) { @@ -139,6 +206,7 @@ carrier_on (NMNetlinkMonitor *monitor, return; set_carrier (self, TRUE, FALSE); + set_speed (self, ethtool_get_speed (self)); } } @@ -542,3 +610,22 @@ nm_device_wired_get_carrier (NMDeviceWired *dev) priv = NM_DEVICE_WIRED_GET_PRIVATE (dev); return priv->carrier; } + +/** + * nm_device_wired_get_speed: + * @dev: an #NMDeviceWired + * + * Get @dev's speed + * + * Return value: @dev's speed in Mb/s + */ +guint32 +nm_device_wired_get_speed (NMDeviceWired *dev) +{ + NMDeviceWiredPrivate *priv; + + g_return_val_if_fail (dev != NULL, 0); + + priv = NM_DEVICE_WIRED_GET_PRIVATE (dev); + return priv->speed; +} diff --git a/src/nm-device-wired.h b/src/nm-device-wired.h index b2f6ee43f..c5959bb4b 100644 --- a/src/nm-device-wired.h +++ b/src/nm-device-wired.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2012 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -49,6 +49,7 @@ GType nm_device_wired_get_type (void); guint8 *nm_device_wired_get_hwaddr (NMDeviceWired *dev); int nm_device_wired_get_hwaddr_type (NMDeviceWired *dev); gboolean nm_device_wired_get_carrier (NMDeviceWired *dev); +guint32 nm_device_wired_get_speed (NMDeviceWired *dev); G_END_DECLS