diff options
author | Jiri Pirko <jpirko@redhat.com> | 2011-09-02 23:34:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-15 17:32:26 -0400 |
commit | 4bc71cb983fd2844e603bf633df2bb53385182d2 (patch) | |
tree | 067b6df32fda6c554b2b9263a94a585c2e5a832d /net/core | |
parent | c5dac7c9984d8a034eb7ae149cedf23ec9259f98 (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.c | 24 | ||||
-rw-r--r-- | net/core/ethtool.c | 20 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 4 |
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 | */ | ||
4580 | int 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 | } | ||
4590 | EXPORT_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 | ||
572 | static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) | 572 | int __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 | } | ||
583 | EXPORT_SYMBOL(__ethtool_get_settings); | ||
584 | |||
585 | static 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 | } |