aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-09-02 23:34:30 -0400
committerDavid S. Miller <davem@davemloft.net>2011-09-15 17:32:26 -0400
commit4bc71cb983fd2844e603bf633df2bb53385182d2 (patch)
tree067b6df32fda6c554b2b9263a94a585c2e5a832d /net/core
parentc5dac7c9984d8a034eb7ae149cedf23ec9259f98 (diff)
net: consolidate and fix ethtool_ops->get_settings calling
This patch does several things: - introduces __ethtool_get_settings which is called from ethtool code and from drivers as well. Put ASSERT_RTNL there. - dev_ethtool_get_settings() is replaced by __ethtool_get_settings() - changes calling in drivers so rtnl locking is respected. In iboe_get_rate was previously ->get_settings() called unlocked. This fixes it. Also prb_calc_retire_blk_tmo() in af_packet.c had the same problem. Also fixed by calling __dev_get_by_index() instead of dev_get_by_index() and holding rtnl_lock for both calls. - introduces rtnl_lock in bnx2fc_vport_create() and fcoe_vport_create() so bnx2fc_if_create() and fcoe_if_create() are called locked as they are from other places. - use __ethtool_get_settings() in bonding code Signed-off-by: Jiri Pirko <jpirko@redhat.com> v2->v3: -removed dev_ethtool_get_settings() -added ASSERT_RTNL into __ethtool_get_settings() -prb_calc_retire_blk_tmo - use __dev_get_by_index() and lock around it and __ethtool_get_settings() call v1->v2: add missing export_symbol Reviewed-by: Ben Hutchings <bhutchings@solarflare.com> [except FCoE bits] Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c24
-rw-r--r--net/core/ethtool.c20
-rw-r--r--net/core/net-sysfs.c4
3 files changed, 17 insertions, 31 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index b2e262ed3963..4b9981caf06f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4566,30 +4566,6 @@ void dev_set_rx_mode(struct net_device *dev)
4566} 4566}
4567 4567
4568/** 4568/**
4569 * dev_ethtool_get_settings - call device's ethtool_ops::get_settings()
4570 * @dev: device
4571 * @cmd: memory area for ethtool_ops::get_settings() result
4572 *
4573 * The cmd arg is initialized properly (cleared and
4574 * ethtool_cmd::cmd field set to ETHTOOL_GSET).
4575 *
4576 * Return device's ethtool_ops::get_settings() result value or
4577 * -EOPNOTSUPP when device doesn't expose
4578 * ethtool_ops::get_settings() operation.
4579 */
4580int dev_ethtool_get_settings(struct net_device *dev,
4581 struct ethtool_cmd *cmd)
4582{
4583 if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
4584 return -EOPNOTSUPP;
4585
4586 memset(cmd, 0, sizeof(struct ethtool_cmd));
4587 cmd->cmd = ETHTOOL_GSET;
4588 return dev->ethtool_ops->get_settings(dev, cmd);
4589}
4590EXPORT_SYMBOL(dev_ethtool_get_settings);
4591
4592/**
4593 * dev_get_flags - get flags reported to userspace 4569 * dev_get_flags - get flags reported to userspace
4594 * @dev: device 4570 * @dev: device
4595 * 4571 *
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 6cdba5fc2bed..f44481707124 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -569,15 +569,25 @@ int __ethtool_set_flags(struct net_device *dev, u32 data)
569 return 0; 569 return 0;
570} 570}
571 571
572static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) 572int __ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
573{ 573{
574 struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; 574 ASSERT_RTNL();
575 int err;
576 575
577 if (!dev->ethtool_ops->get_settings) 576 if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
578 return -EOPNOTSUPP; 577 return -EOPNOTSUPP;
579 578
580 err = dev->ethtool_ops->get_settings(dev, &cmd); 579 memset(cmd, 0, sizeof(struct ethtool_cmd));
580 cmd->cmd = ETHTOOL_GSET;
581 return dev->ethtool_ops->get_settings(dev, cmd);
582}
583EXPORT_SYMBOL(__ethtool_get_settings);
584
585static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
586{
587 int err;
588 struct ethtool_cmd cmd;
589
590 err = __ethtool_get_settings(dev, &cmd);
581 if (err < 0) 591 if (err < 0)
582 return err; 592 return err;
583 593
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 56e42ab7cbc6..7604a635376b 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -147,7 +147,7 @@ static ssize_t show_speed(struct device *dev,
147 147
148 if (netif_running(netdev)) { 148 if (netif_running(netdev)) {
149 struct ethtool_cmd cmd; 149 struct ethtool_cmd cmd;
150 if (!dev_ethtool_get_settings(netdev, &cmd)) 150 if (!__ethtool_get_settings(netdev, &cmd))
151 ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd)); 151 ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd));
152 } 152 }
153 rtnl_unlock(); 153 rtnl_unlock();
@@ -165,7 +165,7 @@ static ssize_t show_duplex(struct device *dev,
165 165
166 if (netif_running(netdev)) { 166 if (netif_running(netdev)) {
167 struct ethtool_cmd cmd; 167 struct ethtool_cmd cmd;
168 if (!dev_ethtool_get_settings(netdev, &cmd)) 168 if (!__ethtool_get_settings(netdev, &cmd))
169 ret = sprintf(buf, "%s\n", 169 ret = sprintf(buf, "%s\n",
170 cmd.duplex ? "full" : "half"); 170 cmd.duplex ? "full" : "half");
171 } 171 }