diff options
| author | David Decotigny <decot@google.com> | 2011-04-27 14:32:38 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-04-29 17:01:30 -0400 |
| commit | 8ae6daca85c8bbd6a32c382db5e2a2a989f8bed2 (patch) | |
| tree | 0c85476c2af6568c3d3a73a960d582d2f91a1256 | |
| parent | 36504605432996590f889e33d47e2d9c581f7569 (diff) | |
ethtool: Call ethtool's get/set_settings callbacks with cleaned data
This makes sure that when a driver calls the ethtool's
get/set_settings() callback of another driver, the data passed to it
is clean. This guarantees that speed_hi will be zeroed correctly if
the called callback doesn't explicitely set it: we are sure we don't
get a corrupted speed from the underlying driver. We also take care of
setting the cmd field appropriately (ETHTOOL_GSET/SSET).
This applies to dev_ethtool_get_settings(), which now makes sure it
sets up that ethtool command parameter correctly before passing it to
drivers. This also means that whoever calls dev_ethtool_get_settings()
does not have to clean the ethtool command parameter. This function
also becomes an exported symbol instead of an inline.
All drivers visible to make allyesconfig under x86_64 have been
updated.
Signed-off-by: David Decotigny <decot@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | arch/mips/txx9/generic/setup_tx4939.c | 21 | ||||
| -rw-r--r-- | drivers/net/e100.c | 2 | ||||
| -rw-r--r-- | drivers/net/mdio.c | 3 | ||||
| -rw-r--r-- | drivers/net/mii.c | 3 | ||||
| -rw-r--r-- | drivers/net/pch_gbe/pch_gbe_main.c | 6 | ||||
| -rw-r--r-- | drivers/net/pch_gbe/pch_gbe_phy.c | 2 | ||||
| -rw-r--r-- | drivers/net/pcnet32.c | 16 | ||||
| -rw-r--r-- | drivers/net/sfc/mdio_10g.c | 4 | ||||
| -rw-r--r-- | drivers/net/stmmac/stmmac_ethtool.c | 5 | ||||
| -rw-r--r-- | drivers/net/usb/asix.c | 28 | ||||
| -rw-r--r-- | drivers/net/usb/dm9601.c | 6 | ||||
| -rw-r--r-- | drivers/net/usb/smsc75xx.c | 7 | ||||
| -rw-r--r-- | drivers/net/usb/smsc95xx.c | 7 | ||||
| -rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 11 | ||||
| -rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 11 | ||||
| -rw-r--r-- | include/linux/ethtool.h | 4 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 9 | ||||
| -rw-r--r-- | include/rdma/ib_addr.h | 13 | ||||
| -rw-r--r-- | net/core/dev.c | 24 | ||||
| -rw-r--r-- | net/core/net-sysfs.c | 24 |
20 files changed, 117 insertions, 89 deletions
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index 3dc19f48295..e9f95dcde37 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c | |||
| @@ -318,19 +318,15 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask) | |||
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) | 320 | #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) |
| 321 | static int tx4939_get_eth_speed(struct net_device *dev) | 321 | static u32 tx4939_get_eth_speed(struct net_device *dev) |
| 322 | { | 322 | { |
| 323 | struct ethtool_cmd cmd = { ETHTOOL_GSET }; | 323 | struct ethtool_cmd cmd; |
| 324 | int speed = 100; /* default 100Mbps */ | 324 | if (dev_ethtool_get_settings(dev, &cmd)) |
| 325 | int err; | 325 | return 100; /* default 100Mbps */ |
| 326 | if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings) | 326 | |
| 327 | return speed; | 327 | return ethtool_cmd_speed(&cmd); |
| 328 | err = dev->ethtool_ops->get_settings(dev, &cmd); | ||
| 329 | if (err < 0) | ||
| 330 | return speed; | ||
| 331 | speed = cmd.speed == SPEED_100 ? 100 : 10; | ||
| 332 | return speed; | ||
| 333 | } | 328 | } |
| 329 | |||
| 334 | static int tx4939_netdev_event(struct notifier_block *this, | 330 | static int tx4939_netdev_event(struct notifier_block *this, |
| 335 | unsigned long event, | 331 | unsigned long event, |
| 336 | void *ptr) | 332 | void *ptr) |
| @@ -343,8 +339,7 @@ static int tx4939_netdev_event(struct notifier_block *this, | |||
| 343 | else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1)) | 339 | else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1)) |
| 344 | bit = TX4939_PCFG_SPEED1; | 340 | bit = TX4939_PCFG_SPEED1; |
| 345 | if (bit) { | 341 | if (bit) { |
| 346 | int speed = tx4939_get_eth_speed(dev); | 342 | if (tx4939_get_eth_speed(dev) == 100) |
| 347 | if (speed == 100) | ||
| 348 | txx9_set64(&tx4939_ccfgptr->pcfg, bit); | 343 | txx9_set64(&tx4939_ccfgptr->pcfg, bit); |
| 349 | else | 344 | else |
| 350 | txx9_clear64(&tx4939_ccfgptr->pcfg, bit); | 345 | txx9_clear64(&tx4939_ccfgptr->pcfg, bit); |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index b0aa9e68990..66ba596a4d3 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
| @@ -1668,7 +1668,7 @@ static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex) | |||
| 1668 | static void e100_watchdog(unsigned long data) | 1668 | static void e100_watchdog(unsigned long data) |
| 1669 | { | 1669 | { |
| 1670 | struct nic *nic = (struct nic *)data; | 1670 | struct nic *nic = (struct nic *)data; |
| 1671 | struct ethtool_cmd cmd; | 1671 | struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; |
| 1672 | 1672 | ||
| 1673 | netif_printk(nic, timer, KERN_DEBUG, nic->netdev, | 1673 | netif_printk(nic, timer, KERN_DEBUG, nic->netdev, |
| 1674 | "right now = %ld\n", jiffies); | 1674 | "right now = %ld\n", jiffies); |
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index e85bf04cf81..f2d10abd040 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c | |||
| @@ -176,6 +176,9 @@ static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr) | |||
| 176 | * @npage_adv: Modes currently advertised on next pages | 176 | * @npage_adv: Modes currently advertised on next pages |
| 177 | * @npage_lpa: Modes advertised by link partner on next pages | 177 | * @npage_lpa: Modes advertised by link partner on next pages |
| 178 | * | 178 | * |
| 179 | * The @ecmd parameter is expected to have been cleared before calling | ||
| 180 | * mdio45_ethtool_gset_npage(). | ||
| 181 | * | ||
| 179 | * Since the CSRs for auto-negotiation using next pages are not fully | 182 | * Since the CSRs for auto-negotiation using next pages are not fully |
| 180 | * standardised, this function does not attempt to decode them. The | 183 | * standardised, this function does not attempt to decode them. The |
| 181 | * caller must pass them in. | 184 | * caller must pass them in. |
diff --git a/drivers/net/mii.c b/drivers/net/mii.c index 0a6c6a2e755..05acca78f63 100644 --- a/drivers/net/mii.c +++ b/drivers/net/mii.c | |||
| @@ -58,6 +58,9 @@ static u32 mii_get_an(struct mii_if_info *mii, u16 addr) | |||
| 58 | * @mii: MII interface | 58 | * @mii: MII interface |
| 59 | * @ecmd: requested ethtool_cmd | 59 | * @ecmd: requested ethtool_cmd |
| 60 | * | 60 | * |
| 61 | * The @ecmd parameter is expected to have been cleared before calling | ||
| 62 | * mii_ethtool_gset(). | ||
| 63 | * | ||
| 61 | * Returns 0 for success, negative on error. | 64 | * Returns 0 for success, negative on error. |
| 62 | */ | 65 | */ |
| 63 | int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) | 66 | int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) |
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 4cc9872f5ec..f3e4b0adae9 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c | |||
| @@ -888,12 +888,12 @@ static void pch_gbe_watchdog(unsigned long data) | |||
| 888 | struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data; | 888 | struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data; |
| 889 | struct net_device *netdev = adapter->netdev; | 889 | struct net_device *netdev = adapter->netdev; |
| 890 | struct pch_gbe_hw *hw = &adapter->hw; | 890 | struct pch_gbe_hw *hw = &adapter->hw; |
| 891 | struct ethtool_cmd cmd; | ||
| 892 | 891 | ||
| 893 | pr_debug("right now = %ld\n", jiffies); | 892 | pr_debug("right now = %ld\n", jiffies); |
| 894 | 893 | ||
| 895 | pch_gbe_update_stats(adapter); | 894 | pch_gbe_update_stats(adapter); |
| 896 | if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) { | 895 | if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) { |
| 896 | struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; | ||
| 897 | netdev->tx_queue_len = adapter->tx_queue_len; | 897 | netdev->tx_queue_len = adapter->tx_queue_len; |
| 898 | /* mii library handles link maintenance tasks */ | 898 | /* mii library handles link maintenance tasks */ |
| 899 | if (mii_ethtool_gset(&adapter->mii, &cmd)) { | 899 | if (mii_ethtool_gset(&adapter->mii, &cmd)) { |
| @@ -903,7 +903,7 @@ static void pch_gbe_watchdog(unsigned long data) | |||
| 903 | PCH_GBE_WATCHDOG_PERIOD)); | 903 | PCH_GBE_WATCHDOG_PERIOD)); |
| 904 | return; | 904 | return; |
| 905 | } | 905 | } |
| 906 | hw->mac.link_speed = cmd.speed; | 906 | hw->mac.link_speed = ethtool_cmd_speed(&cmd); |
| 907 | hw->mac.link_duplex = cmd.duplex; | 907 | hw->mac.link_duplex = cmd.duplex; |
| 908 | /* Set the RGMII control. */ | 908 | /* Set the RGMII control. */ |
| 909 | pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, | 909 | pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, |
| @@ -913,7 +913,7 @@ static void pch_gbe_watchdog(unsigned long data) | |||
| 913 | hw->mac.link_duplex); | 913 | hw->mac.link_duplex); |
| 914 | netdev_dbg(netdev, | 914 | netdev_dbg(netdev, |
| 915 | "Link is Up %d Mbps %s-Duplex\n", | 915 | "Link is Up %d Mbps %s-Duplex\n", |
| 916 | cmd.speed, | 916 | hw->mac.link_speed, |
| 917 | cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); | 917 | cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); |
| 918 | netif_carrier_on(netdev); | 918 | netif_carrier_on(netdev); |
| 919 | netif_wake_queue(netdev); | 919 | netif_wake_queue(netdev); |
diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c index 923a687acd3..9a8207f686f 100644 --- a/drivers/net/pch_gbe/pch_gbe_phy.c +++ b/drivers/net/pch_gbe/pch_gbe_phy.c | |||
| @@ -247,7 +247,7 @@ inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw) | |||
| 247 | void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw) | 247 | void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw) |
| 248 | { | 248 | { |
| 249 | struct pch_gbe_adapter *adapter; | 249 | struct pch_gbe_adapter *adapter; |
| 250 | struct ethtool_cmd cmd; | 250 | struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; |
| 251 | int ret; | 251 | int ret; |
| 252 | u16 mii_reg; | 252 | u16 mii_reg; |
| 253 | 253 | ||
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 0a1efbae1bc..b48aba9e422 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
| @@ -2099,7 +2099,7 @@ static int pcnet32_open(struct net_device *dev) | |||
| 2099 | int first_phy = -1; | 2099 | int first_phy = -1; |
| 2100 | u16 bmcr; | 2100 | u16 bmcr; |
| 2101 | u32 bcr9; | 2101 | u32 bcr9; |
| 2102 | struct ethtool_cmd ecmd; | 2102 | struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; |
| 2103 | 2103 | ||
| 2104 | /* | 2104 | /* |
| 2105 | * There is really no good other way to handle multiple PHYs | 2105 | * There is really no good other way to handle multiple PHYs |
| @@ -2115,9 +2115,9 @@ static int pcnet32_open(struct net_device *dev) | |||
| 2115 | ecmd.port = PORT_MII; | 2115 | ecmd.port = PORT_MII; |
| 2116 | ecmd.transceiver = XCVR_INTERNAL; | 2116 | ecmd.transceiver = XCVR_INTERNAL; |
| 2117 | ecmd.autoneg = AUTONEG_DISABLE; | 2117 | ecmd.autoneg = AUTONEG_DISABLE; |
| 2118 | ecmd.speed = | 2118 | ethtool_cmd_speed_set(&ecmd, |
| 2119 | lp-> | 2119 | (lp->options & PCNET32_PORT_100) ? |
