aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Gospodarek <andy@greyhouse.net>2013-04-16 10:46:00 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-19 16:39:50 -0400
commitbb5b052f751b309b5181686741c724a66c5cb15a (patch)
tree5a5e8a92b9095ba0181929400353ddbd9d735711
parent4b457bdf1dbc961b62252034b05d47ec3e5b85d2 (diff)
bond: add support to read speed and duplex via ethtool
This patch adds support for the get_settings ethtool op to the bonding driver. This was motivated by users who wanted to get the speed of the bond and compare that against throughput to understand utilization. The behavior before this patch was added was problematic when computing line utilization after trying to get link-speed and throughput via SNMP. Output from ethtool looks like this for a round-robin bond: Settings for bond0: Supported ports: [ ] Supported link modes: Not reported Supported pause frame use: No Supports auto-negotiation: No Advertised link modes: Not reported Advertised pause frame use: No Advertised auto-negotiation: No Speed: 11000Mb/s Duplex: Full Port: Other PHYAD: 0 Transceiver: internal Auto-negotiation: off MDI-X: Unknown Link detected: yes I tested this and verified it works as expected. A test was also done on a version backported to an older kernel and it worked well there. v2: Switch to using ethtool_cmd_speed_set to set speed, added check to SLAVE_IS_OK for each slave in bond, dropped mode-specific calculations as they were not needed, and set port type to 'Other.' v3: Fix useless assignment and checkpatch warning. Signed-off-by: Andy Gospodarek <andy@greyhouse.net> Reviewed-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_main.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1e79a7643f08..5e22126c7a26 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4226,6 +4226,37 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
4226 } 4226 }
4227} 4227}
4228 4228
4229static int bond_ethtool_get_settings(struct net_device *bond_dev,
4230 struct ethtool_cmd *ecmd)
4231{
4232 struct bonding *bond = netdev_priv(bond_dev);
4233 struct slave *slave;
4234 int i;
4235 unsigned long speed = 0;
4236
4237 ecmd->duplex = DUPLEX_UNKNOWN;
4238 ecmd->port = PORT_OTHER;
4239
4240 /* Since SLAVE_IS_OK returns false for all inactive or down slaves, we
4241 * do not need to check mode. Though link speed might not represent
4242 * the true receive or transmit bandwidth (not all modes are symmetric)
4243 * this is an accurate maximum.
4244 */
4245 read_lock(&bond->lock);
4246 bond_for_each_slave(bond, slave, i) {
4247 if (SLAVE_IS_OK(slave)) {
4248 if (slave->speed != SPEED_UNKNOWN)
4249 speed += slave->speed;
4250 if (ecmd->duplex == DUPLEX_UNKNOWN &&
4251 slave->duplex != DUPLEX_UNKNOWN)
4252 ecmd->duplex = slave->duplex;
4253 }
4254 }
4255 ethtool_cmd_speed_set(ecmd, speed ? : SPEED_UNKNOWN);
4256 read_unlock(&bond->lock);
4257 return 0;
4258}
4259
4229static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, 4260static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
4230 struct ethtool_drvinfo *drvinfo) 4261 struct ethtool_drvinfo *drvinfo)
4231{ 4262{
@@ -4237,6 +4268,7 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
4237 4268
4238static const struct ethtool_ops bond_ethtool_ops = { 4269static const struct ethtool_ops bond_ethtool_ops = {
4239 .get_drvinfo = bond_ethtool_get_drvinfo, 4270 .get_drvinfo = bond_ethtool_get_drvinfo,
4271 .get_settings = bond_ethtool_get_settings,
4240 .get_link = ethtool_op_get_link, 4272 .get_link = ethtool_op_get_link,
4241}; 4273};
4242 4274