summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Decotigny <decot@google.com>2011-04-27 18:32:38 +0000
committerDavid S. Miller <davem@davemloft.net>2011-04-29 14:01:30 -0700
commit8ae6daca85c8bbd6a32c382db5e2a2a989f8bed2 (patch)
tree0c85476c2af6568c3d3a73a960d582d2f91a1256 /drivers
parent36504605432996590f889e33d47e2d9c581f7569 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/e100.c2
-rw-r--r--drivers/net/mdio.c3
-rw-r--r--drivers/net/mii.c3
-rw-r--r--drivers/net/pch_gbe/pch_gbe_main.c6
-rw-r--r--drivers/net/pch_gbe/pch_gbe_phy.c2
-rw-r--r--drivers/net/pcnet32.c16
-rw-r--r--drivers/net/sfc/mdio_10g.c4
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c5
-rw-r--r--drivers/net/usb/asix.c28
-rw-r--r--drivers/net/usb/dm9601.c6
-rw-r--r--drivers/net/usb/smsc75xx.c7
-rw-r--r--drivers/net/usb/smsc95xx.c7
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c11
-rw-r--r--drivers/scsi/fcoe/fcoe.c11
14 files changed, 63 insertions, 48 deletions
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)
static void e100_watchdog(unsigned long data)
{
struct nic *nic = (struct nic *)data;
- struct ethtool_cmd cmd;
+ struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
netif_printk(nic, timer, KERN_DEBUG, nic->netdev,
"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)
* @npage_adv: Modes currently advertised on next pages
* @npage_lpa: Modes advertised by link partner on next pages
*
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mdio45_ethtool_gset_npage().
+ *
* Since the CSRs for auto-negotiation using next pages are not fully
* standardised, this function does not attempt to decode them. The
* 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)
* @mii: MII interface
* @ecmd: requested ethtool_cmd
*
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mii_ethtool_gset().
+ *
* Returns 0 for success, negative on error.
*/
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)
struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data;
struct net_device *netdev = adapter->netdev;
struct pch_gbe_hw *hw = &adapter->hw;
- struct ethtool_cmd cmd;
pr_debug("right now = %ld\n", jiffies);
pch_gbe_update_stats(adapter);
if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {
+ struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
netdev->tx_queue_len = adapter->tx_queue_len;
/* mii library handles link maintenance tasks */
if (mii_ethtool_gset(&adapter->mii, &cmd)) {
@@ -903,7 +903,7 @@ static void pch_gbe_watchdog(unsigned long data)
PCH_GBE_WATCHDOG_PERIOD));
return;
}
- hw->mac.link_speed = cmd.speed;
+ hw->mac.link_speed = ethtool_cmd_speed(&cmd);
hw->mac.link_duplex = cmd.duplex;
/* Set the RGMII control. */
pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
@@ -913,7 +913,7 @@ static void pch_gbe_watchdog(unsigned long data)
hw->mac.link_duplex);
netdev_dbg(netdev,
"Link is Up %d Mbps %s-Duplex\n",
- cmd.speed,
+ hw->mac.link_speed,
cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
netif_carrier_on(netdev);
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)
void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
{
struct pch_gbe_adapter *adapter;
- struct ethtool_cmd cmd;
+ struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
int ret;
u16 mii_reg;
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)
int first_phy = -1;
u16 bmcr;
u32 bcr9;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
/*
* There is really no good other way to handle multiple PHYs
@@ -2115,9 +2115,9 @@ static int pcnet32_open(struct net_device *dev)
ecmd.port = PORT_MII;
ecmd.transceiver = XCVR_INTERNAL;
ecmd.autoneg = AUTONEG_DISABLE;
- ecmd.speed =
- lp->
- options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
+ ethtool_cmd_speed_set(&ecmd,
+ (lp->options & PCNET32_PORT_100) ?
+ SPEED_100 : SPEED_10);
bcr9 = lp->a.read_bcr(ioaddr, 9);
if (lp->options & PCNET32_PORT_FD) {
@@ -2763,11 +2763,11 @@ static void pcnet32_check_media(struct net_device *dev, int verbose)
netif_carrier_on(dev);
if (lp->mii) {
if (netif_msg_link(lp)) {
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = {
+ .cmd = ETHTOOL_GSET };
mii_ethtool_gset(&lp->mii_if, &ecmd);
- netdev_info(dev, "link up, %sMbps, %s-duplex\n",
- (ecmd.speed == SPEED_100)
- ? "100" : "10",
+ netdev_info(dev, "link up, %uMbps, %s-duplex\n",
+ ethtool_cmd_speed(&ecmd),
(ecmd.duplex == DUPLEX_FULL)
? "full" : "half");
}
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 19e68c26d10..71159145b4b 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -232,12 +232,12 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
*/
int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
{
- struct ethtool_cmd prev;
+ struct ethtool_cmd prev = { .cmd = ETHTOOL_GSET };
efx->phy_op->get_settings(efx, &prev);
if (ecmd->advertising == prev.advertising &&
- ecmd->speed == prev.speed &&
+ ethtool_cmd_speed(ecmd) == ethtool_cmd_speed(&prev) &&
ecmd->duplex == prev.duplex &&
ecmd->port == prev.port &&
ecmd->autoneg == prev.autoneg)
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index 0e61ac8707c..6f5aaeb986f 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -237,13 +237,12 @@ stmmac_set_pauseparam(struct net_device *netdev,
if (phy->autoneg) {
if (netif_running(netdev)) {
- struct ethtool_cmd cmd;
+ struct ethtool_cmd cmd = { .cmd = ETHTOOL_SSET };
/* auto-negotiation automatically restarted */
- cmd.cmd = ETHTOOL_NWAY_RST;
cmd.supported = phy->supported;
cmd.advertising = phy->advertising;
cmd.autoneg = phy->autoneg;
- cmd.speed = phy->speed;
+ ethtool_cmd_speed_set(&cmd, phy->speed);
cmd.duplex = phy->duplex;
cmd.phy_address = phy->addr;
ret = phy_ethtool_sset(phy, &cmd);
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 6140b56cce5..6998aa6b7bb 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -847,7 +847,7 @@ static void ax88172_set_multicast(struct net_device *net)
static int ax88172_link_reset(struct usbnet *dev)
{
u8 mode;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
@@ -856,8 +856,8 @@ static int ax88172_link_reset(struct usbnet *dev)
if (ecmd.duplex != DUPLEX_FULL)
mode |= ~AX88172_MEDIUM_FD;
- netdev_dbg(dev->net, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
- ecmd.speed, ecmd.duplex, mode);
+ netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
asix_write_medium_mode(dev, mode);
@@ -947,20 +947,20 @@ static const struct ethtool_ops ax88772_ethtool_ops = {
static int ax88772_link_reset(struct usbnet *dev)
{
u16 mode;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
mode = AX88772_MEDIUM_DEFAULT;
- if (ecmd.speed != SPEED_100)
+ if (ethtool_cmd_speed(&ecmd) != SPEED_100)
mode &= ~AX_MEDIUM_PS;
if (ecmd.duplex != DUPLEX_FULL)
mode &= ~AX_MEDIUM_FD;
- netdev_dbg(dev->net, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
- ecmd.speed, ecmd.duplex, mode);
+ netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
asix_write_medium_mode(dev, mode);
@@ -1173,18 +1173,20 @@ static int marvell_led_status(struct usbnet *dev, u16 speed)
static int ax88178_link_reset(struct usbnet *dev)
{
u16 mode;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
struct asix_data *data = (struct asix_data *)&dev->data;
+ u32 speed;
netdev_dbg(dev->net, "ax88178_link_reset()\n");
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
mode = AX88178_MEDIUM_DEFAULT;
+ speed = ethtool_cmd_speed(&ecmd);
- if (ecmd.speed == SPEED_1000)
+ if (speed == SPEED_1000)
mode |= AX_MEDIUM_GM;
- else if (ecmd.speed == SPEED_100)
+ else if (speed == SPEED_100)
mode |= AX_MEDIUM_PS;
else
mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
@@ -1196,13 +1198,13 @@ static int ax88178_link_reset(struct usbnet *dev)
else
mode &= ~AX_MEDIUM_FD;
- netdev_dbg(dev->net, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
- ecmd.speed, ecmd.duplex, mode);
+ netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+ speed, ecmd.duplex, mode);
asix_write_medium_mode(dev, mode);
if (data->phymode == PHY_MODE_MARVELL && data->ledmode)
- marvell_led_status(dev, ecmd.speed);
+ marvell_led_status(dev, speed);
return 0;
}
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 5002f5be47b..1d93133e9b7 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -599,13 +599,13 @@ static void dm9601_status(struct usbnet *dev, struct urb *urb)
static int dm9601_link_reset(struct usbnet *dev)
{
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
mii_check_media(&dev->mii, 1, 1);
mii_ethtool_gset(&dev->mii, &ecmd);
- netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
- ecmd.speed, ecmd.duplex);
+ netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex);
return 0;
}
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 860a20c938b..15b3d6888ae 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -503,7 +503,7 @@ static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
static int smsc75xx_link_reset(struct usbnet *dev)
{
struct mii_if_info *mii = &dev->mii;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
u16 lcladv, rmtadv;
int ret;
@@ -519,8 +519,9 @@ static int smsc75xx_link_reset(struct usbnet *dev)
lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
- netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
- " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+ netif_dbg(dev, link, dev->net, "speed: %u duplex: %d lcladv: %04x"
+ " rmtadv: %04x", ethtool_cmd_speed(&ecmd),
+ ecmd.duplex, lcladv, rmtadv);
return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
}
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 24f4b3739dd..b374a999790 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -457,7 +457,7 @@ static int smsc95xx_link_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
struct mii_if_info *mii = &dev->mii;
- struct ethtool_cmd ecmd;
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
unsigned long flags;
u16 lcladv, rmtadv;
u32 intdata;
@@ -472,8 +472,9 @@ static int smsc95xx_link_reset(struct usbnet *dev)
lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
- netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x\n",
- ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+ netif_dbg(dev, link, dev->net,
+ "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n",
+ ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv);
spin_lock_irqsave(&pdata->mac_cr_lock, flags);
if (ecmd.duplex != DUPLEX_FULL) {
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index e2e647509a7..cd050196a16 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -664,7 +664,7 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
struct fcoe_port *port = lport_priv(lport);
struct bnx2fc_hba *hba = port->priv;
struct net_device *netdev = hba->netdev;
- struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ struct ethtool_cmd ecmd;
if (!dev_ethtool_get_settings(netdev, &ecmd)) {
lport->link_supported_speeds &=
@@ -675,12 +675,15 @@ static void bnx2fc_link_speed_update(struct fc_lport *lport)
if (ecmd.supported & SUPPORTED_10000baseT_Full)
lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
- if (ecmd.speed == SPEED_1000)
+ switch (ethtool_cmd_speed(&ecmd)) {
+ case SPEED_1000:
lport->link_speed = FC_PORTSPEED_1GBIT;
- if (ecmd.speed == SPEED_10000)
+ break;
+ case SPEED_10000:
lport->link_speed = FC_PORTSPEED_10GBIT;
+ break;
+ }
}
- return;
}
static int bnx2fc_link_ok(struct fc_lport *lport)
{
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index bde6ee5333e..04f346b562d 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -2026,7 +2026,7 @@ out_nodev:
int fcoe_link_speed_update(struct fc_lport *lport)
{
struct net_device *netdev = fcoe_netdev(lport);
- struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ struct ethtool_cmd ecmd;
if (!dev_ethtool_get_settings(netdev, &ecmd)) {
lport->link_supported_speeds &=
@@ -2037,11 +2037,14 @@ int fcoe_link_speed_update(struct fc_lport *lport)
if (ecmd.supported & SUPPORTED_10000baseT_Full)
lport->link_supported_speeds |=
FC_PORTSPEED_10GBIT;
- if (ecmd.speed == SPEED_1000)
+ switch (ethtool_cmd_speed(&ecmd)) {
+ case SPEED_1000:
lport->link_speed = FC_PORTSPEED_1GBIT;
- if (ecmd.speed == SPEED_10000)
+ break;
+ case SPEED_10000:
lport->link_speed = FC_PORTSPEED_10GBIT;
-
+ break;
+ }
return 0;
}
return -1;