Netdev List
 help / color / mirror / Atom feed
* [PATCH] net: ibm_newemac: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev

Side effect: allow toggling of TX offloads.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/ibm_newemac/core.c |   17 ++++-------------
 1 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 3bb990b..079450f 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2053,13 +2053,6 @@ static void emac_ethtool_get_pauseparam(struct net_device *ndev,
 	mutex_unlock(&dev->link_lock);
 }
 
-static u32 emac_ethtool_get_rx_csum(struct net_device *ndev)
-{
-	struct emac_instance *dev = netdev_priv(ndev);
-
-	return dev->tah_dev != NULL;
-}
-
 static int emac_get_regs_len(struct emac_instance *dev)
 {
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
@@ -2203,15 +2196,11 @@ static const struct ethtool_ops emac_ethtool_ops = {
 	.get_ringparam = emac_ethtool_get_ringparam,
 	.get_pauseparam = emac_ethtool_get_pauseparam,
 
-	.get_rx_csum = emac_ethtool_get_rx_csum,
-
 	.get_strings = emac_ethtool_get_strings,
 	.get_sset_count = emac_ethtool_get_sset_count,
 	.get_ethtool_stats = emac_ethtool_get_ethtool_stats,
 
 	.get_link = ethtool_op_get_link,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 };
 
 static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
@@ -2859,8 +2848,10 @@ static int __devinit emac_probe(struct platform_device *ofdev)
 	if (err != 0)
 		goto err_detach_tah;
 
-	if (dev->tah_dev)
-		ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+	if (dev->tah_dev) {
+		ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
+		ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
+	}
 	ndev->watchdog_timeo = 5 * HZ;
 	if (emac_phy_supports_gige(dev->phy_mode)) {
 		ndev->netdev_ops = &emac_gige_netdev_ops;
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: greth: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: Kristoffer Glembo

Note: Driver modifies its struct net_device_ops. This will break if used for
multiple devices that are not all the same (if that HW config is possible).

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/greth.c |   46 ++++------------------------------------------
 drivers/net/greth.h |    4 ----
 2 files changed, 4 insertions(+), 46 deletions(-)

diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 396ff7d..f181304 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -901,7 +901,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
 
 				skb_put(skb, pkt_len);
 
-				if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status))
+				if (dev->features & NETIF_F_RXCSUM && hw_checksummed(status))
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
 				else
 					skb_checksum_none_assert(skb);
@@ -1142,41 +1142,6 @@ static void greth_get_regs(struct net_device *dev, struct ethtool_regs *regs, vo
 		buff[i] = greth_read_bd(&greth_regs[i]);
 }
 
-static u32 greth_get_rx_csum(struct net_device *dev)
-{
-	struct greth_private *greth = netdev_priv(dev);
-	return (greth->flags & GRETH_FLAG_RX_CSUM) != 0;
-}
-
-static int greth_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct greth_private *greth = netdev_priv(dev);
-
-	spin_lock_bh(&greth->devlock);
-
-	if (data)
-		greth->flags |= GRETH_FLAG_RX_CSUM;
-	else
-		greth->flags &= ~GRETH_FLAG_RX_CSUM;
-
-	spin_unlock_bh(&greth->devlock);
-
-	return 0;
-}
-
-static u32 greth_get_tx_csum(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int greth_set_tx_csum(struct net_device *dev, u32 data)
-{
-	netif_tx_lock_bh(dev);
-	ethtool_op_set_tx_csum(dev, data);
-	netif_tx_unlock_bh(dev);
-	return 0;
-}
-
 static const struct ethtool_ops greth_ethtool_ops = {
 	.get_msglevel		= greth_get_msglevel,
 	.set_msglevel		= greth_set_msglevel,
@@ -1185,10 +1150,6 @@ static const struct ethtool_ops greth_ethtool_ops = {
 	.get_drvinfo		= greth_get_drvinfo,
 	.get_regs_len           = greth_get_regs_len,
 	.get_regs               = greth_get_regs,
-	.get_rx_csum		= greth_get_rx_csum,
-	.set_rx_csum		= greth_set_rx_csum,
-	.get_tx_csum		= greth_get_tx_csum,
-	.set_tx_csum		= greth_set_tx_csum,
 	.get_link		= ethtool_op_get_link,
 };
 
@@ -1570,9 +1531,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev)
 	GRETH_REGSAVE(regs->status, 0xFF);
 
 	if (greth->gbit_mac) {
-		dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HIGHDMA;
+		dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_RXCSUM;
+		dev->features = dev->hw_features | NETIF_F_HIGHDMA;
 		greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit;
-		greth->flags = GRETH_FLAG_RX_CSUM;
 	}
 
 	if (greth->multicast) {
diff --git a/drivers/net/greth.h b/drivers/net/greth.h
index be0f206..9a0040d 100644
--- a/drivers/net/greth.h
+++ b/drivers/net/greth.h
@@ -77,9 +77,6 @@
  */
 #define MAX_FRAME_SIZE		1520
 
-/* Flags */
-#define GRETH_FLAG_RX_CSUM 0x1
-
 /* GRETH APB registers */
 struct greth_regs {
 	u32 control;
@@ -133,7 +130,6 @@ struct greth_private {
 	unsigned int duplex;
 
 	u32 msg_enable;
-	u32 flags;
 
 	u8 phyaddr;
 	u8 multicast;
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: typhoon: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: David Dillow

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/typhoon.c |   39 ++++++++-------------------------------
 1 files changed, 8 insertions(+), 31 deletions(-)

diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 82653cb..119c394 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1144,28 +1144,6 @@ typhoon_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 	return 0;
 }
 
-static u32
-typhoon_get_rx_csum(struct net_device *dev)
-{
-	/* For now, we don't allow turning off RX checksums.
-	 */
-	return 1;
-}
-
-static int
-typhoon_set_flags(struct net_device *dev, u32 data)
-{
-	/* There's no way to turn off the RX VLAN offloading and stripping
-	 * on the current 3XP firmware -- it does not respect the offload
-	 * settings -- so we only allow the user to toggle the TX processing.
-	 */
-	if (!(data & ETH_FLAG_RXVLAN))
-		return -EINVAL;
-
-	return ethtool_op_set_flags(dev, data,
-				    ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
-}
-
 static void
 typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
@@ -1187,13 +1165,7 @@ static const struct ethtool_ops typhoon_ethtool_ops = {
 	.get_wol		= typhoon_get_wol,
 	.set_wol		= typhoon_set_wol,
 	.get_link		= ethtool_op_get_link,
-	.get_rx_csum		= typhoon_get_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum,
-	.set_sg			= ethtool_op_set_sg,
-	.set_tso		= ethtool_op_set_tso,
 	.get_ringparam		= typhoon_get_ringparam,
-	.set_flags		= typhoon_set_flags,
-	.get_flags		= ethtool_op_get_flags,
 };
 
 static int
@@ -2482,10 +2454,15 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	/* We can handle scatter gather, up to 16 entries, and
 	 * we can do IP checksumming (only version 4, doh...)
+	 *
+	 * There's no way to turn off the RX VLAN offloading and stripping
+	 * on the current 3XP firmware -- it does not respect the offload
+	 * settings -- so we only allow the user to toggle the TX processing.
 	 */
-	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->features |= NETIF_F_TSO;
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+		NETIF_F_HW_VLAN_TX;
+	dev->features = dev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM;
 
 	if(register_netdev(dev) < 0) {
 		err_msg = "unable to register netdev";
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: niu: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev

Side effect: allow toggling of TX offloads.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/niu.c |   11 ++---------
 1 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index ea2272f..a707217 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -7913,11 +7913,6 @@ static int niu_set_phys_id(struct net_device *dev,
 	return 0;
 }
 
-static int niu_set_flags(struct net_device *dev, u32 data)
-{
-	return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH);
-}
-
 static const struct ethtool_ops niu_ethtool_ops = {
 	.get_drvinfo		= niu_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
@@ -7934,8 +7929,6 @@ static const struct ethtool_ops niu_ethtool_ops = {
 	.set_phys_id		= niu_set_phys_id,
 	.get_rxnfc		= niu_get_nfc,
 	.set_rxnfc		= niu_set_nfc,
-	.set_flags		= niu_set_flags,
-	.get_flags		= ethtool_op_get_flags,
 };
 
 static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,
@@ -9764,8 +9757,8 @@ static void __devinit niu_device_announce(struct niu *np)
 
 static void __devinit niu_set_basic_features(struct net_device *dev)
 {
-	dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM |
-			  NETIF_F_GRO | NETIF_F_RXHASH);
+	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXHASH;
+	dev->features |= dev->hw_features | NETIF_F_RXCSUM;
 }
 
 static int __devinit niu_pci_init_one(struct pci_dev *pdev,
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: benet: convert to hw_features - fixup
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: Sathya Perla, Subbu Seetharaman, Ajit Khaparde

Remove be_set_flags() as it's already covered by hw_features.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/benet/be_ethtool.c |   13 -------------
 1 files changed, 0 insertions(+), 13 deletions(-)

diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 80226e4..ab7ebdd 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -716,18 +716,6 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
 	return status;
 }
 
-static int be_set_flags(struct net_device *netdev, u32 data)
-{
-	struct be_adapter *adapter = netdev_priv(netdev);
-	int rc = -1;
-
-	if (be_multi_rxq(adapter))
-		rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXHASH |
-				ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN);
-
-	return rc;
-}
-
 const struct ethtool_ops be_ethtool_ops = {
 	.get_settings = be_get_settings,
 	.get_drvinfo = be_get_drvinfo,
@@ -749,5 +737,4 @@ const struct ethtool_ops be_ethtool_ops = {
 	.get_regs = be_get_regs,
 	.flash_device = be_do_flash,
 	.self_test = be_self_test,
-	.set_flags = be_set_flags,
 };
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: ehea: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: Breno Leitao

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/ehea/ehea_ethtool.c |   23 -----------------------
 drivers/net/ehea/ehea_main.c    |    4 +++-
 2 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index 3e2e734..5f13491 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -162,11 +162,6 @@ static void ehea_set_msglevel(struct net_device *dev, u32 value)
 	port->msg_enable = value;
 }
 
-static u32 ehea_get_rx_csum(struct net_device *dev)
-{
-	return 1;
-}
-
 static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = {
 	{"sig_comp_iv"},
 	{"swqe_refill_th"},
@@ -263,34 +258,16 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
 
 }
 
-static int ehea_set_flags(struct net_device *dev, u32 data)
-{
-	/* Avoid changing the VLAN flags */
-	if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) !=
-	    (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN |
-					  ETH_FLAG_TXVLAN))){
-		return -EINVAL;
-	}
-
-	return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
-					| ETH_FLAG_TXVLAN
-					| ETH_FLAG_RXVLAN);
-}
-
 const struct ethtool_ops ehea_ethtool_ops = {
 	.get_settings = ehea_get_settings,
 	.get_drvinfo = ehea_get_drvinfo,
 	.get_msglevel = ehea_get_msglevel,
 	.set_msglevel = ehea_set_msglevel,
 	.get_link = ethtool_op_get_link,
-	.set_tso = ethtool_op_set_tso,
 	.get_strings = ehea_get_strings,
 	.get_sset_count = ehea_get_sset_count,
 	.get_ethtool_stats = ehea_get_ethtool_stats,
-	.get_rx_csum = ehea_get_rx_csum,
 	.set_settings = ehea_set_settings,
-	.get_flags = ethtool_op_get_flags,
-	.set_flags = ehea_set_flags,
 	.nway_reset = ehea_nway_reset,		/* Restart autonegotiation */
 };
 
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index f75d314..ce2f0ca 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -3262,10 +3262,12 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 	dev->netdev_ops = &ehea_netdev_ops;
 	ehea_set_ethtool_ops(dev);
 
+	dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
+		      | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_LRO;
 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
 		      | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
 		      | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
-		      | NETIF_F_LLTX;
+		      | NETIF_F_LLTX | NETIF_F_RXCSUM;
 	dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
 	if (use_lro)
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: chelsio: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev

Also remove flags that were not used or are now redundant to hw_features bits.
No device had UDP_CSUM_CAPABLE set.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/chelsio/common.h |    5 ----
 drivers/net/chelsio/cxgb2.c  |   48 ++++++-----------------------------------
 drivers/net/chelsio/sge.c    |   12 +++++-----
 drivers/net/chelsio/tp.c     |    5 ----
 drivers/net/chelsio/tp.h     |    1 -
 5 files changed, 13 insertions(+), 58 deletions(-)

diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index 092f31a..c26d863 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -264,11 +264,6 @@ struct adapter {
 
 enum {                                           /* adapter flags */
 	FULL_INIT_DONE        = 1 << 0,
-	TSO_CAPABLE           = 1 << 2,
-	TCP_CSUM_CAPABLE      = 1 << 3,
-	UDP_CSUM_CAPABLE      = 1 << 4,
-	VLAN_ACCEL_CAPABLE    = 1 << 5,
-	RX_CSUM_ENABLED       = 1 << 6,
 };
 
 struct mdio_ops;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 0f71304..5f82c9c 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -192,10 +192,8 @@ static void link_start(struct port_info *p)
 
 static void enable_hw_csum(struct adapter *adapter)
 {
-	if (adapter->flags & TSO_CAPABLE)
+	if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
 		t1_tp_set_ip_checksum_offload(adapter->tp, 1);	/* for TSO only */
-	if (adapter->flags & UDP_CSUM_CAPABLE)
-		t1_tp_set_udp_checksum_offload(adapter->tp, 1);
 	t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
 }
 
@@ -705,33 +703,6 @@ static int set_pauseparam(struct net_device *dev,
 	return 0;
 }
 
-static u32 get_rx_csum(struct net_device *dev)
-{
-	struct adapter *adapter = dev->ml_priv;
-
-	return (adapter->flags & RX_CSUM_ENABLED) != 0;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct adapter *adapter = dev->ml_priv;
-
-	if (data)
-		adapter->flags |= RX_CSUM_ENABLED;
-	else
-		adapter->flags &= ~RX_CSUM_ENABLED;
-	return 0;
-}
-
-static int set_tso(struct net_device *dev, u32 value)
-{
-	struct adapter *adapter = dev->ml_priv;
-
-	if (!(adapter->flags & TSO_CAPABLE))
-		return value ? -EOPNOTSUPP : 0;
-	return ethtool_op_set_tso(dev, value);
-}
-
 static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
 	struct adapter *adapter = dev->ml_priv;
@@ -831,17 +802,12 @@ static const struct ethtool_ops t1_ethtool_ops = {
 	.get_eeprom        = get_eeprom,
 	.get_pauseparam    = get_pauseparam,
 	.set_pauseparam    = set_pauseparam,
-	.get_rx_csum       = get_rx_csum,
-	.set_rx_csum       = set_rx_csum,
-	.set_tx_csum       = ethtool_op_set_tx_csum,
-	.set_sg            = ethtool_op_set_sg,
 	.get_link          = ethtool_op_get_link,
 	.get_strings       = get_strings,
 	.get_sset_count	   = get_sset_count,
 	.get_ethtool_stats = get_stats,
 	.get_regs_len      = get_regs_len,
 	.get_regs          = get_regs,
-	.set_tso           = set_tso,
 };
 
 static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
@@ -1105,28 +1071,28 @@ static int __devinit init_one(struct pci_dev *pdev,
 		netdev->mem_start = mmio_start;
 		netdev->mem_end = mmio_start + mmio_len - 1;
 		netdev->ml_priv = adapter;
-		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-		netdev->features |= NETIF_F_LLTX;
+		netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_RXCSUM;
+		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_RXCSUM | NETIF_F_LLTX;
 
-		adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
 		if (pci_using_dac)
 			netdev->features |= NETIF_F_HIGHDMA;
 		if (vlan_tso_capable(adapter)) {
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-			adapter->flags |= VLAN_ACCEL_CAPABLE;
 			netdev->features |=
 				NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 #endif
 
 			/* T204: disable TSO */
 			if (!(is_T2(adapter)) || bi->port_number != 4) {
-				adapter->flags |= TSO_CAPABLE;
+				netdev->hw_features |= NETIF_F_TSO;
 				netdev->features |= NETIF_F_TSO;
 			}
 		}
 
 		netdev->netdev_ops = &cxgb_netdev_ops;
-		netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
+		netdev->hard_header_len += (netdev->hw_features & NETIF_F_TSO) ?
 			sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
 
 		netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 8754d44..f225528 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -929,7 +929,7 @@ void t1_sge_intr_enable(struct sge *sge)
 	u32 en = SGE_INT_ENABLE;
 	u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
 
-	if (sge->adapter->flags & TSO_CAPABLE)
+	if (sge->adapter->port[0].dev->hw_features & NETIF_F_TSO)
 		en &= ~F_PACKET_TOO_BIG;
 	writel(en, sge->adapter->regs + A_SG_INT_ENABLE);
 	writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
@@ -952,7 +952,7 @@ int t1_sge_intr_error_handler(struct sge *sge)
 	struct adapter *adapter = sge->adapter;
 	u32 cause = readl(adapter->regs + A_SG_INT_CAUSE);
 
-	if (adapter->flags & TSO_CAPABLE)
+	if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
 		cause &= ~F_PACKET_TOO_BIG;
 	if (cause & F_RESPQ_EXHAUSTED)
 		sge->stats.respQ_empty++;
@@ -1369,6 +1369,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
 	const struct cpl_rx_pkt *p;
 	struct adapter *adapter = sge->adapter;
 	struct sge_port_stats *st;
+	struct net_device *dev = adapter->port[p->iff].dev;
 
 	skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad);
 	if (unlikely(!skb)) {
@@ -1385,8 +1386,8 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
 
 	st = this_cpu_ptr(sge->port_stats[p->iff]);
 
-	skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
-	if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
+	skb->protocol = eth_type_trans(skb, dev);
+	if ((dev->features & NETIF_F_RXCSUM) && p->csum == 0xffff &&
 	    skb->protocol == htons(ETH_P_IP) &&
 	    (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
 		++st->rx_cso_good;
@@ -1838,8 +1839,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			return NETDEV_TX_OK;
 		}
 
-		if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
-		    skb->ip_summed == CHECKSUM_PARTIAL &&
+		if (skb->ip_summed == CHECKSUM_PARTIAL &&
 		    ip_hdr(skb)->protocol == IPPROTO_UDP) {
 			if (unlikely(skb_checksum_help(skb))) {
 				pr_debug("%s: unable to do udp checksum\n", dev->name);
diff --git a/drivers/net/chelsio/tp.c b/drivers/net/chelsio/tp.c
index 6222d58..8bed4a5 100644
--- a/drivers/net/chelsio/tp.c
+++ b/drivers/net/chelsio/tp.c
@@ -152,11 +152,6 @@ void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable)
 	set_csum_offload(tp, F_IP_CSUM, enable);
 }
 
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable)
-{
-	set_csum_offload(tp, F_UDP_CSUM, enable);
-}
-
 void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable)
 {
 	set_csum_offload(tp, F_TCP_CSUM, enable);
diff --git a/drivers/net/chelsio/tp.h b/drivers/net/chelsio/tp.h
index 32fc71e..dfd8ce2 100644
--- a/drivers/net/chelsio/tp.h
+++ b/drivers/net/chelsio/tp.h
@@ -65,7 +65,6 @@ void t1_tp_intr_clear(struct petp *tp);
 int t1_tp_intr_handler(struct petp *tp);
 
 void t1_tp_get_mib_statistics(adapter_t *adap, struct tp_mib_statistics *tps);
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable);
 void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable);
 void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable);
 int t1_tp_set_coalescing_size(struct petp *tp, unsigned int size);
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: cxgb3: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: Divy Le Ray

This removes some of the remnants of LRO -> GRO conversion.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/cxgb3/adapter.h    |    7 ----
 drivers/net/cxgb3/common.h     |    1 -
 drivers/net/cxgb3/cxgb3_main.c |   78 +++++++---------------------------------
 drivers/net/cxgb3/sge.c        |    7 ++--
 4 files changed, 17 insertions(+), 76 deletions(-)

diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index ef67be5..7300de5 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -50,11 +50,6 @@ struct adapter;
 struct sge_qset;
 struct port_info;
 
-enum {			/* rx_offload flags */
-	T3_RX_CSUM	= 1 << 0,
-	T3_LRO		= 1 << 1,
-};
-
 enum mac_idx_types {
 	LAN_MAC_IDX	= 0,
 	SAN_MAC_IDX,
@@ -74,7 +69,6 @@ struct port_info {
 	struct vlan_group *vlan_grp;
 	struct sge_qset *qs;
 	u8 port_id;
-	u8 rx_offload;
 	u8 nqsets;
 	u8 first_qset;
 	struct cphy phy;
@@ -212,7 +206,6 @@ struct sge_qset {		/* an SGE queue set */
 	struct sge_fl fl[SGE_RXQ_PER_SET];
 	struct sge_txq txq[SGE_TXQ_PER_SET];
 	int nomem;
-	int lro_enabled;
 	void *lro_va;
 	struct net_device *netdev;
 	struct netdev_queue *tx_q;	/* associated netdev TX queue */
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 5ccb77d..056ee8c 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -317,7 +317,6 @@ struct tp_params {
 
 struct qset_params {		/* SGE queue set parameters */
 	unsigned int polling;	/* polling/interrupt service for rspq */
-	unsigned int lro;	/* large receive offload */
 	unsigned int coalesce_usecs;	/* irq coalescing timer */
 	unsigned int rspq_size;	/* # of entries in response queue */
 	unsigned int fl_size;	/* # of entries in regular free list */
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index a087e06..0404918 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -644,26 +644,6 @@ static void enable_all_napi(struct adapter *adap)
 }
 
 /**
- *	set_qset_lro - Turn a queue set's LRO capability on and off
- *	@dev: the device the qset is attached to
- *	@qset_idx: the queue set index
- *	@val: the LRO switch
- *
- *	Sets LRO on or off for a particular queue set.
- *	the device's features flag is updated to reflect the LRO
- *	capability when all queues belonging to the device are
- *	in the same state.
- */
-static void set_qset_lro(struct net_device *dev, int qset_idx, int val)
-{
-	struct port_info *pi = netdev_priv(dev);
-	struct adapter *adapter = pi->adapter;
-
-	adapter->params.sge.qset[qset_idx].lro = !!val;
-	adapter->sge.qs[qset_idx].lro_enabled = !!val;
-}
-
-/**
  *	setup_sge_qsets - configure SGE Tx/Rx/response queues
  *	@adap: the adapter
  *
@@ -685,7 +665,6 @@ static int setup_sge_qsets(struct adapter *adap)
 
 		pi->qs = &adap->sge.qs[pi->first_qset];
 		for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
-			set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO);
 			err = t3_sge_alloc_qset(adap, qset_idx, 1,
 				(adap->flags & USING_MSIX) ? qset_idx + 1 :
 							     irq_idx,
@@ -1910,29 +1889,6 @@ static int set_pauseparam(struct net_device *dev,
 	return 0;
 }
 
-static u32 get_rx_csum(struct net_device *dev)
-{
-	struct port_info *p = netdev_priv(dev);
-
-	return p->rx_offload & T3_RX_CSUM;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct port_info *p = netdev_priv(dev);
-
-	if (data) {
-		p->rx_offload |= T3_RX_CSUM;
-	} else {
-		int i;
-
-		p->rx_offload &= ~(T3_RX_CSUM | T3_LRO);
-		for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
-			set_qset_lro(dev, i, 0);
-	}
-	return 0;
-}
-
 static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
 	struct port_info *pi = netdev_priv(dev);
@@ -2104,10 +2060,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
 	.set_eeprom = set_eeprom,
 	.get_pauseparam = get_pauseparam,
 	.set_pauseparam = set_pauseparam,
-	.get_rx_csum = get_rx_csum,
-	.set_rx_csum = set_rx_csum,
-	.set_tx_csum = ethtool_op_set_tx_csum,
-	.set_sg = ethtool_op_set_sg,
 	.get_link = ethtool_op_get_link,
 	.get_strings = get_strings,
 	.set_phys_id = set_phys_id,
@@ -2117,7 +2069,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
 	.get_regs_len = get_regs_len,
 	.get_regs = get_regs,
 	.get_wol = get_wol,
-	.set_tso = ethtool_op_set_tso,
 };
 
 static int in_range(int val, int lo, int hi)
@@ -2165,15 +2116,6 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 			      MAX_RSPQ_ENTRIES))
 			return -EINVAL;
 
-		if ((adapter->flags & FULL_INIT_DONE) && t.lro > 0)
-			for_each_port(adapter, i) {
-				pi = adap2pinfo(adapter, i);
-				if (t.qset_idx >= pi->first_qset &&
-				    t.qset_idx < pi->first_qset + pi->nqsets &&
-				    !(pi->rx_offload & T3_RX_CSUM))
-					return -EINVAL;
-			}
-
 		if ((adapter->flags & FULL_INIT_DONE) &&
 			(t.rspq_size >= 0 || t.fl_size[0] >= 0 ||
 			t.fl_size[1] >= 0 || t.txq_size[0] >= 0 ||
@@ -2234,8 +2176,14 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 				}
 			}
 		}
-		if (t.lro >= 0)
-			set_qset_lro(dev, t.qset_idx, t.lro);
+
+		if (t.lro >= 0) {
+			if (t.lro)
+				dev->wanted_features |= NETIF_F_GRO;
+			else
+				dev->wanted_features &= ~NETIF_F_GRO;
+			netdev_update_features(dev);
+		}
 
 		break;
 	}
@@ -2269,7 +2217,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 		t.fl_size[0] = q->fl_size;
 		t.fl_size[1] = q->jumbo_size;
 		t.polling = q->polling;
-		t.lro = q->lro;
+		t.lro = !!(dev->features & NETIF_F_GRO);
 		t.intr_lat = q->coalesce_usecs;
 		t.cong_thres = q->cong_thres;
 		t.qnum = q1;
@@ -3307,18 +3255,18 @@ static int __devinit init_one(struct pci_dev *pdev,
 		adapter->port[i] = netdev;
 		pi = netdev_priv(netdev);
 		pi->adapter = adapter;
-		pi->rx_offload = T3_RX_CSUM | T3_LRO;
 		pi->port_id = i;
 		netif_carrier_off(netdev);
 		netdev->irq = pdev->irq;
 		netdev->mem_start = mmio_start;
 		netdev->mem_end = mmio_start + mmio_len - 1;
-		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
-		netdev->features |= NETIF_F_GRO;
+		netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_TSO | NETIF_F_RXCSUM;
+		netdev->features |= netdev->hw_features |
+			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 		if (pci_using_dac)
 			netdev->features |= NETIF_F_HIGHDMA;
 
-		netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 		netdev->netdev_ops = &cxgb_netdev_ops;
 		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
 	}
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index bfa2d56..cba1401 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2019,7 +2019,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
 	skb_pull(skb, sizeof(*p) + pad);
 	skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
 	pi = netdev_priv(skb->dev);
-	if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid &&
+	if ((skb->dev->features & NETIF_F_RXCSUM) && p->csum_valid &&
 	    p->csum == htons(0xffff) && !p->fragment) {
 		qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2120,7 +2120,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
 		offset = 2 + sizeof(struct cpl_rx_pkt);
 		cpl = qs->lro_va = sd->pg_chunk.va + 2;
 
-		if ((pi->rx_offload & T3_RX_CSUM) &&
+		if ((qs->netdev->features & NETIF_F_RXCSUM) &&
 		     cpl->csum_valid && cpl->csum == htons(0xffff)) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
@@ -2285,7 +2285,8 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
 	q->next_holdoff = q->holdoff_tmr;
 
 	while (likely(budget_left && is_new_response(r, q))) {
-		int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
+		int packet_complete, eth, ethpad = 2;
+		int lro = !!(qs->netdev->features & NETIF_F_GRO);
 		struct sk_buff *skb = NULL;
 		u32 len, flags;
 		__be32 rss_hi, rss_lo;
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: mv643xx: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: Lennert Buytenhek

Side effect: don't reenable RXCSUM on every ifdown/ifup.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/mv643xx_eth.c |   28 +++++++---------------------
 1 files changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 34425b9..29605a3 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1575,18 +1575,12 @@ mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
 	return 0;
 }
 
-static u32
-mv643xx_eth_get_rx_csum(struct net_device *dev)
-{
-	struct mv643xx_eth_private *mp = netdev_priv(dev);
-
-	return !!(rdlp(mp, PORT_CONFIG) & 0x02000000);
-}
 
 static int
-mv643xx_eth_set_rx_csum(struct net_device *dev, u32 rx_csum)
+mv643xx_eth_set_features(struct net_device *dev, u32 features)
 {
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
+	u32 rx_csum = features & NETIF_F_RXCSUM;
 
 	wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000);
 
@@ -1634,11 +1628,6 @@ static void mv643xx_eth_get_ethtool_stats(struct net_device *dev,
 	}
 }
 
-static int mv643xx_eth_set_flags(struct net_device *dev, u32 data)
-{
-	return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO);
-}
-
 static int mv643xx_eth_get_sset_count(struct net_device *dev, int sset)
 {
 	if (sset == ETH_SS_STATS)
@@ -1657,14 +1646,8 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = {
 	.set_coalesce		= mv643xx_eth_set_coalesce,
 	.get_ringparam		= mv643xx_eth_get_ringparam,
 	.set_ringparam		= mv643xx_eth_set_ringparam,
-	.get_rx_csum		= mv643xx_eth_get_rx_csum,
-	.set_rx_csum		= mv643xx_eth_set_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum,
-	.set_sg			= ethtool_op_set_sg,
 	.get_strings		= mv643xx_eth_get_strings,
 	.get_ethtool_stats	= mv643xx_eth_get_ethtool_stats,
-	.get_flags		= ethtool_op_get_flags,
-	.set_flags		= mv643xx_eth_set_flags,
 	.get_sset_count		= mv643xx_eth_get_sset_count,
 };
 
@@ -2264,7 +2247,7 @@ static void port_start(struct mv643xx_eth_private *mp)
 	 * frames to RX queue #0, and include the pseudo-header when
 	 * calculating receive checksums.
 	 */
-	wrlp(mp, PORT_CONFIG, 0x02000000);
+	mv643xx_eth_set_features(dev, dev->features);
 
 	/*
 	 * Treat BPDUs as normal multicasts, and disable partition mode.
@@ -2848,6 +2831,7 @@ static const struct net_device_ops mv643xx_eth_netdev_ops = {
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= mv643xx_eth_ioctl,
 	.ndo_change_mtu		= mv643xx_eth_change_mtu,
+	.ndo_set_features	= mv643xx_eth_set_features,
 	.ndo_tx_timeout		= mv643xx_eth_tx_timeout,
 	.ndo_get_stats		= mv643xx_eth_get_stats,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2930,7 +2914,9 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 	dev->watchdog_timeo = 2 * HZ;
 	dev->base_addr = 0;
 
-	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+		NETIF_F_RXCSUM | NETIF_F_LRO;
+	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
 	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: tehuti: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: Alexander Indenbaum, Andy Gospodarek

As a side effect, make TX offloads changeable.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/tehuti.c |   26 +++-----------------------
 1 files changed, 3 insertions(+), 23 deletions(-)

diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 8564ec5..8be71de 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -2017,9 +2017,11 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		ndev->irq = pdev->irq;
 		ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO
 		    | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
-		    NETIF_F_HW_VLAN_FILTER
+		    NETIF_F_HW_VLAN_FILTER | NETIF_F_RXCSUM
 		    /*| NETIF_F_FRAGLIST */
 		    ;
+		ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+			NETIF_F_TSO | NETIF_F_HW_VLAN_TX;
 
 		if (pci_using_dac)
 			ndev->features |= NETIF_F_HIGHDMA;
@@ -2188,24 +2190,6 @@ bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 }
 
 /*
- * bdx_get_rx_csum - report whether receive checksums are turned on or off
- * @netdev
- */
-static u32 bdx_get_rx_csum(struct net_device *netdev)
-{
-	return 1;		/* always on */
-}
-
-/*
- * bdx_get_tx_csum - report whether transmit checksums are turned on or off
- * @netdev
- */
-static u32 bdx_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-/*
  * bdx_get_coalesce - get interrupt coalescing parameters
  * @netdev
  * @ecoal
@@ -2424,10 +2408,6 @@ static void bdx_set_ethtool_ops(struct net_device *netdev)
 		.set_coalesce = bdx_set_coalesce,
 		.get_ringparam = bdx_get_ringparam,
 		.set_ringparam = bdx_set_ringparam,
-		.get_rx_csum = bdx_get_rx_csum,
-		.get_tx_csum = bdx_get_tx_csum,
-		.get_sg = ethtool_op_get_sg,
-		.get_tso = ethtool_op_get_tso,
 		.get_strings = bdx_get_strings,
 		.get_sset_count = bdx_get_sset_count,
 		.get_ethtool_stats = bdx_get_ethtool_stats,
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] net: macvlan: convert to hw_features
From: Michał Mirosław @ 2011-04-17 10:15 UTC (permalink / raw)
  To: netdev; +Cc: Patrick McHardy

Not much of a conversion anyway - macvlan has no way to change the offload
settings independently to its base device.

Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
 drivers/net/macvlan.c |   16 +---------------
 1 files changed, 1 insertions(+), 15 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 78e34e9..3ad5425 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -415,7 +415,7 @@ static struct lock_class_key macvlan_netdev_addr_lock_key;
 #define MACVLAN_FEATURES \
 	(NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
 	 NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \
-	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO)
+	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM)
 
 #define MACVLAN_STATE_MASK \
 	((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
@@ -517,12 +517,6 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
 	snprintf(drvinfo->version, 32, "0.1");
 }
 
-static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
-{
-	const struct macvlan_dev *vlan = netdev_priv(dev);
-	return dev_ethtool_get_rx_csum(vlan->lowerdev);
-}
-
 static int macvlan_ethtool_get_settings(struct net_device *dev,
 					struct ethtool_cmd *cmd)
 {
@@ -530,18 +524,10 @@ static int macvlan_ethtool_get_settings(struct net_device *dev,
 	return dev_ethtool_get_settings(vlan->lowerdev, cmd);
 }
 
-static u32 macvlan_ethtool_get_flags(struct net_device *dev)
-{
-	const struct macvlan_dev *vlan = netdev_priv(dev);
-	return dev_ethtool_get_flags(vlan->lowerdev);
-}
-
 static const struct ethtool_ops macvlan_ethtool_ops = {
 	.get_link		= ethtool_op_get_link,
 	.get_settings		= macvlan_ethtool_get_settings,
-	.get_rx_csum		= macvlan_ethtool_get_rx_csum,
 	.get_drvinfo		= macvlan_ethtool_get_drvinfo,
-	.get_flags		= macvlan_ethtool_get_flags,
 };
 
 static const struct net_device_ops macvlan_netdev_ops = {
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH net-2.6] bnx2x: Fix port identification problem
From: Yaniv Rosner @ 2011-04-17  6:35 UTC (permalink / raw)
  To: davem; +Cc: netdev, eilong

This patch fixes port identification on optic devices when there's no link on the port.

Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
 drivers/net/bnx2x/bnx2x_ethtool.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index f505015..89cb977 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -2114,19 +2114,18 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
 	for (i = 0; i < (data * 2); i++) {
 		if ((i % 2) == 0)
 			bnx2x_set_led(&bp->link_params, &bp->link_vars,
-				      LED_MODE_OPER, SPEED_1000);
+				      LED_MODE_ON, SPEED_1000);
 		else
 			bnx2x_set_led(&bp->link_params, &bp->link_vars,
-				      LED_MODE_OFF, 0);
+				      LED_MODE_FRONT_PANEL_OFF, 0);
 
 		msleep_interruptible(500);
 		if (signal_pending(current))
 			break;
 	}
 
-	if (bp->link_vars.link_up)
-		bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER,
-			      bp->link_vars.line_speed);
+	bnx2x_set_led(&bp->link_params, &bp->link_vars,
+		      LED_MODE_OPER, bp->link_vars.line_speed);
 
 	return 0;
 }
-- 
1.7.1







^ permalink raw reply related

* O seu mau crédito
From: smae.inc @ 2011-04-17  6:00 UTC (permalink / raw)


Hello,
  Please contact us for your secure and unsecured Loan at an interest rate of 3.75%
..................
Olá,
  Você está enfrentando alguma dificuldade financeira em sua vida profissional ou social, então você precisa de ajuda financeira.
  Meu nome é Dr. Alli Sallie Mae. O director da SALLIE MAE INTERNACIONAL. O nosso seguro de crédito irá garantir que você não está perdendo um único centavo que você receberá. Oferecemos empréstimos seguro com taxa de juros de 3.75%.
Este é o nosso endereço de contato para os interessados em participar de uma transação com a gente:
smae.inc@gncn.net

(n º de segurança social e sem verificação de crédito, 100% garantido!)
Espero que possamos atendê-lo.
Novamente, obrigado pela sua atenção.

SALLIE MAE INC


^ permalink raw reply

* Re: [PATCH 1/5] ethtool: cosmetics: enforce const-ness in ethtool_cmd_speed
From: Ben Hutchings @ 2011-04-17  2:06 UTC (permalink / raw)
  To: David Decotigny
  Cc: David S. Miller, Michał Mirosław, Stanislaw Gruszka,
	Alexander Duyck, ilon Greenstein, linux-kernel, netdev
In-Reply-To: <1303001651-4074-1-git-send-email-decot@google.com>

On Sat, 2011-04-16 at 17:54 -0700, David Decotigny wrote:
> The 'ep' argument of ethtool_cmd_speed is not altered: advertise it in
> protoype. +Indentation fix. Also add comments to advise using the
> ethtool_cmd_speed API to get/set the link speed.
> 
> Signed-off-by: David Decotigny <decot@google.com>
> ---
>  include/linux/ethtool.h |   14 ++++++++++----
>  1 files changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
> index 9de3127..170439e 100644
> --- a/include/linux/ethtool.h
> +++ b/include/linux/ethtool.h
> @@ -24,7 +24,10 @@ struct ethtool_cmd {
>  	__u32	cmd;
>  	__u32	supported;	/* Features this interface supports */
>  	__u32	advertising;	/* Features this interface advertises */
> -	__u16	speed;		/* The forced speed, 10Mb, 100Mb, gigabit */
> +	__u16	speed;	        /* The forced speed (lower bits): see
> +				 * SPEED_ macros below. Please use
> +				 * ethtool_cmd_speed()/_set() to
> +				 * access it */
[...]

Don't encourage use of the SPEED_* macros.  The speed is just a value in
units of Mbit/s.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH 4/5] ethtool: Use the full 32 bit speed range in ethtool's set_settings
From: Ben Hutchings @ 2011-04-17  2:02 UTC (permalink / raw)
  To: David Decotigny
  Cc: David S. Miller, Michał Mirosław, Stanislaw Gruszka,
	Alexander Duyck, ilon Greenstein, linux-kernel, netdev
In-Reply-To: <1303001651-4074-4-git-send-email-decot@google.com>

On Sat, 2011-04-16 at 17:54 -0700, David Decotigny wrote:
> This makes sure the ethtool's set_settings() callback of network
> drivers don't ignore the 16 most significant bits when ethtool calls
> their set_settings().
> 
> All the driver compiled with make allyesconfig on x86_64 have been
> updated.

You missed one generic function, mdio45_ethtool_gset_npage() in
drivers/net/mdio.c.

[...]
> diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
> index c05db60..ba6c151 100644
> --- a/drivers/net/dl2k.c
> +++ b/drivers/net/dl2k.c
> @@ -1219,11 +1219,11 @@ static int rio_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
>  	} else {
>  		np->an_enable = 0;
>  		if (np->speed == 1000) {
> -			cmd->speed = SPEED_100;
> +			ethtool_cmd_speed_set(cmd, SPEED_100);
>  			cmd->duplex = DUPLEX_FULL;
>  			printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n");
>  		}
> -		switch(cmd->speed + cmd->duplex) {
> +		switch (ethtool_cmd_speed(cmd) + cmd->duplex) {
[...]

If you're going to stop these drivers ignoring speed_hi, maybe you
should also stop them ignoring the difference between speed and duplex!
Currently the user can ask for 99 Mbit/s full-duplex and get 100 Mbit/s
half-duplex.

There are several others that use this trick.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCH 3/5] ethtool: Call ethtool's get/set_settings callbacks with cleaned data
From: Ben Hutchings @ 2011-04-17  1:53 UTC (permalink / raw)
  To: David Decotigny
  Cc: David S. Miller, Michał Mirosław, Stanislaw Gruszka,
	Alexander Duyck, ilon Greenstein, linux-kernel, netdev
In-Reply-To: <1303001651-4074-3-git-send-email-decot@google.com>

On Sat, 2011-04-16 at 17:54 -0700, David Decotigny wrote:
> This makes sure that when a driver calls the ethtool's
> get/set_settings() callback of another driver,

Many of them are calling themselves, and they can ignore speed_hi
because they will never set it.

> 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).

I think this initialisation ought to be done in
dev_ethtool_get_settings(), and that function moved into net/core/dev.c,
to avoid code bloat.  (Yes it's minimal in this case, but these things
add up.)

Maybe also in mii_ethtool_gset().

> All drivers visible to make allyesconfig under x86_64 have been
> updated.
>
> Tested: make allyesconfig compiles + e1000 & bnx2x work
> 
> Signed-off-by: David Decotigny <decot@google.com>
> ---
>  arch/mips/txx9/generic/setup_tx4939.c |   15 ++++--------
>  drivers/net/e100.c                    |   10 +++++---
>  drivers/net/pch_gbe/pch_gbe_main.c    |    6 ++--
>  drivers/net/pch_gbe/pch_gbe_phy.c     |    2 +-
>  drivers/net/pcnet32.c                 |   15 ++++++-----
>  drivers/net/sfc/mdio_10g.c            |    4 +-
>  drivers/net/stmmac/stmmac_ethtool.c   |    4 +-
>  drivers/net/usb/asix.c                |   28 ++++++++++++----------
>  drivers/net/usb/dm9601.c              |    6 ++--
>  drivers/net/usb/smsc75xx.c            |    7 +++--
>  drivers/net/usb/smsc95xx.c            |    7 +++--
>  drivers/scsi/bnx2fc/bnx2fc_fcoe.c     |   36 +++++++++++++++++------------
>  drivers/scsi/fcoe/fcoe.c              |   41 ++++++++++++++++++--------------
>  include/rdma/ib_addr.h                |   15 ++++++-----
>  net/core/net-sysfs.c                  |   24 ++++++++-----------
>  15 files changed, 115 insertions(+), 105 deletions(-)
> 
> diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
> index 3dc19f4..af0588f 100644
> --- a/arch/mips/txx9/generic/setup_tx4939.c
> +++ b/arch/mips/txx9/generic/setup_tx4939.c
> @@ -320,16 +320,11 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
>  #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
>  static int tx4939_get_eth_speed(struct net_device *dev)
>  {
> -	struct ethtool_cmd cmd = { ETHTOOL_GSET };
> -	int speed = 100;	/* default 100Mbps */
> -	int err;
> -	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
> -		return speed;
> -	err = dev->ethtool_ops->get_settings(dev, &cmd);
> -	if (err < 0)
> -		return speed;
> -	speed = cmd.speed == SPEED_100 ? 100 : 10;
> -	return speed;
> +	struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
> +	if (dev_ethtool_get_settings(dev, &cmd))
> +		return 100;	/* default 100Mbps */
> +
> +	return (ethtool_cmd_speed(&cmd) == SPEED_100 ? 100 : 10);

If you're going to rewrite the whole function then at least get rid of
this stupid conditional and return ethtool_cmd_speed(&cmd).

>  }
>  static int tx4939_netdev_event(struct notifier_block *this,
>  			       unsigned long event,
> diff --git a/drivers/net/e100.c b/drivers/net/e100.c
> index b0aa9e6..c810cda 100644
> --- a/drivers/net/e100.c
> +++ b/drivers/net/e100.c

e100 is just getting its own settings and doesn't need to be changed.

[...]
> diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
> index 2ef2f9c..7d4452e 100644
> --- a/drivers/net/pch_gbe/pch_gbe_main.c
> +++ b/drivers/net/pch_gbe/pch_gbe_main.c

Ditto pch_gbe.

[...] 
> diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
> index 0a1efba..07398bc 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,12 @@ 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",
> +					    (ethtool_cmd_speed(&ecmd)
> +					     == SPEED_100) ? "100" : "10",

Just use ethtool_cmd_speed() and %u rather than this conditional.

>  					    (ecmd.duplex == DUPLEX_FULL)
>  					    ? "full" : "half");
>  			}
> diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
> index 19e68c2..7115914 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)

That looks correct.

> diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
> index 0e61ac8..33cf0b1 100644
> --- a/drivers/net/stmmac/stmmac_ethtool.c
> +++ b/drivers/net/stmmac/stmmac_ethtool.c
> @@ -237,13 +237,13 @@ 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;

This line immediately changes cmd.cmd.  The original author is clearly
confused, as the phy_ethtool_sset() ignores cmd.cmd and ETHTOOL_NWAY_RST
does not take any parameters.

I think this whole block should really just be:

			ret = phy_start_aneg(phy);

[...]
> diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
> index e2e6475..6df9540 100644
> --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
> +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
> @@ -664,22 +664,28 @@ 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 };
> -
> -	if (!dev_ethtool_get_settings(netdev, &ecmd)) {
> -		lport->link_supported_speeds &=
> -			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
> -		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
> -				      SUPPORTED_1000baseT_Full))
> -			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
> -		if (ecmd.supported & SUPPORTED_10000baseT_Full)
> -			lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
> -
> -		if (ecmd.speed == SPEED_1000)
> -			lport->link_speed = FC_PORTSPEED_1GBIT;
> -		if (ecmd.speed == SPEED_10000)
> -			lport->link_speed = FC_PORTSPEED_10GBIT;
> +	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
> +
> +	if (dev_ethtool_get_settings(netdev, &ecmd))
> +		return;
> +
> +	lport->link_supported_speeds &=
> +		~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
> +	if (ecmd.supported & (SUPPORTED_1000baseT_Half |
> +			      SUPPORTED_1000baseT_Full))
> +		lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
> +	if (ecmd.supported & SUPPORTED_10000baseT_Full)
> +		lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
> +
> +	switch (ethtool_cmd_speed(&ecmd)) {
> +	case SPEED_1000:
> +		lport->link_speed = FC_PORTSPEED_1GBIT;
> +		break;
> +	case SPEED_10000:
> +		lport->link_speed = FC_PORTSPEED_10GBIT;
> +		break;
>  	}
> +
>  	return;
>  }
>  static int bnx2fc_link_ok(struct fc_lport *lport)

This restructuring looks entirely unnecessary, and obscures the real
change being made.

> diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
> index bde6ee5..ba9e84a 100644
> --- a/drivers/scsi/fcoe/fcoe.c
> +++ b/drivers/scsi/fcoe/fcoe.c
> @@ -2026,25 +2026,30 @@ out_nodev:
>  int fcoe_link_speed_update(struct fc_lport *lport)
>  {
[...]

Ditto here.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* send detail to claim £950.000.00 in our online promo(BMW AUTOMOBILE SPLASH)
From: Sofia Isabel Freire Bernal @ 2011-04-17  0:50 UTC (permalink / raw)




^ permalink raw reply

* [PATCH] acenic: Fix using the specified speed when configuring NIC
From: David Decotigny @ 2011-04-17  0:57 UTC (permalink / raw)
  To: Jes Sorensen, linux-acenic, netdev, linux-kernel; +Cc: David Decotigny

This patch needs review, as I did not test it: I only think something
is weird by looking at the code, but experts must confirm.

This tells the NIC to take the speed specified by ethtool into account
when configuring the NIC, instead of keeping the previous speed.

Signed-off-by: David Decotigny <decot@google.com>
---
 drivers/net/acenic.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index a579899..82260ca 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2720,7 +2720,7 @@ static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		link |= LNK_NEGOTIATE;
 	if (ethtool_cmd_speed(ecmd) != speed) {
 		link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
-		switch (speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case SPEED_1000:
 			link |= LNK_1000MB;
 			break;
-- 
1.7.3.1


^ permalink raw reply related

* Re: [PATCH v3] net: cxgb4{,vf}: convert to hw_features
From: Dimitris Michailidis @ 2011-04-17  0:55 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, Casey Leedom
In-Reply-To: <20110416230508.38A6113A65@rere.qmqm.pl>

Michał Mirosław wrote:
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>

Looks good for both drivers.

Acked-by: Dimitris Michailidis <dm@chelsio.com>

> ---
> v3: cxgb4vf: fix hw/vlan_features values again
> v2: cxgb4: remove now unneeded variable in t4_ethrx_handler()
>     cxgb4vf: fix hw/vlan_features values
> 
>  drivers/net/cxgb4/cxgb4.h          |    6 ---
>  drivers/net/cxgb4/cxgb4_main.c     |   72 ++++++++---------------------------
>  drivers/net/cxgb4/sge.c            |    4 +-
>  drivers/net/cxgb4vf/adapter.h      |    6 ---
>  drivers/net/cxgb4vf/cxgb4vf_main.c |   57 ++++------------------------
>  drivers/net/cxgb4vf/sge.c          |    4 +-
>  6 files changed, 28 insertions(+), 121 deletions(-)
> 
> diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
> index 01d49ea..bc9982a 100644
> --- a/drivers/net/cxgb4/cxgb4.h
> +++ b/drivers/net/cxgb4/cxgb4.h
> @@ -290,7 +290,6 @@ struct port_info {
>  	u8     port_id;
>  	u8     tx_chan;
>  	u8     lport;                 /* associated offload logical port */
> -	u8     rx_offload;            /* CSO, etc */
>  	u8     nqsets;                /* # of qsets */
>  	u8     first_qset;            /* index of first qset */
>  	u8     rss_mode;
> @@ -298,11 +297,6 @@ struct port_info {
>  	u16   *rss;
>  };
>  
> -/* port_info.rx_offload flags */
> -enum {
> -	RX_CSO = 1 << 0,
> -};
> -
>  struct dentry;
>  struct work_struct;
>  
> diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
> index 0af9c9f..bdc868c 100644
> --- a/drivers/net/cxgb4/cxgb4_main.c
> +++ b/drivers/net/cxgb4/cxgb4_main.c
> @@ -1531,24 +1531,6 @@ static int set_pauseparam(struct net_device *dev,
>  	return 0;
>  }
>  
> -static u32 get_rx_csum(struct net_device *dev)
> -{
> -	struct port_info *p = netdev_priv(dev);
> -
> -	return p->rx_offload & RX_CSO;
> -}
> -
> -static int set_rx_csum(struct net_device *dev, u32 data)
> -{
> -	struct port_info *p = netdev_priv(dev);
> -
> -	if (data)
> -		p->rx_offload |= RX_CSO;
> -	else
> -		p->rx_offload &= ~RX_CSO;
> -	return 0;
> -}
> -
>  static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
>  {
>  	const struct port_info *pi = netdev_priv(dev);
> @@ -1870,36 +1852,20 @@ static int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
>  	return err;
>  }
>  
> -#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
> -
> -static int set_tso(struct net_device *dev, u32 value)
> -{
> -	if (value)
> -		dev->features |= TSO_FLAGS;
> -	else
> -		dev->features &= ~TSO_FLAGS;
> -	return 0;
> -}
> -
> -static int set_flags(struct net_device *dev, u32 flags)
> +static int cxgb_set_features(struct net_device *dev, u32 features)
>  {
> +	const struct port_info *pi = netdev_priv(dev);
> +	u32 changed = dev->features ^ features;
>  	int err;
> -	unsigned long old_feat = dev->features;
>  
> -	err = ethtool_op_set_flags(dev, flags, ETH_FLAG_RXHASH |
> -				   ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
> -	if (err)
> -		return err;
> +	if (!(changed & NETIF_F_HW_VLAN_RX))
> +		return 0;
>  
> -	if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) {
> -		const struct port_info *pi = netdev_priv(dev);
> -
> -		err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1,
> -				    -1, -1, -1, !!(flags & ETH_FLAG_RXVLAN),
> -				    true);
> -		if (err)
> -			dev->features = old_feat;
> -	}
> +	err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1,
> +			    -1, -1, -1,
> +			    !!(features & NETIF_F_HW_VLAN_RX), true);
> +	if (unlikely(err))
> +		dev->features = features ^ NETIF_F_HW_VLAN_RX;
>  	return err;
>  }
>  
> @@ -2010,10 +1976,6 @@ static struct ethtool_ops cxgb_ethtool_ops = {
>  	.set_eeprom        = set_eeprom,
>  	.get_pauseparam    = get_pauseparam,
>  	.set_pauseparam    = set_pauseparam,
> -	.get_rx_csum       = get_rx_csum,
> -	.set_rx_csum       = set_rx_csum,
> -	.set_tx_csum       = ethtool_op_set_tx_ipv6_csum,
> -	.set_sg            = ethtool_op_set_sg,
>  	.get_link          = ethtool_op_get_link,
>  	.get_strings       = get_strings,
>  	.set_phys_id       = identify_port,
> @@ -2024,8 +1986,6 @@ static struct ethtool_ops cxgb_ethtool_ops = {
>  	.get_regs          = get_regs,
>  	.get_wol           = get_wol,
>  	.set_wol           = set_wol,
> -	.set_tso           = set_tso,
> -	.set_flags         = set_flags,
>  	.get_rxnfc         = get_rxnfc,
>  	.get_rxfh_indir    = get_rss_table,
>  	.set_rxfh_indir    = set_rss_table,
> @@ -2882,6 +2842,7 @@ static const struct net_device_ops cxgb4_netdev_ops = {
>  	.ndo_get_stats64      = cxgb_get_stats,
>  	.ndo_set_rx_mode      = cxgb_set_rxmode,
>  	.ndo_set_mac_address  = cxgb_set_mac_addr,
> +	.ndo_set_features     = cxgb_set_features,
>  	.ndo_validate_addr    = eth_validate_addr,
>  	.ndo_do_ioctl         = cxgb_ioctl,
>  	.ndo_change_mtu       = cxgb_change_mtu,
> @@ -3564,6 +3525,7 @@ static void free_some_resources(struct adapter *adapter)
>  		t4_fw_bye(adapter, adapter->fn);
>  }
>  
> +#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
>  #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
>  		   NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
>  
> @@ -3665,14 +3627,14 @@ static int __devinit init_one(struct pci_dev *pdev,
>  		pi = netdev_priv(netdev);
>  		pi->adapter = adapter;
>  		pi->xact_addr_filt = -1;
> -		pi->rx_offload = RX_CSO;
>  		pi->port_id = i;
>  		netdev->irq = pdev->irq;
>  
> -		netdev->features |= NETIF_F_SG | TSO_FLAGS;
> -		netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
> -		netdev->features |= NETIF_F_GRO | NETIF_F_RXHASH | highdma;
> -		netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
> +		netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
> +			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> +			NETIF_F_RXCSUM | NETIF_F_RXHASH |
> +			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
> +		netdev->features |= netdev->hw_features | highdma;
>  		netdev->vlan_features = netdev->features & VLAN_FEAT;
>  
>  		netdev->netdev_ops = &cxgb4_netdev_ops;
> diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
> index 311471b..75a4b0f 100644
> --- a/drivers/net/cxgb4/sge.c
> +++ b/drivers/net/cxgb4/sge.c
> @@ -1556,7 +1556,6 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
>  {
>  	bool csum_ok;
>  	struct sk_buff *skb;
> -	struct port_info *pi;
>  	const struct cpl_rx_pkt *pkt;
>  	struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
>  
> @@ -1584,10 +1583,9 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
>  	if (skb->dev->features & NETIF_F_RXHASH)
>  		skb->rxhash = (__force u32)pkt->rsshdr.hash_val;
>  
> -	pi = netdev_priv(skb->dev);
>  	rxq->stats.pkts++;
>  
> -	if (csum_ok && (pi->rx_offload & RX_CSO) &&
> +	if (csum_ok && (q->netdev->features & NETIF_F_RXCSUM) &&
>  	    (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) {
>  		if (!pkt->ip_frag) {
>  			skb->ip_summed = CHECKSUM_UNNECESSARY;
> diff --git a/drivers/net/cxgb4vf/adapter.h b/drivers/net/cxgb4vf/adapter.h
> index 4766b41..4fd821a 100644
> --- a/drivers/net/cxgb4vf/adapter.h
> +++ b/drivers/net/cxgb4vf/adapter.h
> @@ -97,17 +97,11 @@ struct port_info {
>  	u16 rss_size;			/* size of VI's RSS table slice */
>  	u8 pidx;			/* index into adapter port[] */
>  	u8 port_id;			/* physical port ID */
> -	u8 rx_offload;			/* CSO, etc. */
>  	u8 nqsets;			/* # of "Queue Sets" */
>  	u8 first_qset;			/* index of first "Queue Set" */
>  	struct link_config link_cfg;	/* physical port configuration */
>  };
>  
> -/* port_info.rx_offload flags */
> -enum {
> -	RX_CSO = 1 << 0,
> -};
> -
>  /*
>   * Scatter Gather Engine resources for the "adapter".  Our ingress and egress
>   * queues are organized into "Queue Sets" with one ingress and one egress
> diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
> index c662679..8cf9890 100644
> --- a/drivers/net/cxgb4vf/cxgb4vf_main.c
> +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
> @@ -1326,30 +1326,6 @@ static void cxgb4vf_get_pauseparam(struct net_device *dev,
>  }
>  
>  /*
> - * Return whether RX Checksum Offloading is currently enabled for the device.
> - */
> -static u32 cxgb4vf_get_rx_csum(struct net_device *dev)
> -{
> -	struct port_info *pi = netdev_priv(dev);
> -
> -	return (pi->rx_offload & RX_CSO) != 0;
> -}
> -
> -/*
> - * Turn RX Checksum Offloading on or off for the device.
> - */
> -static int cxgb4vf_set_rx_csum(struct net_device *dev, u32 csum)
> -{
> -	struct port_info *pi = netdev_priv(dev);
> -
> -	if (csum)
> -		pi->rx_offload |= RX_CSO;
> -	else
> -		pi->rx_offload &= ~RX_CSO;
> -	return 0;
> -}
> -
> -/*
>   * Identify the port by blinking the port's LED.
>   */
>  static int cxgb4vf_phys_id(struct net_device *dev,
> @@ -1569,18 +1545,6 @@ static void cxgb4vf_get_wol(struct net_device *dev,
>   */
>  #define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
>  
> -/*
> - * Set TCP Segmentation Offloading feature capabilities.
> - */
> -static int cxgb4vf_set_tso(struct net_device *dev, u32 tso)
> -{
> -	if (tso)
> -		dev->features |= TSO_FLAGS;
> -	else
> -		dev->features &= ~TSO_FLAGS;
> -	return 0;
> -}
> -
>  static struct ethtool_ops cxgb4vf_ethtool_ops = {
>  	.get_settings		= cxgb4vf_get_settings,
>  	.get_drvinfo		= cxgb4vf_get_drvinfo,
> @@ -1591,10 +1555,6 @@ static struct ethtool_ops cxgb4vf_ethtool_ops = {
>  	.get_coalesce		= cxgb4vf_get_coalesce,
>  	.set_coalesce		= cxgb4vf_set_coalesce,
>  	.get_pauseparam		= cxgb4vf_get_pauseparam,
> -	.get_rx_csum		= cxgb4vf_get_rx_csum,
> -	.set_rx_csum		= cxgb4vf_set_rx_csum,
> -	.set_tx_csum		= ethtool_op_set_tx_ipv6_csum,
> -	.set_sg			= ethtool_op_set_sg,
>  	.get_link		= ethtool_op_get_link,
>  	.get_strings		= cxgb4vf_get_strings,
>  	.set_phys_id		= cxgb4vf_phys_id,
> @@ -1603,7 +1563,6 @@ static struct ethtool_ops cxgb4vf_ethtool_ops = {
>  	.get_regs_len		= cxgb4vf_get_regs_len,
>  	.get_regs		= cxgb4vf_get_regs,
>  	.get_wol		= cxgb4vf_get_wol,
> -	.set_tso		= cxgb4vf_set_tso,
>  };
>  
>  /*
> @@ -2638,19 +2597,19 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
>  		 * it.
>  		 */
>  		pi->xact_addr_filt = -1;
> -		pi->rx_offload = RX_CSO;
>  		netif_carrier_off(netdev);
>  		netdev->irq = pdev->irq;
>  
> -		netdev->features = (NETIF_F_SG | TSO_FLAGS |
> -				    NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> -				    NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
> -				    NETIF_F_GRO);
> +		netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
> +			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> +			NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM;
> +		netdev->vlan_features = NETIF_F_SG | TSO_FLAGS |
> +			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
> +			NETIF_F_HIGHDMA;
> +		netdev->features = netdev->hw_features |
> +			NETIF_F_HW_VLAN_RX;
>  		if (pci_using_dac)
>  			netdev->features |= NETIF_F_HIGHDMA;
> -		netdev->vlan_features =
> -			(netdev->features &
> -			 ~(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX));
>  
>  #ifdef HAVE_NET_DEVICE_OPS
>  		netdev->netdev_ops = &cxgb4vf_netdev_ops;
> diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c
> index bb65121..5182960 100644
> --- a/drivers/net/cxgb4vf/sge.c
> +++ b/drivers/net/cxgb4vf/sge.c
> @@ -1555,8 +1555,8 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
>  	pi = netdev_priv(skb->dev);
>  	rxq->stats.pkts++;
>  
> -	if (csum_ok && (pi->rx_offload & RX_CSO) && !pkt->err_vec &&
> -	    (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
> +	if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) &&
> +	    !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
>  		if (!pkt->ip_frag)
>  			skb->ip_summed = CHECKSUM_UNNECESSARY;
>  		else {


^ permalink raw reply

* [PATCH 5/5] ethtool: cosmetic: Use the ethtool speed_cmd_speed API
From: David Decotigny @ 2011-04-17  0:54 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, Michał Mirosław,
	Stanislaw Gruszka
  Cc: David Decotigny
In-Reply-To: <1303001651-4074-1-git-send-email-decot@google.com>

This updates the network drivers so that they don't access the
ethtool_cmd::speed field directly, but use ethtoo_cmd_speed()
instead. This is mostly cosmetic (cleanup + consistency).

All the drivers compiled with make allyesconfig ion x86_64 have been
updated.

Tested: make allyesconfig on x86_64 + e1000e/bnx2x work
Signed-off-by: David Decotigny <decot@google.com>
---
 drivers/infiniband/hw/nes/nes_nic.c     |    4 ++--
 drivers/net/3c509.c                     |    2 +-
 drivers/net/acenic.c                    |    8 ++++----
 drivers/net/arm/etherh.c                |    5 +++--
 drivers/net/arm/ks8695net.c             |    7 ++++---
 drivers/net/atl1c/atl1c_ethtool.c       |    4 ++--
 drivers/net/atl1e/atl1e_ethtool.c       |    4 ++--
 drivers/net/atlx/atl1.c                 |    4 ++--
 drivers/net/atlx/atl2.c                 |    4 ++--
 drivers/net/b44.c                       |    6 +++---
 drivers/net/bcm63xx_enet.c              |    3 ++-
 drivers/net/benet/be_ethtool.c          |   10 +++++-----
 drivers/net/bna/bnad_ethtool.c          |    4 ++--
 drivers/net/bnx2.c                      |    7 +++----
 drivers/net/cassini.c                   |   25 ++++++++++++-------------
 drivers/net/chelsio/cxgb2.c             |    4 ++--
 drivers/net/cxgb3/cxgb3_main.c          |    4 ++--
 drivers/net/cxgb4/cxgb4_main.c          |    3 ++-
 drivers/net/cxgb4vf/cxgb4vf_main.c      |    3 ++-
 drivers/net/dl2k.c                      |    4 ++--
 drivers/net/e1000/e1000_ethtool.c       |    4 ++--
 drivers/net/e1000e/ethtool.c            |   12 +++++++-----
 drivers/net/eepro.c                     |    2 +-
 drivers/net/ehea/ehea_ethtool.c         |   23 ++++++++++++++++++-----
 drivers/net/enc28j60.c                  |    2 +-
 drivers/net/enic/enic_main.c            |    4 ++--
 drivers/net/ewrk3.c                     |    2 +-
 drivers/net/forcedeth.c                 |   14 +++++++++-----
 drivers/net/ibmveth.c                   |    2 +-
 drivers/net/igb/igb_ethtool.c           |    8 ++++----
 drivers/net/igbvf/ethtool.c             |    8 ++++----
 drivers/net/ixgb/ixgb_ethtool.c         |    4 ++--
 drivers/net/ixgbe/ixgbe_ethtool.c       |    8 ++++----
 drivers/net/ixgbevf/ethtool.c           |    8 +++++---
 drivers/net/mdio.c                      |   19 +++++++++++--------
 drivers/net/mii.c                       |   15 +++++++++------
 drivers/net/mlx4/en_ethtool.c           |    4 ++--
 drivers/net/mv643xx_eth.c               |    6 +++---
 drivers/net/myri10ge/myri10ge.c         |    2 +-
 drivers/net/natsemi.c                   |    6 +++---
 drivers/net/netxen/netxen_nic_ethtool.c |   10 +++++-----
 drivers/net/niu.c                       |    2 +-
 drivers/net/ns83820.c                   |    8 ++++----
 drivers/net/pch_gbe/pch_gbe_ethtool.c   |    2 +-
 drivers/net/pch_gbe/pch_gbe_phy.c       |    2 +-
 drivers/net/pcmcia/smc91c92_cs.c        |    2 +-
 drivers/net/phy/phy.c                   |    2 +-
 drivers/net/ps3_gelic_net.c             |    8 ++++----
 drivers/net/qla3xxx.c                   |    2 +-
 drivers/net/qlcnic/qlcnic_ethtool.c     |    8 ++++----
 drivers/net/qlge/qlge_ethtool.c         |    2 +-
 drivers/net/r8169.c                     |    2 +-
 drivers/net/s2io.c                      |    4 ++--
 drivers/net/sc92031.c                   |    3 ++-
 drivers/net/sfc/ethtool.c               |    2 +-
 drivers/net/sfc/mcdi_phy.c              |    2 +-
 drivers/net/sfc/tenxpress.c             |    2 +-
 drivers/net/skge.c                      |    2 +-
 drivers/net/sky2.c                      |    4 ++--
 drivers/net/smc911x.c                   |    4 ++--
 drivers/net/smc91x.c                    |    4 ++--
 drivers/net/spider_net_ethtool.c        |    2 +-
 drivers/net/sungem.c                    |    6 +++---
 drivers/net/sunhme.c                    |   13 ++++++-------
 drivers/net/tehuti.c                    |    2 +-
 drivers/net/tg3.c                       |    4 ++--
 drivers/net/tulip/de2104x.c             |    6 +++---
 drivers/net/tulip/uli526x.c             |    6 +++---
 drivers/net/tun.c                       |    2 +-
 drivers/net/typhoon.c                   |    2 +-
 drivers/net/usb/catc.c                  |    2 +-
 drivers/net/usb/rtl8150.c               |   11 ++++++-----
 drivers/net/veth.c                      |    2 +-
 drivers/net/via-velocity.c              |   11 +++++++----
 drivers/net/vmxnet3/vmxnet3_ethtool.c   |    4 ++--
 drivers/net/vxge/vxge-ethtool.c         |    4 ++--
 net/batman-adv/soft-interface.c         |    2 +-
 77 files changed, 229 insertions(+), 195 deletions(-)

diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index e96b8fb..e6eb114 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1521,7 +1521,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
 	et_cmd->maxrxpkt = 511;
 
 	if (nesadapter->OneG_Mode) {
-		et_cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(et_cmd, SPEED_1000);
 		if (phy_type == NES_PHY_TYPE_PUMA_1G) {
 			et_cmd->supported   = SUPPORTED_1000baseT_Full;
 			et_cmd->advertising = ADVERTISED_1000baseT_Full;
@@ -1560,7 +1560,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd
 		et_cmd->advertising = ADVERTISED_10000baseT_Full;
 		et_cmd->phy_address = mac_index;
 	}
-	et_cmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(et_cmd, SPEED_10000);
 	et_cmd->autoneg = AUTONEG_DISABLE;
 	return 0;
 }
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 91abb96..44b28b2 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -1207,7 +1207,7 @@ el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 			ecmd->duplex = DUPLEX_FULL;
 	}
 
-	ecmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(ecmd, SPEED_10);
 	EL3WINDOW(1);
 	return 0;
 }
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 0b4d8d1..a579899 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2658,15 +2658,15 @@ static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
 	link = readl(&regs->GigLnkState);
 	if (link & LNK_1000MB)
-		ecmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(ecmd, SPEED_1000);
 	else {
 		link = readl(&regs->FastLnkState);
 		if (link & LNK_100MB)
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else if (link & LNK_10MB)
-			ecmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 		else
-			ecmd->speed = 0;
+			ethtool_cmd_speed_set(ecmd, 0);
 	}
 	if (link & LNK_FULL_DUPLEX)
 		ecmd->duplex = DUPLEX_FULL;
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 4af235d..e252cd5 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -591,10 +591,11 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
 static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	cmd->supported	= etherh_priv(dev)->supported;
-	cmd->speed	= SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 	cmd->duplex	= DUPLEX_HALF;
 	cmd->port	= dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
-	cmd->autoneg	= dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+	cmd->autoneg	= (dev->flags & IFF_AUTOMEDIA ?
+			   AUTONEG_ENABLE : AUTONEG_DISABLE);
 	return 0;
 }
 
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index aa07657..a7b0caa 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -891,15 +891,16 @@ ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
 			cmd->advertising |= ADVERTISED_Pause;
 		cmd->autoneg = AUTONEG_ENABLE;
 
-		cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(cmd,
+				      (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10);
 		cmd->duplex = (ctrl & WMC_WDS) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		/* auto-negotiation is disabled */
 		cmd->autoneg = AUTONEG_DISABLE;
 
-		cmd->speed = (ctrl & WMC_WANF100) ?
-			SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ?
+					    SPEED_100 : SPEED_10));
 		cmd->duplex = (ctrl & WMC_WANFF) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 	}
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
index b1eceee..7be884d 100644
--- a/drivers/net/atl1c/atl1c_ethtool.c
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -50,13 +50,13 @@ static int atl1c_get_settings(struct net_device *netdev,
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed != SPEED_0) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		if (adapter->link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index 4778374..6269438 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -51,13 +51,13 @@ static int atl1e_get_settings(struct net_device *netdev,
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed != SPEED_0) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		if (adapter->link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index de27e5b..165b898 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -3234,13 +3234,13 @@ static int atl1_get_settings(struct net_device *netdev,
 	if (netif_carrier_ok(adapter->netdev)) {
 		u16 link_speed, link_duplex;
 		atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
-		ecmd->speed = link_speed;
+		ethtool_cmd_speed_set(ecmd, link_speed);
 		if (link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index b75aa29..16249e9 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -1769,13 +1769,13 @@ static int atl2_get_settings(struct net_device *netdev,
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed != SPEED_0) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		if (adapter->link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 909cc4b..a69331e 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1807,8 +1807,8 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	if (bp->flags & B44_FLAG_ADV_100FULL)
 		cmd->advertising |= ADVERTISED_100baseT_Full;
 	cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
-	cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
-		SPEED_100 : SPEED_10;
+	ethtool_cmd_speed_set(cmd, ((bp->flags & B44_FLAG_100_BASE_T) ?
+				    SPEED_100 : SPEED_10));
 	cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
 		DUPLEX_FULL : DUPLEX_HALF;
 	cmd->port = 0;
@@ -1820,7 +1820,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	if (cmd->autoneg == AUTONEG_ENABLE)
 		cmd->advertising |= ADVERTISED_Autoneg;
 	if (!netif_running(dev)){
-		cmd->speed = 0;
+		ethtool_cmd_speed_set(cmd, 0);
 		cmd->duplex = 0xff;
 	}
 	cmd->maxtxpkt = 0;
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index e68ffe6..f1573d4 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -1346,7 +1346,8 @@ static int bcm_enet_get_settings(struct net_device *dev,
 		return phy_ethtool_gset(priv->phydev, cmd);
 	} else {
 		cmd->autoneg = 0;
-		cmd->speed = (priv->force_speed_100) ? SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(cmd, ((priv->force_speed_100)
+					    ? SPEED_100 : SPEED_10));
 		cmd->duplex = (priv->force_duplex_full) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 		cmd->supported = ADVERTISED_10baseT_Half  |
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 80226e4..108f045 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -379,14 +379,14 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 		be_link_status_update(adapter, link_up);
 		/* link_speed is in units of 10 Mbps */
 		if (link_speed) {
-			ecmd->speed = link_speed*10;
+			ethtool_cmd_speed_set(ecmd, link_speed*10);
 		} else {
 			switch (mac_speed) {
 			case PHY_LINK_SPEED_1GBPS:
-				ecmd->speed = SPEED_1000;
+				ethtool_cmd_speed_set(ecmd, SPEED_1000);
 				break;
 			case PHY_LINK_SPEED_10GBPS:
-				ecmd->speed = SPEED_10000;
+				ethtool_cmd_speed_set(ecmd, SPEED_10000);
 				break;
 			}
 		}
@@ -429,14 +429,14 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 		}
 
 		/* Save for future use */
-		adapter->link_speed = ecmd->speed;
+		adapter->link_speed = ethtool_cmd_speed(ecmd);
 		adapter->port_type = ecmd->port;
 		adapter->transceiver = ecmd->transceiver;
 		adapter->autoneg = ecmd->autoneg;
 		dma_free_coherent(&adapter->pdev->dev, phy_cmd.size, phy_cmd.va,
 				  phy_cmd.dma);
 	} else {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->port = adapter->port_type;
 		ecmd->transceiver = adapter->transceiver;
 		ecmd->autoneg = adapter->autoneg;
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c
index ae1e118..3330cd7 100644
--- a/drivers/net/bna/bnad_ethtool.c
+++ b/drivers/net/bna/bnad_ethtool.c
@@ -237,10 +237,10 @@ bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 	cmd->phy_address = 0;
 
 	if (netif_carrier_ok(netdev)) {
-		cmd->speed = SPEED_10000;
+		ethtool_cmd_speed_set(cmd, SPEED_10000);
 		cmd->duplex = DUPLEX_FULL;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 	cmd->transceiver = XCVR_EXTERNAL;
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index e43efd8..1bebdfb 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -6696,17 +6696,16 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	if (bp->autoneg & AUTONEG_SPEED) {
 		cmd->autoneg = AUTONEG_ENABLE;
-	}
-	else {
+	} else {
 		cmd->autoneg = AUTONEG_DISABLE;
 	}
 
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = bp->line_speed;
+		ethtool_cmd_speed_set(cmd, bp->line_speed);
 		cmd->duplex = bp->duplex;
 	}
 	else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 	spin_unlock_bh(&bp->phy_lock);
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index a6c3f8c..22ce03e 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4606,18 +4606,17 @@ static int cas_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	if (bmcr & BMCR_ANENABLE) {
 		cmd->advertising |= ADVERTISED_Autoneg;
 		cmd->autoneg = AUTONEG_ENABLE;
-		cmd->speed = ((speed == 10) ?
-			      SPEED_10 :
-			      ((speed == 1000) ?
-			       SPEED_1000 : SPEED_100));
+		ethtool_cmd_speed_set(cmd, ((speed == 10) ?
+					    SPEED_10 :
+					    ((speed == 1000) ?
+					     SPEED_1000 : SPEED_100)));
 		cmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		cmd->autoneg = AUTONEG_DISABLE;
-		cmd->speed =
-			(bmcr & CAS_BMCR_SPEED1000) ?
-			SPEED_1000 :
-			((bmcr & BMCR_SPEED100) ? SPEED_100:
-			 SPEED_10);
+		ethtool_cmd_speed_set(cmd, ((bmcr & CAS_BMCR_SPEED1000) ?
+					    SPEED_1000 :
+					    ((bmcr & BMCR_SPEED100) ?
+					     SPEED_100 : SPEED_10)));
 		cmd->duplex =
 			(bmcr & BMCR_FULLDPLX) ?
 			DUPLEX_FULL : DUPLEX_HALF;
@@ -4634,14 +4633,14 @@ static int cas_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		 * settings that we configured.
 		 */
 		if (cp->link_cntl & BMCR_ANENABLE) {
-			cmd->speed = 0;
+			ethtool_cmd_speed_set(cmd, 0);
 			cmd->duplex = 0xff;
 		} else {
-			cmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(cmd, SPEED_10);
 			if (cp->link_cntl & BMCR_SPEED100) {
-				cmd->speed = SPEED_100;
+				ethtool_cmd_speed_set(cmd, SPEED_100);
 			} else if (cp->link_cntl & CAS_BMCR_SPEED1000) {
-				cmd->speed = SPEED_1000;
+				ethtool_cmd_speed_set(cmd, SPEED_1000);
 			}
 			cmd->duplex = (cp->link_cntl & BMCR_FULLDPLX)?
 				DUPLEX_FULL : DUPLEX_HALF;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index a2eed0c..7073a1e 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -579,10 +579,10 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	cmd->advertising = p->link_config.advertising;
 
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = p->link_config.speed;
+		ethtool_cmd_speed_set(cmd, p->link_config.speed);
 		cmd->duplex = p->link_config.duplex;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 00469dc..8e94fb4 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1780,10 +1780,10 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	cmd->advertising = p->link_config.advertising;
 
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = p->link_config.speed;
+		ethtool_cmd_speed_set(cmd, p->link_config.speed);
 		cmd->duplex = p->link_config.duplex;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index a49d370..b8ccabb 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -1436,7 +1436,8 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported);
 	cmd->advertising = from_fw_linkcaps(p->port_type,
 					    p->link_cfg.advertising);
-	cmd->speed = netif_carrier_ok(dev) ? p->link_cfg.speed : 0;
+	ethtool_cmd_speed_set(cmd,
+			      netif_carrier_ok(dev) ? p->link_cfg.speed : 0);
 	cmd->duplex = DUPLEX_FULL;
 	cmd->autoneg = p->link_cfg.autoneg;
 	cmd->maxtxpkt = 0;
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index c662679..f8f1d75 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -1167,7 +1167,8 @@ static int cxgb4vf_get_settings(struct net_device *dev,
 
 	cmd->supported = pi->link_cfg.supported;
 	cmd->advertising = pi->link_cfg.advertising;
-	cmd->speed = netif_carrier_ok(dev) ? pi->link_cfg.speed : -1;
+	ethtool_cmd_speed_set(cmd,
+			      netif_carrier_ok(dev) ? pi->link_cfg.speed : -1);
 	cmd->duplex = DUPLEX_FULL;
 
 	cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index ba6c151..d4527a5 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -1189,10 +1189,10 @@ static int rio_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		cmd->transceiver = XCVR_INTERNAL;
 	}
 	if ( np->link_status ) {
-		cmd->speed = np->speed;
+		ethtool_cmd_speed_set(cmd, np->speed);
 		cmd->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 	if ( np->an_enable)
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index a53629d..127fef4 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -158,7 +158,7 @@ static int e1000_get_settings(struct net_device *netdev,
 
 		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
 		                                   &adapter->link_duplex);
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 
 		/* unfortunately FULL_DUPLEX != DUPLEX_FULL
 		 *          and HALF_DUPLEX != DUPLEX_HALF */
@@ -168,7 +168,7 @@ static int e1000_get_settings(struct net_device *netdev,
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 1dd81b2..2f369ed 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -122,6 +122,7 @@ static int e1000_get_settings(struct net_device *netdev,
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	u32 speed;
 
 	if (hw->phy.media_type == e1000_media_type_copper) {
 
@@ -159,23 +160,23 @@ static int e1000_get_settings(struct net_device *netdev,
 		ecmd->transceiver = XCVR_EXTERNAL;
 	}
 
-	ecmd->speed = -1;
+	speed = -1;
 	ecmd->duplex = -1;
 
 	if (netif_running(netdev)) {
 		if (netif_carrier_ok(netdev)) {
-			ecmd->speed = adapter->link_speed;
+			speed = adapter->link_speed;
 			ecmd->duplex = adapter->link_duplex - 1;
 		}
 	} else {
 		u32 status = er32(STATUS);
 		if (status & E1000_STATUS_LU) {
 			if (status & E1000_STATUS_SPEED_1000)
-				ecmd->speed = 1000;
+				speed = SPEED_1000;
 			else if (status & E1000_STATUS_SPEED_100)
-				ecmd->speed = 100;
+				speed = SPEED_100;
 			else
-				ecmd->speed = 10;
+				speed = SPEED_10;
 
 			if (status & E1000_STATUS_FD)
 				ecmd->duplex = DUPLEX_FULL;
@@ -184,6 +185,7 @@ static int e1000_get_settings(struct net_device *netdev,
 		}
 	}
 
+	ethtool_cmd_speed_set(ecmd, speed);
 	ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
 			 hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index eb35951..dfeb006 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1703,7 +1703,7 @@ static int eepro_ethtool_get_settings(struct net_device *dev,
 		cmd->advertising |= ADVERTISED_AUI;
 	}
 
-	cmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 
 	if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
 		cmd->duplex = DUPLEX_FULL;
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c
index 3e2e734..e5ed504 100644
--- a/drivers/net/ehea/ehea_ethtool.c
+++ b/drivers/net/ehea/ehea_ethtool.c
@@ -34,6 +34,7 @@
 static int ehea_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct ehea_port *port = netdev_priv(dev);
+	u32 speed;
 	int ret;
 
 	ret = ehea_sense_port_attr(port);
@@ -43,17 +44,29 @@ static int ehea_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	if (netif_carrier_ok(dev)) {
 		switch (port->port_speed) {
-		case EHEA_SPEED_10M: cmd->speed = SPEED_10; break;
-		case EHEA_SPEED_100M: cmd->speed = SPEED_100; break;
-		case EHEA_SPEED_1G: cmd->speed = SPEED_1000; break;
-		case EHEA_SPEED_10G: cmd->speed = SPEED_10000; break;
+		case EHEA_SPEED_10M:
+			speed = SPEED_10;
+			break;
+		case EHEA_SPEED_100M:
+			speed = SPEED_100;
+			break;
+		case EHEA_SPEED_1G:
+			speed = SPEED_1000;
+			break;
+		case EHEA_SPEED_10G:
+			speed = SPEED_10000;
+			break;
+		default:
+			speed = -1;
+			break; /* BUG */
 		}
 		cmd->duplex = port->full_duplex == 1 ?
 						     DUPLEX_FULL : DUPLEX_HALF;
 	} else {
-		cmd->speed = -1;
+		speed = ~0;
 		cmd->duplex = -1;
 	}
+	ethtool_cmd_speed_set(cmd, speed);
 
 	cmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full
 		       | SUPPORTED_100baseT_Full |  SUPPORTED_100baseT_Half
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index 81a7937..2837ce2 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -1488,7 +1488,7 @@ enc28j60_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	cmd->supported	= SUPPORTED_10baseT_Half
 			| SUPPORTED_10baseT_Full
 			| SUPPORTED_TP;
-	cmd->speed	= SPEED_10;
+	ethtool_cmd_speed_set(cmd,  SPEED_10);
 	cmd->duplex	= priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
 	cmd->port	= PORT_TP;
 	cmd->autoneg	= AUTONEG_DISABLE;
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index b224551..3d99b0f 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -180,10 +180,10 @@ static int enic_get_settings(struct net_device *netdev,
 	ecmd->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(netdev)) {
-		ecmd->speed = vnic_dev_port_speed(enic->vdev);
+		ethtool_cmd_speed_set(ecmd, vnic_dev_port_speed(enic->vdev));
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index 17b6027..b5f6173 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -1545,7 +1545,7 @@ static int ewrk3_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	}
 
 	ecmd->supported |= SUPPORTED_10baseT_Half;
-	ecmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(ecmd, SPEED_10);
 	ecmd->duplex = DUPLEX_HALF;
 	return 0;
 }
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 9ecd33a..e25444d 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -3955,6 +3955,7 @@ static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
 static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct fe_priv *np = netdev_priv(dev);
+	u32 speed;
 	int adv;
 
 	spin_lock_irq(&np->lock);
@@ -3974,23 +3975,26 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	if (netif_carrier_ok(dev)) {
 		switch (np->linkspeed & (NVREG_LINKSPEED_MASK)) {
 		case NVREG_LINKSPEED_10:
-			ecmd->speed = SPEED_10;
+			speed = SPEED_10;
 			break;
 		case NVREG_LINKSPEED_100:
-			ecmd->speed = SPEED_100;
+			speed = SPEED_100;
 			break;
 		case NVREG_LINKSPEED_1000:
-			ecmd->speed = SPEED_1000;
+			speed = SPEED_1000;
+			break;
+		default:
+			speed = -1;
 			break;
 		}
 		ecmd->duplex = DUPLEX_HALF;
 		if (np->duplex)
 			ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		speed = -1;
 		ecmd->duplex = -1;
 	}
-
+	ethtool_cmd_speed_set(ecmd, speed);
 	ecmd->autoneg = np->autoneg;
 
 	ecmd->advertising = ADVERTISED_MII;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 5522d45..2086c90 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -710,7 +710,7 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 				SUPPORTED_FIBRE);
 	cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
 				ADVERTISED_FIBRE);
-	cmd->speed = SPEED_1000;
+	ethtool_cmd_speed_set(cmd, SPEED_1000);
 	cmd->duplex = DUPLEX_FULL;
 	cmd->port = PORT_FIBRE;
 	cmd->phy_address = 0;
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 2cc221b..023aa9b 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -178,11 +178,11 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 
 		if ((status & E1000_STATUS_SPEED_1000) ||
 		    hw->phy.media_type != e1000_media_type_copper)
-			ecmd->speed = SPEED_1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 		else if (status & E1000_STATUS_SPEED_100)
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else
-			ecmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 
 		if ((status & E1000_STATUS_FD) ||
 		    hw->phy.media_type != e1000_media_type_copper)
@@ -190,7 +190,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c
index 1d943aa..112ae15 100644
--- a/drivers/net/igbvf/ethtool.c
+++ b/drivers/net/igbvf/ethtool.c
@@ -90,18 +90,18 @@ static int igbvf_get_settings(struct net_device *netdev,
 	status = er32(STATUS);
 	if (status & E1000_STATUS_LU) {
 		if (status & E1000_STATUS_SPEED_1000)
-			ecmd->speed = 1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 		else if (status & E1000_STATUS_SPEED_100)
-			ecmd->speed = 100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else
-			ecmd->speed = 10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 
 		if (status & E1000_STATUS_FD)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index edb3d7e..5f224c3 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -104,10 +104,10 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 	ecmd->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(adapter->netdev)) {
-		ecmd->speed = SPEED_10000;
+		ethtool_cmd_speed_set(ecmd, SPEED_10000);
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index e1c3576..01ea04c 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -288,20 +288,20 @@ static int ixgbe_get_settings(struct net_device *netdev,
 	if (link_up) {
 		switch (link_speed) {
 		case IXGBE_LINK_SPEED_10GB_FULL:
-			ecmd->speed = SPEED_10000;
+			ethtool_cmd_speed_set(ecmd, SPEED_10000);
 			break;
 		case IXGBE_LINK_SPEED_1GB_FULL:
-			ecmd->speed = SPEED_1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 			break;
 		case IXGBE_LINK_SPEED_100_FULL:
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 			break;
 		default:
 			break;
 		}
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c
index 0563ab2..deee375 100644
--- a/drivers/net/ixgbevf/ethtool.c
+++ b/drivers/net/ixgbevf/ethtool.c
@@ -104,11 +104,13 @@ static int ixgbevf_get_settings(struct net_device *netdev,
 	hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
 
 	if (link_up) {
-		ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
-			       SPEED_10000 : SPEED_1000;
+		ethtool_cmd_speed_set(
+			ecmd,
+			(link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
+			SPEED_10000 : SPEED_1000);
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
index e85bf04..e7dfb80 100644
--- a/drivers/net/mdio.c
+++ b/drivers/net/mdio.c
@@ -287,33 +287,36 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
 		if (modes & (ADVERTISED_10000baseT_Full |
 			     ADVERTISED_10000baseKX4_Full |
 			     ADVERTISED_10000baseKR_Full)) {
-			ecmd->speed = SPEED_10000;
+			ethtool_cmd_speed_set(ecmd, SPEED_10000);
 			ecmd->duplex = DUPLEX_FULL;
 		} else if (modes & (ADVERTISED_1000baseT_Full |
 				    ADVERTISED_1000baseT_Half |
 				    ADVERTISED_1000baseKX_Full)) {
-			ecmd->speed = SPEED_1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 			ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half);
 		} else if (modes & (ADVERTISED_100baseT_Full |
 				    ADVERTISED_100baseT_Half)) {
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 			ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
 		} else {
-			ecmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 			ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
 		}
 	} else {
 		/* Report forced settings */
+		u32 speed;
 		reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
 				      MDIO_CTRL1);
-		ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) *
-			       ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
+		speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1)
+			 * ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
 		ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX ||
-				ecmd->speed == SPEED_10000);
+				speed == SPEED_10000);
+		ethtool_cmd_speed_set(ecmd, speed);
 	}
 
 	/* 10GBASE-T MDI/MDI-X */
-	if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) {
+	if (ecmd->port == PORT_TP
+	    && (ethtool_cmd_speed(ecmd) == SPEED_10000)) {
 		switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
 					MDIO_PMA_10GBT_SWAPPOL)) {
 		case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index cc5a22d..416374e 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -118,22 +118,25 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 
 		if (nego & (ADVERTISED_1000baseT_Full |
 			    ADVERTISED_1000baseT_Half)) {
-			ecmd->speed = SPEED_1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 			ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full);
 		} else if (nego & (ADVERTISED_100baseT_Full |
 				   ADVERTISED_100baseT_Half)) {
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 			ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full);
 		} else {
-			ecmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 			ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full);
 		}
 	} else {
 		ecmd->autoneg = AUTONEG_DISABLE;
 
-		ecmd->speed = ((bmcr & BMCR_SPEED1000 &&
-				(bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 :
-			       (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10);
+		ethtool_cmd_speed_set(ecmd,
+				      ((bmcr & BMCR_SPEED1000 &&
+					(bmcr & BMCR_SPEED100) == 0) ?
+				       SPEED_1000 :
+				       ((bmcr & BMCR_SPEED100) ?
+					SPEED_100 : SPEED_10)));
 		ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
 	}
 
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
index be4a9e0..2e858e4 100644
--- a/drivers/net/mlx4/en_ethtool.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -265,10 +265,10 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	trans_type = priv->port_state.transciver;
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = priv->port_state.link_speed;
+		ethtool_cmd_speed_set(cmd, priv->port_state.link_speed);
 		cmd->duplex = DUPLEX_FULL;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 34425b9..1b031cb 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1444,13 +1444,13 @@ mv643xx_eth_get_settings_phyless(struct mv643xx_eth_private *mp,
 	cmd->advertising = ADVERTISED_MII;
 	switch (port_status & PORT_SPEED_MASK) {
 	case PORT_SPEED_10:
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	case PORT_SPEED_100:
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 		break;
 	case PORT_SPEED_1000:
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 		break;
 	default:
 		cmd->speed = -1;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 1446de5..b32357a 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1645,7 +1645,7 @@ myri10ge_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 	int i;
 
 	cmd->autoneg = AUTONEG_DISABLE;
-	cmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(cmd, SPEED_10000);
 	cmd->duplex = DUPLEX_FULL;
 
 	/*
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index dbe31e9..78572b3 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -2817,7 +2817,7 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 	u32 tmp;
 
 	ecmd->port        = dev->if_port;
-	ecmd->speed       = np->speed;
+	ethtool_cmd_speed_set(ecmd, np->speed);
 	ecmd->duplex      = np->duplex;
 	ecmd->autoneg     = np->autoneg;
 	ecmd->advertising = 0;
@@ -2875,9 +2875,9 @@ static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 		tmp = mii_nway_result(
 			np->advertising & mdio_read(dev, MII_LPA));
 		if (tmp == LPA_100FULL || tmp == LPA_100HALF)
-			ecmd->speed  = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else
-			ecmd->speed  = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 		if (tmp == LPA_100FULL || tmp == LPA_10FULL)
 			ecmd->duplex = DUPLEX_FULL;
 		else
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index e8d16f6..b34fb74 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -117,7 +117,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
 		ecmd->port = PORT_TP;
 
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->duplex = adapter->link_duplex;
 		ecmd->autoneg = adapter->link_autoneg;
 
@@ -134,7 +134,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		}
 
 		if (netif_running(dev) && adapter->has_link_events) {
-			ecmd->speed = adapter->link_speed;
+			ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 			ecmd->autoneg = adapter->link_autoneg;
 			ecmd->duplex = adapter->link_duplex;
 			goto skip;
@@ -146,10 +146,10 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 			u16 pcifn = adapter->ahw.pci_func;
 
 			val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
-			ecmd->speed = P3_LINK_SPEED_MHZ *
-					P3_LINK_SPEED_VAL(pcifn, val);
+			ethtool_cmd_speed_set(ecmd, P3_LINK_SPEED_MHZ *
+					      P3_LINK_SPEED_VAL(pcifn, val));
 		} else
-			ecmd->speed = SPEED_10000;
+			ethtool_cmd_speed_set(ecmd, SPEED_10000);
 
 		ecmd->duplex = DUPLEX_FULL;
 		ecmd->autoneg = AUTONEG_DISABLE;
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 350225f..eff4f8a 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -6844,7 +6844,7 @@ static int niu_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	cmd->supported = lp->supported;
 	cmd->advertising = lp->active_advertising;
 	cmd->autoneg = lp->active_autoneg;
-	cmd->speed = lp->active_speed;
+	ethtool_cmd_speed_set(cmd, lp->active_speed);
 	cmd->duplex = lp->active_duplex;
 	cmd->port = (np->flags & NIU_FLAGS_FIBER) ? PORT_FIBRE : PORT_TP;
 	cmd->transceiver = (np->flags & NIU_FLAGS_XCVR_SERDES) ?
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 6667e06..3e4040f 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1251,7 +1251,7 @@ static int ns83820_get_settings(struct net_device *ndev,
 	/*
 	 * Here's the list of available ethtool commands from other drivers:
 	 *	cmd->advertising =
-	 *	cmd->speed =
+	 *	ethtool_cmd_speed_set(cmd, ...)
 	 *	cmd->duplex =
 	 *	cmd->port = 0;
 	 *	cmd->phy_address =
@@ -1289,13 +1289,13 @@ static int ns83820_get_settings(struct net_device *ndev,
 	cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF;
 	switch (cfg / CFG_SPDSTS0 & 3) {
 	case 2:
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 		break;
 	case 1:
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 		break;
 	default:
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	}
 	cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE)
diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c
index cae1e7f..eb78090 100644
--- a/drivers/net/pch_gbe/pch_gbe_ethtool.c
+++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c
@@ -92,7 +92,7 @@ static int pch_gbe_get_settings(struct net_device *netdev,
 	ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
 
 	if (!netif_carrier_ok(adapter->netdev))
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 	return ret;
 }
 
diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c
index 9a8207f..28bb960 100644
--- a/drivers/net/pch_gbe/pch_gbe_phy.c
+++ b/drivers/net/pch_gbe/pch_gbe_phy.c
@@ -256,7 +256,7 @@ void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
 	if (ret)
 		pr_err("Error: mii_ethtool_gset\n");
 
-	cmd.speed = hw->mac.link_speed;
+	ethtool_cmd_speed_set(&cmd, hw->mac.link_speed);
 	cmd.duplex = hw->mac.link_duplex;
 	cmd.advertising = hw->phy.autoneg_advertised;
 	cmd.autoneg = hw->mac.autoneg;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index bc71cb2..288e4f1 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1860,7 +1860,7 @@ static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
     tmp = inw(ioaddr + CONFIG);
     ecmd->port = (tmp & CFG_AUI_SELECT) ? PORT_AUI : PORT_TP;
     ecmd->transceiver = XCVR_INTERNAL;
-    ecmd->speed = SPEED_10;
+    ethtool_cmd_speed_set(ecmd, SPEED_10);
     ecmd->phy_address = ioaddr + MGMT;
 
     SMC_SELECT_BANK(0);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e3f3501..a475957 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -288,7 +288,7 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 
 	cmd->advertising = phydev->advertising;
 
-	cmd->speed = phydev->speed;
+	ethtool_cmd_speed_set(cmd, phydev->speed);
 	cmd->duplex = phydev->duplex;
 	cmd->port = PORT_MII;
 	cmd->phy_address = phydev->addr;
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 4383ed2..b1f251d 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -1243,17 +1243,17 @@ static int gelic_ether_get_settings(struct net_device *netdev,
 
 	switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) {
 	case GELIC_LV1_ETHER_SPEED_10:
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	case GELIC_LV1_ETHER_SPEED_100:
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 		break;
 	case GELIC_LV1_ETHER_SPEED_1000:
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 		break;
 	default:
 		pr_info("%s: speed unknown\n", __func__);
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	}
 
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index f3f737b..d495a68 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1725,7 +1725,7 @@ static int ql_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
 	}
 	ecmd->advertising = ql_supported_modes(qdev);
 	ecmd->autoneg = ql_get_auto_cfg_status(qdev);
-	ecmd->speed = ql_get_speed(qdev);
+	ethtool_cmd_speed_set(ecmd, ql_get_speed(qdev));
 	ecmd->duplex = ql_get_full_dup(qdev);
 	return 0;
 }
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 9886dfc..4db4115 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -166,7 +166,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 				     ADVERTISED_1000baseT_Half |
 				     ADVERTISED_1000baseT_Full);
 
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->duplex = adapter->link_duplex;
 		ecmd->autoneg = adapter->link_autoneg;
 
@@ -183,15 +183,15 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		}
 
 		if (netif_running(dev) && adapter->has_link_events) {
-			ecmd->speed = adapter->link_speed;
+			ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 			ecmd->autoneg = adapter->link_autoneg;
 			ecmd->duplex = adapter->link_duplex;
 			goto skip;
 		}
 
 		val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
-		ecmd->speed = P3P_LINK_SPEED_MHZ *
-			P3P_LINK_SPEED_VAL(pcifn, val);
+		ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ *
+				      P3P_LINK_SPEED_VAL(pcifn, val));
 		ecmd->duplex = DUPLEX_FULL;
 		ecmd->autoneg = AUTONEG_DISABLE;
 	} else
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 687754d..05b123d 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -356,7 +356,7 @@ static int ql_get_settings(struct net_device *ndev,
 		ecmd->port = PORT_FIBRE;
 	}
 
-	ecmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(ecmd, SPEED_10000);
 	ecmd->duplex = DUPLEX_FULL;
 
 	return 0;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a11e6ca..7a27bb3 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1353,7 +1353,7 @@ static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
 	cmd->advertising = (status & TBINwEnable) ?  ADVERTISED_Autoneg : 0;
 	cmd->autoneg = !!(status & TBINwEnable);
 
-	cmd->speed = SPEED_1000;
+	ethtool_cmd_speed_set(cmd, SPEED_1000);
 	cmd->duplex = DUPLEX_FULL; /* Always set */
 
 	return 0;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 956a139..6cd2fc9 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -5414,10 +5414,10 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
 	info->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(sp->dev)) {
-		info->speed = 10000;
+		ethtool_cmd_speed_set(info, SPEED_10000);
 		info->duplex = DUPLEX_FULL;
 	} else {
-		info->speed = -1;
+		ethtool_cmd_speed_set(info, -1);
 		info->duplex = -1;
 	}
 
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index f3ffc1d..fa74314 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1173,7 +1173,8 @@ static int sc92031_ethtool_get_settings(struct net_device *dev,
 	if (phy_ctrl & PhyCtrlAne)
 		cmd->advertising |= ADVERTISED_Autoneg;
 
-	cmd->speed = (output_status & 0x2) ? SPEED_100 : SPEED_10;
+	ethtool_cmd_speed_set(cmd,
+			      (output_status & 0x2) ? SPEED_100 : SPEED_10);
 	cmd->duplex = (output_status & 0x4) ? DUPLEX_FULL : DUPLEX_HALF;
 	cmd->port = PORT_MII;
 	cmd->phy_address = phy_address;
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 10b160a..8c5e005 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -219,7 +219,7 @@ static int efx_ethtool_get_settings(struct net_device *net_dev,
 	ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 
 	if (LOOPBACK_INTERNAL(efx)) {
-		ecmd->speed = link_state->speed;
+		ethtool_cmd_speed_set(ecmd, link_state->speed);
 		ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
 	}
 
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c
index 6c5fccb..6c63ab0 100644
--- a/drivers/net/sfc/mcdi_phy.c
+++ b/drivers/net/sfc/mcdi_phy.c
@@ -513,7 +513,7 @@ static void efx_mcdi_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *e
 	ecmd->supported =
 		mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap);
 	ecmd->advertising = efx->link_advertising;
-	ecmd->speed = efx->link_state.speed;
+	ethtool_cmd_speed_set(ecmd, efx->link_state.speed);
 	ecmd->duplex = efx->link_state.fd;
 	ecmd->port = mcdi_to_ethtool_media(phy_cfg->media);
 	ecmd->phy_address = phy_cfg->port;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index 204ecda..7b0fd89 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -460,7 +460,7 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 	/* In loopback, the PHY automatically brings up the correct interface,
 	 * but doesn't advertise the correct speed. So override it */
 	if (LOOPBACK_EXTERNAL(efx))
-		ecmd->speed = SPEED_10000;
+		ethtool_cmd_speed_set(ecmd, SPEED_10000);
 }
 
 static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index b0fa999..56a1899 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -303,7 +303,7 @@ static int skge_get_settings(struct net_device *dev,
 
 	ecmd->advertising = skge->advertising;
 	ecmd->autoneg = skge->autoneg;
-	ecmd->speed = skge->speed;
+	ethtool_cmd_speed_set(ecmd, skge->speed);
 	ecmd->duplex = skge->duplex;
 	return 0;
 }
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 40afe07..66f5db6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3413,10 +3413,10 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	ecmd->phy_address = PHY_ADDR_MARV;
 	if (sky2_is_copper(hw)) {
 		ecmd->port = PORT_TP;
-		ecmd->speed = sky2->speed;
+		ethtool_cmd_speed_set(ecmd, sky2->speed);
 		ecmd->supported |=  SUPPORTED_Autoneg | SUPPORTED_TP;
 	} else {
-		ecmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(ecmd, SPEED_1000);
 		ecmd->port = PORT_FIBRE;
 		ecmd->supported |=  SUPPORTED_Autoneg | SUPPORTED_FIBRE;
 	}
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 66831f3..053863a 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1488,9 +1488,9 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
 				SUPPORTED_TP | SUPPORTED_AUI;
 
 		if (lp->ctl_rspeed == 10)
-			cmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(cmd, SPEED_10);
 		else if (lp->ctl_rspeed == 100)
-			cmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(cmd, SPEED_100);
 
 		cmd->autoneg = AUTONEG_DISABLE;
 		if (lp->mii.phy_id==1)
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 43654a3..dc4805f 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1565,9 +1565,9 @@ smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
 				 SUPPORTED_TP | SUPPORTED_AUI;
 
 		if (lp->ctl_rspeed == 10)
-			cmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(cmd, SPEED_10);
 		else if (lp->ctl_rspeed == 100)
-			cmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(cmd, SPEED_100);
 
 		cmd->autoneg = AUTONEG_DISABLE;
 		cmd->transceiver = XCVR_INTERNAL;
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c
index d723fca..9c288cd 100644
--- a/drivers/net/spider_net_ethtool.c
+++ b/drivers/net/spider_net_ethtool.c
@@ -58,7 +58,7 @@ spider_net_ethtool_get_settings(struct net_device *netdev,
 	cmd->advertising = (ADVERTISED_1000baseT_Full |
 			     ADVERTISED_FIBRE);
 	cmd->port = PORT_FIBRE;
-	cmd->speed = card->phy.speed;
+	ethtool_cmd_speed_set(cmd, card->phy.speed);
 	cmd->duplex = DUPLEX_FULL;
 
 	return 0;
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 40a755d..ab59300 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2642,7 +2642,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		/* Return current PHY settings */
 		spin_lock_irq(&gp->lock);
 		cmd->autoneg = gp->want_autoneg;
-		cmd->speed = gp->phy_mii.speed;
+		ethtool_cmd_speed_set(cmd, gp->phy_mii.speed);
 		cmd->duplex = gp->phy_mii.duplex;
 		cmd->advertising = gp->phy_mii.advertising;
 
@@ -2659,7 +2659,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 			 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
 			 SUPPORTED_Autoneg);
 		cmd->advertising = cmd->supported;
-		cmd->speed = 0;
+		ethtool_cmd_speed_set(cmd, 0);
 		cmd->duplex = cmd->port = cmd->phy_address =
 			cmd->transceiver = cmd->autoneg = 0;
 
@@ -2673,7 +2673,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 			cmd->advertising = cmd->supported;
 			cmd->transceiver = XCVR_INTERNAL;
 			if (gp->lstate == link_up)
-				cmd->speed = SPEED_1000;
+				ethtool_cmd_speed_set(cmd, SPEED_1000);
 			cmd->duplex = DUPLEX_FULL;
 			cmd->autoneg = 1;
 		}
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 8f3f028..d381a0f 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2401,6 +2401,7 @@ static void happy_meal_set_multicast(struct net_device *dev)
 static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct happy_meal *hp = netdev_priv(dev);
+	u32 speed;
 
 	cmd->supported =
 		(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -2420,10 +2421,9 @@ static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	if (hp->sw_bmcr & BMCR_ANENABLE) {
 		cmd->autoneg = AUTONEG_ENABLE;
-		cmd->speed =
-			(hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
-			SPEED_100 : SPEED_10;
-		if (cmd->speed == SPEED_100)
+		speed = ((hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
+			 SPEED_100 : SPEED_10);
+		if (speed == SPEED_100)
 			cmd->duplex =
 				(hp->sw_lpa & (LPA_100FULL)) ?
 				DUPLEX_FULL : DUPLEX_HALF;
@@ -2433,13 +2433,12 @@ static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 				DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		cmd->autoneg = AUTONEG_DISABLE;
-		cmd->speed =
-			(hp->sw_bmcr & BMCR_SPEED100) ?
-			SPEED_100 : SPEED_10;
+		speed = (hp->sw_bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
 		cmd->duplex =
 			(hp->sw_bmcr & BMCR_FULLDPLX) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 	}
+	ethtool_cmd_speed_set(cmd, speed);
 	return 0;
 }
 
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 8564ec5..a685df5 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -2149,7 +2149,7 @@ static int bdx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 
 	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
 	ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
-	ecmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(ecmd, SPEED_10000);
 	ecmd->duplex = DUPLEX_FULL;
 	ecmd->port = PORT_FIBRE;
 	ecmd->transceiver = XCVR_EXTERNAL;	/* what does it mean? */
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 0e40af2..e784dd4 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9959,10 +9959,10 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	cmd->advertising = tp->link_config.advertising;
 	if (netif_running(dev)) {
-		cmd->speed = tp->link_config.active_speed;
+		ethtool_cmd_speed_set(cmd, tp->link_config.active_speed);
 		cmd->duplex = tp->link_config.active_duplex;
 	} else {
-		cmd->speed = SPEED_INVALID;
+		ethtool_cmd_speed_set(cmd, SPEED_INVALID);
 		cmd->duplex = DUPLEX_INVALID;
 	}
 	cmd->phy_address = tp->phy_addr;
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index f8d26bf..ab78e1d 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1518,15 +1518,15 @@ static int __de_get_settings(struct de_private *de, struct ethtool_cmd *ecmd)
 	switch (de->media_type) {
 	case DE_MEDIA_AUI:
 		ecmd->port = PORT_AUI;
-		ecmd->speed = 5;
+		ethtool_cmd_speed_set(ecmd, 5);
 		break;
 	case DE_MEDIA_BNC:
 		ecmd->port = PORT_BNC;
-		ecmd->speed = 2;
+		ethtool_cmd_speed_set(ecmd, 2);
 		break;
 	default:
 		ecmd->port = PORT_TP;
-		ecmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(ecmd, SPEED_10);
 		break;
 	}
 
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 74217db..a4375c4 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -945,12 +945,12 @@ ULi_ethtool_gset(struct uli526x_board_info *db, struct ethtool_cmd *ecmd)
 
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	ecmd->speed = 10;
+	ethtool_cmd_speed_set(ecmd, SPEED_10);
 	ecmd->duplex = DUPLEX_HALF;
 
 	if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD)
 	{
-		ecmd->speed = 100;
+		ethtool_cmd_speed_set(ecmd, SPEED_100);
 	}
 	if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
 	{
@@ -958,7 +958,7 @@ ULi_ethtool_gset(struct uli526x_board_info *db, struct ethtool_cmd *ecmd)
 	}
 	if(db->link_failed)
 	{
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index f5e9ac0..7dfeae0 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1548,7 +1548,7 @@ static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	cmd->supported		= 0;
 	cmd->advertising	= 0;
-	cmd->speed		= SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 	cmd->duplex		= DUPLEX_FULL;
 	cmd->port		= PORT_TP;
 	cmd->phy_address	= 0;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index adf5dbc..ed278ba 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1050,7 +1050,7 @@ typhoon_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	/* need to get stats to make these link speed/duplex valid */
 	typhoon_do_get_stats(tp);
-	cmd->speed = tp->speed;
+	ethtool_cmd_speed_set(cmd, tp->speed);
 	cmd->duplex = tp->duplex;
 	cmd->phy_address = 0;
 	cmd->transceiver = XCVR_INTERNAL;
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 97687d3..d7221c4 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -686,7 +686,7 @@ static int catc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_TP;
 	cmd->advertising = ADVERTISED_10baseT_Half | ADVERTISED_TP;
-	cmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 	cmd->duplex = DUPLEX_HALF;
 	cmd->port = PORT_TP; 
 	cmd->phy_address = 0;
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index e85c89c..041fb7d 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -843,10 +843,11 @@ static int rtl8150_get_settings(struct net_device *netdev, struct ethtool_cmd *e
 	get_registers(dev, BMCR, 2, &bmcr);
 	get_registers(dev, ANLP, 2, &lpa);
 	if (bmcr & BMCR_ANENABLE) {
+		u32 speed = ((lpa & (LPA_100HALF | LPA_100FULL)) ?
+			     SPEED_100 : SPEED_10);
+		ethtool_cmd_speed_set(ecmd, speed);
 		ecmd->autoneg = AUTONEG_ENABLE;
-		ecmd->speed = (lpa & (LPA_100HALF | LPA_100FULL)) ?
-			     SPEED_100 : SPEED_10;
-		if (ecmd->speed == SPEED_100)
+		if (speed == SPEED_100)
 			ecmd->duplex = (lpa & LPA_100FULL) ?
 			    DUPLEX_FULL : DUPLEX_HALF;
 		else
@@ -854,8 +855,8 @@ static int rtl8150_get_settings(struct net_device *netdev, struct ethtool_cmd *e
 			    DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		ecmd->autoneg = AUTONEG_DISABLE;
-		ecmd->speed = (bmcr & BMCR_SPEED100) ?
-		    SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(ecmd, ((bmcr & BMCR_SPEED100) ?
+					     SPEED_100 : SPEED_10));
 		ecmd->duplex = (bmcr & BMCR_FULLDPLX) ?
 		    DUPLEX_FULL : DUPLEX_HALF;
 	}
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 6542288..cbe953a 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -52,7 +52,7 @@ static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	cmd->supported		= 0;
 	cmd->advertising	= 0;
-	cmd->speed		= SPEED_10000;
+	ethtool_cmd_speed_set(cmd, SPEED_10000);
 	cmd->duplex		= DUPLEX_FULL;
 	cmd->port		= PORT_TP;
 	cmd->phy_address	= 0;
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 9a8f116..06daa9d 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -3182,7 +3182,8 @@ static void velocity_ethtool_down(struct net_device *dev)
 		pci_set_power_state(vptr->pdev, PCI_D3hot);
 }
 
-static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int velocity_get_settings(struct net_device *dev,
+				 struct ethtool_cmd *cmd)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 	struct mac_regs __iomem *regs = vptr->mac_regs;
@@ -3228,12 +3229,14 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd
 			break;
 		}
 	}
+
 	if (status & VELOCITY_SPEED_1000)
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 	else if (status & VELOCITY_SPEED_100)
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 	else
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
+
 	cmd->autoneg = (status & VELOCITY_AUTONEG_ENABLE) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 	cmd->port = PORT_TP;
 	cmd->transceiver = XCVR_INTERNAL;
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 51f2ef1..9dbe0a4 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -459,10 +459,10 @@ vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 	return 0;
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index ac73246..f88080f 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -59,10 +59,10 @@ static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
 	info->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(dev)) {
-		info->speed = SPEED_10000;
+		ethtool_cmd_speed_set(info, SPEED_10000);
 		info->duplex = DUPLEX_FULL;
 	} else {
-		info->speed = -1;
+		ethtool_cmd_speed_set(info, -1);
 		info->duplex = -1;
 	}
 
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 824e1f6..6c47785 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -640,7 +640,7 @@ static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	cmd->supported = 0;
 	cmd->advertising = 0;
-	cmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 	cmd->duplex = DUPLEX_FULL;
 	cmd->port = PORT_TP;
 	cmd->phy_address = 0;
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH 3/5] ethtool: Call ethtool's get/set_settings callbacks with cleaned data
From: David Decotigny @ 2011-04-17  0:54 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, Michał Mirosław,
	Stanislaw Gruszka
  Cc: David Decotigny
In-Reply-To: <1303001651-4074-1-git-send-email-decot@google.com>

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).

All drivers visible to make allyesconfig under x86_64 have been
updated.

Tested: make allyesconfig compiles + e1000 & bnx2x work

Signed-off-by: David Decotigny <decot@google.com>
---
 arch/mips/txx9/generic/setup_tx4939.c |   15 ++++--------
 drivers/net/e100.c                    |   10 +++++---
 drivers/net/pch_gbe/pch_gbe_main.c    |    6 ++--
 drivers/net/pch_gbe/pch_gbe_phy.c     |    2 +-
 drivers/net/pcnet32.c                 |   15 ++++++-----
 drivers/net/sfc/mdio_10g.c            |    4 +-
 drivers/net/stmmac/stmmac_ethtool.c   |    4 +-
 drivers/net/usb/asix.c                |   28 ++++++++++++----------
 drivers/net/usb/dm9601.c              |    6 ++--
 drivers/net/usb/smsc75xx.c            |    7 +++--
 drivers/net/usb/smsc95xx.c            |    7 +++--
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c     |   36 +++++++++++++++++------------
 drivers/scsi/fcoe/fcoe.c              |   41 ++++++++++++++++++--------------
 include/rdma/ib_addr.h                |   15 ++++++-----
 net/core/net-sysfs.c                  |   24 ++++++++-----------
 15 files changed, 115 insertions(+), 105 deletions(-)

diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 3dc19f4..af0588f 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -320,16 +320,11 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
 #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
 static int tx4939_get_eth_speed(struct net_device *dev)
 {
-	struct ethtool_cmd cmd = { ETHTOOL_GSET };
-	int speed = 100;	/* default 100Mbps */
-	int err;
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
-		return speed;
-	err = dev->ethtool_ops->get_settings(dev, &cmd);
-	if (err < 0)
-		return speed;
-	speed = cmd.speed == SPEED_100 ? 100 : 10;
-	return speed;
+	struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
+	if (dev_ethtool_get_settings(dev, &cmd))
+		return 100;	/* default 100Mbps */
+
+	return (ethtool_cmd_speed(&cmd) == SPEED_100 ? 100 : 10);
 }
 static int tx4939_netdev_event(struct notifier_block *this,
 			       unsigned long event,
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index b0aa9e6..c810cda 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1668,7 +1668,8 @@ 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 };
+	u32 speed;
 
 	netif_printk(nic, timer, KERN_DEBUG, nic->netdev,
 		     "right now = %ld\n", jiffies);
@@ -1676,10 +1677,11 @@ static void e100_watchdog(unsigned long data)
 	/* mii library handles link maintenance tasks */
 
 	mii_ethtool_gset(&nic->mii, &cmd);
+	speed = ethtool_cmd_speed(&cmd);
 
 	if (mii_link_ok(&nic->mii) && !netif_carrier_ok(nic->netdev)) {
 		netdev_info(nic->netdev, "NIC Link is Up %u Mbps %s Duplex\n",
-			    cmd.speed == SPEED_100 ? 100 : 10,
+			    speed == SPEED_100 ? 100 : 10,
 			    cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
 	} else if (!mii_link_ok(&nic->mii) && netif_carrier_ok(nic->netdev)) {
 		netdev_info(nic->netdev, "NIC Link is Down\n");
@@ -1698,13 +1700,13 @@ static void e100_watchdog(unsigned long data)
 	spin_unlock_irq(&nic->cmd_lock);
 
 	e100_update_stats(nic);
-	e100_adjust_adaptive_ifs(nic, cmd.speed, cmd.duplex);
+	e100_adjust_adaptive_ifs(nic, speed, cmd.duplex);
 
 	if (nic->mac <= mac_82557_D100_C)
 		/* Issue a multicast command to workaround a 557 lock up */
 		e100_set_multicast_list(nic->netdev);
 
-	if (nic->flags & ich && cmd.speed==SPEED_10 && cmd.duplex==DUPLEX_HALF)
+	if (nic->flags & ich && speed == SPEED_10 && cmd.duplex == DUPLEX_HALF)
 		/* Need SW workaround for ICH[x] 10Mbps/half duplex Tx hang. */
 		nic->flags |= ich_10h_workaround;
 	else
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index 2ef2f9c..7d4452e 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -887,7 +887,7 @@ 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;
+	struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
 
 	pr_debug("right now = %ld\n", jiffies);
 
@@ -902,7 +902,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,
@@ -912,7 +912,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 923a687..9a8207f 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 0a1efba..07398bc 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,12 @@ 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",
+					    (ethtool_cmd_speed(&ecmd)
+					     == SPEED_100) ? "100" : "10",
 					    (ecmd.duplex == DUPLEX_FULL)
 					    ? "full" : "half");
 			}
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 19e68c2..7115914 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 0e61ac8..33cf0b1 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -237,13 +237,13 @@ 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 6140b56..6998aa6 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 5002f5b..1d93133 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 860a20c..15b3d68 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 24f4b37..b374a99 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 e2e6475..6df9540 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -664,22 +664,28 @@ 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 };
-
-	if (!dev_ethtool_get_settings(netdev, &ecmd)) {
-		lport->link_supported_speeds &=
-			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
-		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
-				      SUPPORTED_1000baseT_Full))
-			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
-		if (ecmd.supported & SUPPORTED_10000baseT_Full)
-			lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
-
-		if (ecmd.speed == SPEED_1000)
-			lport->link_speed = FC_PORTSPEED_1GBIT;
-		if (ecmd.speed == SPEED_10000)
-			lport->link_speed = FC_PORTSPEED_10GBIT;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
+
+	if (dev_ethtool_get_settings(netdev, &ecmd))
+		return;
+
+	lport->link_supported_speeds &=
+		~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
+	if (ecmd.supported & (SUPPORTED_1000baseT_Half |
+			      SUPPORTED_1000baseT_Full))
+		lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+	if (ecmd.supported & SUPPORTED_10000baseT_Full)
+		lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
+
+	switch (ethtool_cmd_speed(&ecmd)) {
+	case SPEED_1000:
+		lport->link_speed = FC_PORTSPEED_1GBIT;
+		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 bde6ee5..ba9e84a 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -2026,25 +2026,30 @@ out_nodev:
 int fcoe_link_speed_update(struct fc_lport *lport)
 {
 	struct net_device *netdev = fcoe_netdev(lport);
-	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
-
-	if (!dev_ethtool_get_settings(netdev, &ecmd)) {
-		lport->link_supported_speeds &=
-			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
-		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
-				      SUPPORTED_1000baseT_Full))
-			lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
-		if (ecmd.supported & SUPPORTED_10000baseT_Full)
-			lport->link_supported_speeds |=
-				FC_PORTSPEED_10GBIT;
-		if (ecmd.speed == SPEED_1000)
-			lport->link_speed = FC_PORTSPEED_1GBIT;
-		if (ecmd.speed == SPEED_10000)
-			lport->link_speed = FC_PORTSPEED_10GBIT;
-
-		return 0;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
+
+	if (dev_ethtool_get_settings(netdev, &ecmd))
+		return -1;
+
+	lport->link_supported_speeds &=
+		~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
+	if (ecmd.supported & (SUPPORTED_1000baseT_Half |
+			      SUPPORTED_1000baseT_Full))
+		lport->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+	if (ecmd.supported & SUPPORTED_10000baseT_Full)
+		lport->link_supported_speeds |=
+			FC_PORTSPEED_10GBIT;
+
+	switch (ethtool_cmd_speed(&ecmd)) {
+	case SPEED_1000:
+		lport->link_speed = FC_PORTSPEED_1GBIT;
+		break;
+	case SPEED_10000:
+		lport->link_speed = FC_PORTSPEED_10GBIT;
+		break;
 	}
-	return -1;
+
+	return 0;
 }
 
 /**
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index b5fc9f3..672904f 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -216,19 +216,20 @@ static inline enum ib_mtu iboe_get_mtu(int mtu)
 
 static inline int iboe_get_rate(struct net_device *dev)
 {
-	struct ethtool_cmd cmd;
+	struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
+	u32 speed;
 
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings ||
-	    dev->ethtool_ops->get_settings(dev, &cmd))
+	if (dev_ethtool_get_settings(dev, &cmd))
 		return IB_RATE_PORT_CURRENT;
 
-	if (cmd.speed >= 40000)
+	speed = ethtool_cmd_speed(&cmd);
+	if (speed >= 40000)
 		return IB_RATE_40_GBPS;
-	else if (cmd.speed >= 30000)
+	else if (speed >= 30000)
 		return IB_RATE_30_GBPS;
-	else if (cmd.speed >= 20000)
+	else if (speed >= 20000)
 		return IB_RATE_20_GBPS;
-	else if (cmd.speed >= 10000)
+	else if (speed >= 10000)
 		return IB_RATE_10_GBPS;
 	else
 		return IB_RATE_PORT_CURRENT;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 5ceb257..38733e5 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -28,6 +28,7 @@
 static const char fmt_hex[] = "%#x\n";
 static const char fmt_long_hex[] = "%#lx\n";
 static const char fmt_dec[] = "%d\n";
+static const char fmt_udec[] = "%u\n";
 static const char fmt_ulong[] = "%lu\n";
 static const char fmt_u64[] = "%llu\n";
 
@@ -145,13 +146,10 @@ static ssize_t show_speed(struct device *dev,
 	if (!rtnl_trylock())
 		return restart_syscall();
 
-	if (netif_running(netdev) &&
-	    netdev->ethtool_ops &&
-	    netdev->ethtool_ops->get_settings) {
-		struct ethtool_cmd cmd = { ETHTOOL_GSET };
-
-		if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
-			ret = sprintf(buf, fmt_dec, ethtool_cmd_speed(&cmd));
+	if (netif_running(netdev)) {
+		struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
+		if (!dev_ethtool_get_settings(netdev, &cmd))
+			ret = sprintf(buf, fmt_udec, ethtool_cmd_speed(&cmd));
 	}
 	rtnl_unlock();
 	return ret;
@@ -166,13 +164,11 @@ static ssize_t show_duplex(struct device *dev,
 	if (!rtnl_trylock())
 		return restart_syscall();
 
-	if (netif_running(netdev) &&
-	    netdev->ethtool_ops &&
-	    netdev->ethtool_ops->get_settings) {
-		struct ethtool_cmd cmd = { ETHTOOL_GSET };
-
-		if (!netdev->ethtool_ops->get_settings(netdev, &cmd))
-			ret = sprintf(buf, "%s\n", cmd.duplex ? "full" : "half");
+	if (netif_running(netdev)) {
+		struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
+		if (!dev_ethtool_get_settings(netdev, &cmd))
+			ret = sprintf(buf, "%s\n",
+				      cmd.duplex ? "full" : "half");
 	}
 	rtnl_unlock();
 	return ret;
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH 4/5] ethtool: Use the full 32 bit speed range in ethtool's set_settings
From: David Decotigny @ 2011-04-17  0:54 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, Michał Mirosław,
	Stanislaw Gruszka
  Cc: David Decotigny
In-Reply-To: <1303001651-4074-1-git-send-email-decot@google.com>

This makes sure the ethtool's set_settings() callback of network
drivers don't ignore the 16 most significant bits when ethtool calls
their set_settings().

All the driver compiled with make allyesconfig on x86_64 have been
updated.

Tested: make allyesconfig compiles + e1000e and bnx2x work

Signed-off-by: David Decotigny <decot@google.com>
---
 drivers/net/acenic.c                    |    2 +-
 drivers/net/atl1c/atl1c_ethtool.c       |    5 +++--
 drivers/net/atlx/atl1.c                 |    5 +++--
 drivers/net/b44.c                       |    7 ++++---
 drivers/net/bna/bnad_ethtool.c          |    3 ++-
 drivers/net/bnx2.c                      |   12 ++++++------
 drivers/net/cassini.c                   |   12 +++++++-----
 drivers/net/chelsio/cxgb2.c             |    7 ++++---
 drivers/net/cxgb3/cxgb3_main.c          |   10 ++++++----
 drivers/net/cxgb4/cxgb4_main.c          |   11 ++++++-----
 drivers/net/dl2k.c                      |    4 ++--
 drivers/net/e1000/e1000_ethtool.c       |    6 ++++--
 drivers/net/e1000e/ethtool.c            |    3 ++-
 drivers/net/enc28j60.c                  |    3 ++-
 drivers/net/forcedeth.c                 |   11 ++++++-----
 drivers/net/igb/igb_ethtool.c           |    3 ++-
 drivers/net/ixgb/ixgb_ethtool.c         |    3 ++-
 drivers/net/ixgbe/ixgbe_ethtool.c       |    3 ++-
 drivers/net/jme.c                       |    3 ++-
 drivers/net/ksz884x.c                   |    9 +++++----
 drivers/net/mii.c                       |   13 +++++++------
 drivers/net/mlx4/en_ethtool.c           |    3 ++-
 drivers/net/natsemi.c                   |    5 +++--
 drivers/net/netxen/netxen_nic_ethtool.c |    5 +++--
 drivers/net/niu.c                       |    2 +-
 drivers/net/pch_gbe/pch_gbe_ethtool.c   |    7 ++++---
 drivers/net/pcmcia/smc91c92_cs.c        |    4 ++--
 drivers/net/phy/phy.c                   |   10 ++++++----
 drivers/net/qlcnic/qlcnic_ethtool.c     |    4 ++--
 drivers/net/r8169.c                     |    3 ++-
 drivers/net/s2io.c                      |    2 +-
 drivers/net/sc92031.c                   |    5 +++--
 drivers/net/sfc/ethtool.c               |    3 ++-
 drivers/net/sfc/mcdi_phy.c              |    4 ++--
 drivers/net/skge.c                      |    4 ++--
 drivers/net/sky2.c                      |    4 ++--
 drivers/net/sungem.c                    |    9 +++++----
 drivers/net/sunhme.c                    |    6 +++---
 drivers/net/tg3.c                       |    9 +++++----
 drivers/net/tulip/de2104x.c             |    5 +++--
 drivers/net/typhoon.c                   |   17 +++++++++--------
 drivers/net/via-velocity.c              |   10 ++++++----
 drivers/net/vxge/vxge-ethtool.c         |    3 ++-
 net/bridge/br_if.c                      |    4 ++--
 44 files changed, 150 insertions(+), 113 deletions(-)

diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index ee648fe..0b4d8d1 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2718,7 +2718,7 @@ static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		link |= LNK_TX_FLOW_CTL_Y;
 	if (ecmd->autoneg == AUTONEG_ENABLE)
 		link |= LNK_NEGOTIATE;
-	if (ecmd->speed != speed) {
+	if (ethtool_cmd_speed(ecmd) != speed) {
 		link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
 		switch (speed) {
 		case SPEED_1000:
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
index 3af5a33..b1eceee 100644
--- a/drivers/net/atl1c/atl1c_ethtool.c
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -77,7 +77,8 @@ static int atl1c_set_settings(struct net_device *netdev,
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		autoneg_advertised = ADVERTISED_Autoneg;
 	} else {
-		if (ecmd->speed == SPEED_1000) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (speed == SPEED_1000) {
 			if (ecmd->duplex != DUPLEX_FULL) {
 				if (netif_msg_link(adapter))
 					dev_warn(&adapter->pdev->dev,
@@ -86,7 +87,7 @@ static int atl1c_set_settings(struct net_device *netdev,
 				return -EINVAL;
 			}
 			autoneg_advertised = ADVERTISED_1000baseT_Full;
-		} else if (ecmd->speed == SPEED_100) {
+		} else if (speed == SPEED_100) {
 			if (ecmd->duplex == DUPLEX_FULL)
 				autoneg_advertised = ADVERTISED_100baseT_Full;
 			else
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 98334a1..de27e5b 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -3271,7 +3271,8 @@ static int atl1_set_settings(struct net_device *netdev,
 	if (ecmd->autoneg == AUTONEG_ENABLE)
 		hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
 	else {
-		if (ecmd->speed == SPEED_1000) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (speed == SPEED_1000) {
 			if (ecmd->duplex != DUPLEX_FULL) {
 				if (netif_msg_link(adapter))
 					dev_warn(&adapter->pdev->dev,
@@ -3280,7 +3281,7 @@ static int atl1_set_settings(struct net_device *netdev,
 				goto exit_sset;
 			}
 			hw->media_type = MEDIA_TYPE_1000M_FULL;
-		} else if (ecmd->speed == SPEED_100) {
+		} else if (speed == SPEED_100) {
 			if (ecmd->duplex == DUPLEX_FULL)
 				hw->media_type = MEDIA_TYPE_100M_FULL;
 			else
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 2e2b762..909cc4b 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1831,6 +1831,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct b44 *bp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	/* We do not support gigabit. */
 	if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -1838,8 +1839,8 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		    (ADVERTISED_1000baseT_Half |
 		     ADVERTISED_1000baseT_Full))
 			return -EINVAL;
-	} else if ((cmd->speed != SPEED_100 &&
-		    cmd->speed != SPEED_10) ||
+	} else if ((speed != SPEED_100 &&
+		    speed != SPEED_10) ||
 		   (cmd->duplex != DUPLEX_HALF &&
 		    cmd->duplex != DUPLEX_FULL)) {
 			return -EINVAL;
@@ -1873,7 +1874,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	} else {
 		bp->flags |= B44_FLAG_FORCE_LINK;
 		bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
-		if (cmd->speed == SPEED_100)
+		if (speed == SPEED_100)
 			bp->flags |= B44_FLAG_100_BASE_T;
 		if (cmd->duplex == DUPLEX_FULL)
 			bp->flags |= B44_FLAG_FULL_DUPLEX;
diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c
index c51e078e..ae1e118 100644
--- a/drivers/net/bna/bnad_ethtool.c
+++ b/drivers/net/bna/bnad_ethtool.c
@@ -256,7 +256,8 @@ bnad_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 	/* 10G full duplex setting supported only */
 	if (cmd->autoneg == AUTONEG_ENABLE)
 		return -EOPNOTSUPP; else {
-		if ((cmd->speed == SPEED_10000) && (cmd->duplex == DUPLEX_FULL))
+		if ((ethtool_cmd_speed(cmd) == SPEED_10000)
+		    && (cmd->duplex == DUPLEX_FULL))
 			return 0;
 	}
 
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index bf729ee..e43efd8 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -6758,21 +6758,21 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		advertising |= ADVERTISED_Autoneg;
 	}
 	else {
+		u32 speed = ethtool_cmd_speed(cmd);
 		if (cmd->port == PORT_FIBRE) {
-			if ((cmd->speed != SPEED_1000 &&
-			     cmd->speed != SPEED_2500) ||
+			if ((speed != SPEED_1000 &&
+			     speed != SPEED_2500) ||
 			    (cmd->duplex != DUPLEX_FULL))
 				goto err_out_unlock;
 
-			if (cmd->speed == SPEED_2500 &&
+			if (speed == SPEED_2500 &&
 			    !(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
 				goto err_out_unlock;
-		}
-		else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500)
+		} else if (speed == SPEED_1000 || speed == SPEED_2500)
 			goto err_out_unlock;
 
 		autoneg &= ~AUTONEG_SPEED;
-		req_line_speed = cmd->speed;
+		req_line_speed = speed;
 		req_duplex = cmd->duplex;
 		advertising = 0;
 	}
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 143a28c..a6c3f8c 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -709,10 +709,11 @@ static void cas_begin_auto_negotiation(struct cas *cp, struct ethtool_cmd *ep)
 	if (ep->autoneg == AUTONEG_ENABLE)
 		cp->link_cntl = BMCR_ANENABLE;
 	else {
+		u32 speed = ethtool_cmd_speed(ep);
 		cp->link_cntl = 0;
-		if (ep->speed == SPEED_100)
+		if (speed == SPEED_100)
 			cp->link_cntl |= BMCR_SPEED100;
-		else if (ep->speed == SPEED_1000)
+		else if (speed == SPEED_1000)
 			cp->link_cntl |= CAS_BMCR_SPEED1000;
 		if (ep->duplex == DUPLEX_FULL)
 			cp->link_cntl |= BMCR_FULLDPLX;
@@ -4653,6 +4654,7 @@ static int cas_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct cas *cp = netdev_priv(dev);
 	unsigned long flags;
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	/* Verify the settings we care about. */
 	if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -4660,9 +4662,9 @@ static int cas_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		return -EINVAL;
 
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_1000 &&
-	      cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((speed != SPEED_1000 &&
+	      speed != SPEED_100 &&
+	      speed != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 0f71304..a2eed0c 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -640,11 +640,12 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		return -EOPNOTSUPP;             /* can't change speed/duplex */
 
 	if (cmd->autoneg == AUTONEG_DISABLE) {
-		int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+		u32 speed = ethtool_cmd_speed(cmd);
+		int cap = speed_duplex_to_caps(speed, cmd->duplex);
 
-		if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
+		if (!(lc->supported & cap) || (speed == SPEED_1000))
 			return -EINVAL;
-		lc->requested_speed = cmd->speed;
+		lc->requested_speed = speed;
 		lc->requested_duplex = cmd->duplex;
 		lc->advertising = 0;
 	} else {
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index a087e06..00469dc 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1842,7 +1842,8 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		 * being requested.
 		 */
 		if (cmd->autoneg == AUTONEG_DISABLE) {
-			int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+			u32 speed = ethtool_cmd_speed(cmd);
+			int cap = speed_duplex_to_caps(speed, cmd->duplex);
 			if (lc->supported & cap)
 				return 0;
 		}
@@ -1850,11 +1851,12 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	}
 
 	if (cmd->autoneg == AUTONEG_DISABLE) {
-		int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+		u32 speed = ethtool_cmd_speed(cmd);
+		int cap = speed_duplex_to_caps(speed, cmd->duplex);
 
-		if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
+		if (!(lc->supported & cap) || (speed == SPEED_1000))
 			return -EINVAL;
-		lc->requested_speed = cmd->speed;
+		lc->requested_speed = speed;
 		lc->requested_duplex = cmd->duplex;
 		lc->advertising = 0;
 	} else {
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index 0af9c9f..a49d370 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -1460,6 +1460,7 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	unsigned int cap;
 	struct port_info *p = netdev_priv(dev);
 	struct link_config *lc = &p->link_cfg;
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	if (cmd->duplex != DUPLEX_FULL)     /* only full-duplex supported */
 		return -EINVAL;
@@ -1470,16 +1471,16 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		 * being requested.
 		 */
 		if (cmd->autoneg == AUTONEG_DISABLE &&
-		    (lc->supported & speed_to_caps(cmd->speed)))
-				return 0;
+		    (lc->supported & speed_to_caps(speed)))
+			return 0;
 		return -EINVAL;
 	}
 
 	if (cmd->autoneg == AUTONEG_DISABLE) {
-		cap = speed_to_caps(cmd->speed);
+		cap = speed_to_caps(speed);
 
-		if (!(lc->supported & cap) || cmd->speed == SPEED_1000 ||
-		    cmd->speed == SPEED_10000)
+		if (!(lc->supported & cap) || (speed == SPEED_1000) ||
+		    (ethtool_cmd_speed(cmd) == SPEED_10000))
 			return -EINVAL;
 		lc->requested_speed = cap;
 		lc->advertising = 0;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index c05db60..ba6c151 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -1219,11 +1219,11 @@ static int rio_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	} else {
 		np->an_enable = 0;
 		if (np->speed == 1000) {
-			cmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(cmd, SPEED_100);
 			cmd->duplex = DUPLEX_FULL;
 			printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n");
 		}
-		switch(cmd->speed + cmd->duplex) {
+		switch (ethtool_cmd_speed(cmd) + cmd->duplex) {
 
 		case SPEED_10 + DUPLEX_HALF:
 			np->speed = 10;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index dd70738..a53629d 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -197,11 +197,13 @@ static int e1000_set_settings(struct net_device *netdev,
 			                         ADVERTISED_TP |
 			                         ADVERTISED_Autoneg;
 		ecmd->advertising = hw->autoneg_advertised;
-	} else
-		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+	} else {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (e1000_set_spd_dplx(adapter, speed + ecmd->duplex)) {
 			clear_bit(__E1000_RESETTING, &adapter->flags);
 			return -EINVAL;
 		}
+	}
 
 	/* reset the link */
 
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index a31d280..1dd81b2 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -269,7 +269,8 @@ static int e1000_set_settings(struct net_device *netdev,
 		if (adapter->fc_autoneg)
 			hw->fc.requested_mode = e1000_fc_default;
 	} else {
-		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (e1000_set_spd_dplx(adapter, speed + ecmd->duplex)) {
 			clear_bit(__E1000_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index 907b05a..81a7937 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -1499,7 +1499,8 @@ enc28j60_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static int
 enc28j60_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	return enc28j60_setlink(dev, cmd->autoneg, cmd->speed, cmd->duplex);
+	return enc28j60_setlink(dev, cmd->autoneg,
+				ethtool_cmd_speed(cmd), cmd->duplex);
 }
 
 static u32 enc28j60_get_msglevel(struct net_device *dev)
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index ec9a32d..9ecd33a 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -4029,6 +4029,7 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct fe_priv *np = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(ecmd);
 
 	if (ecmd->port != PORT_MII)
 		return -EINVAL;
@@ -4054,7 +4055,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		/* Note: autonegotiation disable, speed 1000 intentionally
 		 * forbidden - no one should need that. */
 
-		if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+		if (speed != SPEED_10 && speed != SPEED_100)
 			return -EINVAL;
 		if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 			return -EINVAL;
@@ -4138,13 +4139,13 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
 		adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
 		adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-		if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF)
+		if (speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF)
 			adv |= ADVERTISE_10HALF;
-		if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL)
+		if (speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL)
 			adv |= ADVERTISE_10FULL;
-		if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF)
+		if (speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF)
 			adv |= ADVERTISE_100HALF;
-		if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL)
+		if (speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL)
 			adv |= ADVERTISE_100FULL;
 		np->pause_flags &= ~(NV_PAUSEFRAME_AUTONEG|NV_PAUSEFRAME_RX_ENABLE|NV_PAUSEFRAME_TX_ENABLE);
 		if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) {/* for rx we set both advertisements but disable tx pause */
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index d976733..2cc221b 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -223,7 +223,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 		if (adapter->fc_autoneg)
 			hw->fc.requested_mode = e1000_fc_default;
 	} else {
-		if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (igb_set_spd_dplx(adapter, speed + ecmd->duplex)) {
 			clear_bit(__IGB_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index cc53aa1..edb3d7e 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -129,9 +129,10 @@ static int
 ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
+	u32 speed = ethtool_cmd_speed(ecmd);
 
 	if (ecmd->autoneg == AUTONEG_ENABLE ||
-	   ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
+	    (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
 		return -EINVAL;
 
 	if (netif_running(adapter->netdev)) {
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 5005a36..e1c3576 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -346,9 +346,10 @@ static int ixgbe_set_settings(struct net_device *netdev,
 		}
 	} else {
 		/* in this case we currently only support 10Gb/FULL */
+		u32 speed = ethtool_cmd_speed(ecmd);
 		if ((ecmd->autoneg == AUTONEG_ENABLE) ||
 		    (ecmd->advertising != ADVERTISED_10000baseT_Full) ||
-		    (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
+		    (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
 			return -EINVAL;
 	}
 
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index be4773f..b5b174a 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -2555,7 +2555,8 @@ jme_set_settings(struct net_device *netdev,
 	struct jme_adapter *jme = netdev_priv(netdev);
 	int rc, fdc = 0;
 
-	if (ecmd->speed == SPEED_1000 && ecmd->autoneg != AUTONEG_ENABLE)
+	if (ethtool_cmd_speed(ecmd) == SPEED_1000
+	    && ecmd->autoneg != AUTONEG_ENABLE)
 		return -EINVAL;
 
 	/*
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 2c37a38..66037b1 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -5998,6 +5998,7 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	struct dev_priv *priv = netdev_priv(dev);
 	struct dev_info *hw_priv = priv->adapter;
 	struct ksz_port *port = &priv->port;
+	u32 speed = ethtool_cmd_speed(cmd);
 	int rc;
 
 	/*
@@ -6006,11 +6007,11 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	 */
 	if (cmd->autoneg && priv->advertising == cmd->advertising) {
 		cmd->advertising |= ADVERTISED_ALL;
-		if (10 == cmd->speed)
+		if (SPEED_10 == speed)
 			cmd->advertising &=
 				~(ADVERTISED_100baseT_Full |
 				ADVERTISED_100baseT_Half);
-		else if (100 == cmd->speed)
+		else if (SPEED_100 == speed)
 			cmd->advertising &=
 				~(ADVERTISED_10baseT_Full |
 				ADVERTISED_10baseT_Half);
@@ -6032,8 +6033,8 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		port->force_link = 0;
 	} else {
 		port->duplex = cmd->duplex + 1;
-		if (cmd->speed != 1000)
-			port->speed = cmd->speed;
+		if (speed != SPEED_1000)
+			port->speed = speed;
 		if (cmd->autoneg)
 			port->force_link = 0;
 		else
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index 0a6c6a2..cc5a22d 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -154,10 +154,11 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 {
 	struct net_device *dev = mii->dev;
+	u32 speed = ethtool_cmd_speed(ecmd);
 
-	if (ecmd->speed != SPEED_10 &&
-	    ecmd->speed != SPEED_100 &&
-	    ecmd->speed != SPEED_1000)
+	if (speed != SPEED_10 &&
+	    speed != SPEED_100 &&
+	    speed != SPEED_1000)
 		return -EINVAL;
 	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 		return -EINVAL;
@@ -169,7 +170,7 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 		return -EINVAL;
 	if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
 		return -EINVAL;
-	if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii))
+	if ((speed == SPEED_1000) && (!mii->supports_gmii))
 		return -EINVAL;
 
 	/* ignore supported, maxtxpkt, maxrxpkt */
@@ -227,9 +228,9 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 		bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
 		tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 |
 			       BMCR_SPEED1000 | BMCR_FULLDPLX);
-		if (ecmd->speed == SPEED_1000)
+		if (speed == SPEED_1000)
 			tmp |= BMCR_SPEED1000;
-		else if (ecmd->speed == SPEED_100)
+		else if (speed == SPEED_100)
 			tmp |= BMCR_SPEED100;
 		if (ecmd->duplex == DUPLEX_FULL) {
 			tmp |= BMCR_FULLDPLX;
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
index da1b64d..be4a9e0 100644
--- a/drivers/net/mlx4/en_ethtool.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -292,7 +292,8 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	if ((cmd->autoneg == AUTONEG_ENABLE) ||
-	    (cmd->speed != SPEED_10000) || (cmd->duplex != DUPLEX_FULL))
+	    (ethtool_cmd_speed(cmd) != SPEED_10000) ||
+	    (cmd->duplex != DUPLEX_FULL))
 		return -EINVAL;
 
 	/* Nothing to change */
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index aa2813e..dbe31e9 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -2905,7 +2905,8 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 			return -EINVAL;
 		}
 	} else if (ecmd->autoneg == AUTONEG_DISABLE) {
-		if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (speed != SPEED_10 && speed != SPEED_100)
 			return -EINVAL;
 		if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 			return -EINVAL;
@@ -2953,7 +2954,7 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 		if (ecmd->advertising & ADVERTISED_100baseT_Full)
 			np->advertising |= ADVERTISE_100FULL;
 	} else {
-		np->speed  = ecmd->speed;
+		np->speed  = ethtool_cmd_speed(ecmd);
 		np->duplex = ecmd->duplex;
 		/* user overriding the initial full duplex parm? */
 		if (np->duplex == DUPLEX_HALF)
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 29f90ba..e8d16f6 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -251,6 +251,7 @@ static int
 netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(ecmd);
 	int ret;
 
 	if (adapter->ahw.port_type != NETXEN_NIC_GBE)
@@ -259,14 +260,14 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG))
 		return -EOPNOTSUPP;
 
-	ret = nx_fw_cmd_set_gbe_port(adapter, ecmd->speed, ecmd->duplex,
+	ret = nx_fw_cmd_set_gbe_port(adapter, speed, ecmd->duplex,
 				     ecmd->autoneg);
 	if (ret == NX_RCODE_NOT_SUPPORTED)
 		return -EOPNOTSUPP;
 	else if (ret)
 		return -EIO;
 
-	adapter->link_speed = ecmd->speed;
+	adapter->link_speed = speed;
 	adapter->link_duplex = ecmd->duplex;
 	adapter->link_autoneg = ecmd->autoneg;
 
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index ea2272f..350225f 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -6859,7 +6859,7 @@ static int niu_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	struct niu_link_config *lp = &np->link_config;
 
 	lp->advertising = cmd->advertising;
-	lp->speed = cmd->speed;
+	lp->speed = ethtool_cmd_speed(cmd);
 	lp->duplex = cmd->duplex;
 	lp->autoneg = cmd->autoneg;
 	return niu_init_link(np);
diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c
index d2174a4..cae1e7f 100644
--- a/drivers/net/pch_gbe/pch_gbe_ethtool.c
+++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c
@@ -109,12 +109,13 @@ static int pch_gbe_set_settings(struct net_device *netdev,
 {
 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 	struct pch_gbe_hw *hw = &adapter->hw;
+	u32 speed = ethtool_cmd_speed(ecmd);
 	int ret;
 
 	pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
 
-	if (ecmd->speed == USHRT_MAX) {
-		ecmd->speed = SPEED_1000;
+	if (speed == USHRT_MAX) {
+		speed = SPEED_1000;
 		ecmd->duplex = DUPLEX_FULL;
 	}
 	ret = mii_ethtool_sset(&adapter->mii, ecmd);
@@ -122,7 +123,7 @@ static int pch_gbe_set_settings(struct net_device *netdev,
 		pr_err("Error: mii_ethtool_sset\n");
 		return ret;
 	}
-	hw->mac.link_speed = ecmd->speed;
+	hw->mac.link_speed = speed;
 	hw->mac.link_duplex = ecmd->duplex;
 	hw->phy.autoneg_advertised = ecmd->advertising;
 	hw->mac.autoneg = ecmd->autoneg;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 1085917..bc71cb2 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1875,8 +1875,8 @@ static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
     u16 tmp;
     unsigned int ioaddr = dev->base_addr;
 
-    if (ecmd->speed != SPEED_10)
-    	return -EINVAL;
+    if (ethtool_cmd_speed(ecmd) != SPEED_10)
+	return -EINVAL;
     if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
     	return -EINVAL;
     if (ecmd->port != PORT_TP && ecmd->port != PORT_AUI)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index f767033..e3f3501 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -238,6 +238,8 @@ static void phy_sanitize_settings(struct phy_device *phydev)
  */
 int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 {
+	u32 speed = ethtool_cmd_speed(cmd);
+
 	if (cmd->phy_address != phydev->addr)
 		return -EINVAL;
 
@@ -253,16 +255,16 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 		return -EINVAL;
 
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_1000 &&
-	      cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((speed != SPEED_1000 &&
+	      speed != SPEED_100 &&
+	      speed != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
 
 	phydev->autoneg = cmd->autoneg;
 
-	phydev->speed = cmd->speed;
+	phydev->speed = speed;
 
 	phydev->advertising = cmd->advertising;
 
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 3cd8a16..9886dfc 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -302,7 +302,7 @@ qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 			      &status) != 0)
 			return -EIO;
 
-		switch (ecmd->speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case SPEED_10:
 			qlcnic_set_phy_speed(status, 0);
 			break;
@@ -323,7 +323,7 @@ qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 			       *((int *)&status)) != 0)
 			return -EIO;
 		else {
-			adapter->link_speed = ecmd->speed;
+			adapter->link_speed = ethtool_cmd_speed(ecmd);
 			adapter->link_duplex = ecmd->duplex;
 		}
 	} else
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 058524f..a11e6ca 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1280,7 +1280,8 @@ static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	spin_lock_irqsave(&tp->lock, flags);
 	ret = rtl8169_set_speed(dev,
-		cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising);
+				cmd->autoneg, ethtool_cmd_speed(cmd),
+				cmd->duplex, cmd->advertising);
 	spin_unlock_irqrestore(&tp->lock, flags);
 
 	return ret;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 2302d97..956a139 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -5380,7 +5380,7 @@ static int s2io_ethtool_sset(struct net_device *dev,
 {
 	struct s2io_nic *sp = netdev_priv(dev);
 	if ((info->autoneg == AUTONEG_ENABLE) ||
-	    (info->speed != SPEED_10000) ||
+	    (ethtool_cmd_speed(info) != SPEED_10000) ||
 	    (info->duplex != DUPLEX_FULL))
 		return -EINVAL;
 	else {
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 76290a8..f3ffc1d 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1188,10 +1188,11 @@ static int sc92031_ethtool_set_settings(struct net_device *dev,
 {
 	struct sc92031_priv *priv = netdev_priv(dev);
 	void __iomem *port_base = priv->port_base;
+	u32 speed = ethtool_cmd_speed(cmd);
 	u32 phy_ctrl;
 	u32 old_phy_ctrl;
 
-	if (!(cmd->speed == SPEED_10 || cmd->speed == SPEED_100))
+	if (!(speed == SPEED_10 || speed == SPEED_100))
 		return -EINVAL;
 	if (!(cmd->duplex == DUPLEX_HALF || cmd->duplex == DUPLEX_FULL))
 		return -EINVAL;
@@ -1229,7 +1230,7 @@ static int sc92031_ethtool_set_settings(struct net_device *dev,
 		// FIXME: Whole branch guessed
 		phy_ctrl = 0;
 
-		if (cmd->speed == SPEED_10)
+		if (speed == SPEED_10)
 			phy_ctrl |= PhyCtrlSpd10;
 		else /* cmd->speed == SPEED_100 */
 			phy_ctrl |= PhyCtrlSpd100;
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 5d8468f..10b160a 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -234,7 +234,8 @@ static int efx_ethtool_set_settings(struct net_device *net_dev,
 	int rc;
 
 	/* GMAC does not support 1000Mbps HD */
-	if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
+	if ((ethtool_cmd_speed(ecmd) == SPEED_1000) &&
+	    (ecmd->duplex != DUPLEX_FULL)) {
 		netif_dbg(efx, drv, efx->net_dev,
 			  "rejecting unsupported 1000Mbps HD setting\n");
 		return -EINVAL;
diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c
index 1fcda2d..6c5fccb 100644
--- a/drivers/net/sfc/mcdi_phy.c
+++ b/drivers/net/sfc/mcdi_phy.c
@@ -545,7 +545,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
 		caps = (ethtool_to_mcdi_cap(ecmd->advertising) |
 			 1 << MC_CMD_PHY_CAP_AN_LBN);
 	} else if (ecmd->duplex) {
-		switch (ecmd->speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case 10:    caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN;    break;
 		case 100:   caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN;   break;
 		case 1000:  caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN;  break;
@@ -553,7 +553,7 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
 		default:    return -EINVAL;
 		}
 	} else {
-		switch (ecmd->speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case 10:    caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN;    break;
 		case 100:   caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN;   break;
 		case 1000:  caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN;  break;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 176d784..b0fa999 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -322,7 +322,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	} else {
 		u32 setting;
 
-		switch (ecmd->speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case SPEED_1000:
 			if (ecmd->duplex == DUPLEX_FULL)
 				setting = SUPPORTED_1000baseT_Full;
@@ -355,7 +355,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		if ((setting & supported) == 0)
 			return -EINVAL;
 
-		skge->speed = ecmd->speed;
+		skge->speed = ethtool_cmd_speed(ecmd);
 		skge->duplex = ecmd->duplex;
 	}
 
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index c8d0451..40afe07 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3453,7 +3453,7 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	} else {
 		u32 setting;
 
-		switch (ecmd->speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case SPEED_1000:
 			if (ecmd->duplex == DUPLEX_FULL)
 				setting = SUPPORTED_1000baseT_Full;
@@ -3486,7 +3486,7 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		if ((setting & supported) == 0)
 			return -EINVAL;
 
-		sky2->speed = ecmd->speed;
+		sky2->speed = ethtool_cmd_speed(ecmd);
 		sky2->duplex = ecmd->duplex;
 		sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
 	}
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 81b6eb8..40a755d 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -1294,7 +1294,7 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
 		autoneg = 1;
 	} else {
 		autoneg = 0;
-		speed = ep->speed;
+		speed = ethtool_cmd_speed(ep);
 		duplex = ep->duplex;
 	}
 
@@ -2686,6 +2686,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct gem *gp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	/* Verify the settings we care about. */
 	if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -2697,9 +2698,9 @@ static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		return -EINVAL;
 
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_1000 &&
-	      cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((speed != SPEED_1000 &&
+	      speed != SPEED_100 &&
+	      speed != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 80e907d..8f3f028 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -1383,7 +1383,7 @@ force_link:
 		if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) {
 			hp->sw_bmcr = BMCR_SPEED100;
 		} else {
-			if (ep->speed == SPEED_100)
+			if (ethtool_cmd_speed(ep) == SPEED_100)
 				hp->sw_bmcr = BMCR_SPEED100;
 			else
 				hp->sw_bmcr = 0;
@@ -2452,8 +2452,8 @@ static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	    cmd->autoneg != AUTONEG_DISABLE)
 		return -EINVAL;
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((ethtool_cmd_speed(cmd) != SPEED_100 &&
+	      ethtool_cmd_speed(cmd) != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 9915734..0e40af2 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9976,6 +9976,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct tg3 *tp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 		struct phy_device *phydev;
@@ -10025,14 +10026,14 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		cmd->advertising &= mask;
 	} else {
 		if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) {
-			if (cmd->speed != SPEED_1000)
+			if (speed != SPEED_1000)
 				return -EINVAL;
 
 			if (cmd->duplex != DUPLEX_FULL)
 				return -EINVAL;
 		} else {
-			if (cmd->speed != SPEED_100 &&
-			    cmd->speed != SPEED_10)
+			if (speed != SPEED_100 &&
+			    speed != SPEED_10)
 				return -EINVAL;
 		}
 	}
@@ -10047,7 +10048,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		tp->link_config.duplex = DUPLEX_INVALID;
 	} else {
 		tp->link_config.advertising = 0;
-		tp->link_config.speed = cmd->speed;
+		tp->link_config.speed = speed;
 		tp->link_config.duplex = cmd->duplex;
 	}
 
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index b13c6b0..f8d26bf 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1549,10 +1549,11 @@ static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd)
 {
 	u32 new_media;
 	unsigned int media_lock;
+	u32 speed = ethtool_cmd_speed(ecmd);
 
-	if (ecmd->speed != SPEED_10 && ecmd->speed != 5 && ecmd->speed != 2)
+	if (speed != SPEED_10 && speed != 5 && speed != 2)
 		return -EINVAL;
-	if (de->de21040 && ecmd->speed == 2)
+	if (de->de21040 && speed == 2)
 		return -EINVAL;
 	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 		return -EINVAL;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 82653cb..adf5dbc 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1068,25 +1068,26 @@ static int
 typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct typhoon *tp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 	struct cmd_desc xp_cmd;
 	__le16 xcvr;
 	int err;
 
 	err = -EINVAL;
-	if(cmd->autoneg == AUTONEG_ENABLE) {
+	if (cmd->autoneg == AUTONEG_ENABLE) {
 		xcvr = TYPHOON_XCVR_AUTONEG;
 	} else {
-		if(cmd->duplex == DUPLEX_HALF) {
-			if(cmd->speed == SPEED_10)
+		if (cmd->duplex == DUPLEX_HALF) {
+			if (speed == SPEED_10)
 				xcvr = TYPHOON_XCVR_10HALF;
-			else if(cmd->speed == SPEED_100)
+			else if (speed == SPEED_100)
 				xcvr = TYPHOON_XCVR_100HALF;
 			else
 				goto out;
-		} else if(cmd->duplex == DUPLEX_FULL) {
-			if(cmd->speed == SPEED_10)
+		} else if (cmd->duplex == DUPLEX_FULL) {
+			if (speed == SPEED_10)
 				xcvr = TYPHOON_XCVR_10FULL;
-			else if(cmd->speed == SPEED_100)
+			else if (speed == SPEED_100)
 				xcvr = TYPHOON_XCVR_100FULL;
 			else
 				goto out;
@@ -1105,7 +1106,7 @@ typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		tp->speed = 0xff;	/* invalid */
 		tp->duplex = 0xff;	/* invalid */
 	} else {
-		tp->speed = cmd->speed;
+		tp->speed = speed;
 		tp->duplex = cmd->duplex;
 	}
 
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index baf04b0..9a8f116 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -3247,9 +3247,11 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd
 	return 0;
 }
 
-static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int velocity_set_settings(struct net_device *dev,
+				 struct ethtool_cmd *cmd)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 	u32 curr_status;
 	u32 new_status = 0;
 	int ret = 0;
@@ -3258,9 +3260,9 @@ static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd
 	curr_status &= (~VELOCITY_LINK_FAIL);
 
 	new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0);
-	new_status |= ((cmd->speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0);
-	new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
-	new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
+	new_status |= ((speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0);
+	new_status |= ((speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
+	new_status |= ((speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
 	new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0);
 
 	if ((new_status & VELOCITY_AUTONEG_ENABLE) &&
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index 43c4583..ac73246 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -33,7 +33,8 @@ static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info)
 {
 	/* We currently only support 10Gb/FULL */
 	if ((info->autoneg == AUTONEG_ENABLE) ||
-	    (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL))
+	    (ethtool_cmd_speed(info) != SPEED_10000) ||
+	    (info->duplex != DUPLEX_FULL))
 		return -EINVAL;
 
 	return 0;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 7f5379c..c57d187 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -36,8 +36,8 @@ static int port_cost(struct net_device *dev)
 	if (dev->ethtool_ops && dev->ethtool_ops->get_settings) {
 		struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET, };
 
-		if (!dev->ethtool_ops->get_settings(dev, &ecmd)) {
-			switch(ecmd.speed) {
+		if (!dev_ethtool_get_settings(dev, &ecmd)) {
+			switch (ethtool_cmd_speed(&ecmd)) {
 			case SPEED_10000:
 				return 2;
 			case SPEED_1000:
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH 2/5] bnx2x: cosmetics: Using ethtool_cmd_speed() API
From: David Decotigny @ 2011-04-17  0:54 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, Michał Mirosław,
	Stanislaw Gruszka
  Cc: David Decotigny
In-Reply-To: <1303001651-4074-1-git-send-email-decot@google.com>

This updates bnx2x to use the ethtool_cmd_speed() family of functions
(see b11f8d8c in 2.6.27-rc3 aka. "ethtool: Expand ethtool_cmd.speed to
32 bits") to get and set the link speed via ethtool. This allows to
avoid manually accessing ethtool_cmd's speed_hi field.

Signed-off-by: David Decotigny <decot@google.com>
---
 drivers/net/bnx2x/bnx2x_ethtool.c |   25 +++++++++++++------------
 1 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 0a5e88d..e711a22 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -167,6 +167,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+
 	/* Dual Media boards present all available port types */
 	cmd->supported = bp->port.supported[cfg_idx] |
 		(bp->port.supported[cfg_idx ^ 1] &
@@ -176,16 +177,16 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	if ((bp->state == BNX2X_STATE_OPEN) &&
 	    !(bp->flags & MF_FUNC_DIS) &&
 	    (bp->link_vars.link_up)) {
-		cmd->speed = bp->link_vars.line_speed;
+		ethtool_cmd_speed_set(cmd, bp->link_vars.line_speed);
 		cmd->duplex = bp->link_vars.duplex;
 	} else {
-
-		cmd->speed = bp->link_params.req_line_speed[cfg_idx];
+		ethtool_cmd_speed_set(
+			cmd, bp->link_params.req_line_speed[cfg_idx]);
 		cmd->duplex = bp->link_params.req_duplex[cfg_idx];
 	}
 
 	if (IS_MF(bp))
-		cmd->speed = bnx2x_get_mf_speed(bp);
+		ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp));
 
 	if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
 		cmd->port = PORT_TP;
@@ -206,10 +207,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	cmd->maxrxpkt = 0;
 
 	DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
-	   DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %d\n"
+	   DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %u\n"
 	   DP_LEVEL "  duplex %d  port %d  phy_address %d  transceiver %d\n"
 	   DP_LEVEL "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
-	   cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+	   cmd->cmd, cmd->supported, cmd->advertising,
+	   ethtool_cmd_speed(cmd),
 	   cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
 	   cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
 
@@ -226,16 +228,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		return 0;
 
 	DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
-	   "  supported 0x%x  advertising 0x%x  speed %d speed_hi %d\n"
+	   "  supported 0x%x  advertising 0x%x  speed %u\n"
 	   "  duplex %d  port %d  phy_address %d  transceiver %d\n"
 	   "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
-	   cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
-	   cmd->speed_hi,
+	   cmd->cmd, cmd->supported, cmd->advertising,
+	   ethtool_cmd_speed(cmd),
 	   cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
 	   cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
 
-	speed = cmd->speed;
-	speed |= (cmd->speed_hi << 16);
+	speed = ethtool_cmd_speed(cmd);
 
 	if (IS_MF_SI(bp)) {
 		u32 part;
@@ -439,7 +440,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 			break;
 
 		default:
-			DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed);
+			DP(NETIF_MSG_LINK, "Unsupported speed %u\n", speed);
 			return -EINVAL;
 		}
 
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH 1/5] ethtool: cosmetics: enforce const-ness in ethtool_cmd_speed
From: David Decotigny @ 2011-04-17  0:54 UTC (permalink / raw)
  To: David S. Miller, Ben Hutchings, Michał Mirosław,
	Stanislaw Gruszka
  Cc: David Decotigny

The 'ep' argument of ethtool_cmd_speed is not altered: advertise it in
protoype. +Indentation fix. Also add comments to advise using the
ethtool_cmd_speed API to get/set the link speed.

Signed-off-by: David Decotigny <decot@google.com>
---
 include/linux/ethtool.h |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 9de3127..170439e 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -24,7 +24,10 @@ struct ethtool_cmd {
 	__u32	cmd;
 	__u32	supported;	/* Features this interface supports */
 	__u32	advertising;	/* Features this interface advertises */
-	__u16	speed;		/* The forced speed, 10Mb, 100Mb, gigabit */
+	__u16	speed;	        /* The forced speed (lower bits): see
+				 * SPEED_ macros below. Please use
+				 * ethtool_cmd_speed()/_set() to
+				 * access it */
 	__u8	duplex;		/* Duplex, half or full */
 	__u8	port;		/* Which connector port */
 	__u8	phy_address;
@@ -33,7 +36,10 @@ struct ethtool_cmd {
 	__u8	mdio_support;
 	__u32	maxtxpkt;	/* Tx pkts before generating tx int */
 	__u32	maxrxpkt;	/* Rx pkts before generating rx int */
-	__u16	speed_hi;
+	__u16	speed_hi;       /* The forced speed (upper
+				 * bits). Please use
+				 * ethtool_cmd_speed()/_set() to
+				 * access it */
 	__u8	eth_tp_mdix;
 	__u8	reserved2;
 	__u32	lp_advertising;	/* Features the link partner advertises */
@@ -41,14 +47,14 @@ struct ethtool_cmd {
 };
 
 static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
-						__u32 speed)
+					 __u32 speed)
 {
 
 	ep->speed = (__u16)speed;
 	ep->speed_hi = (__u16)(speed >> 16);
 }
 
-static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep)
+static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep)
 {
 	return (ep->speed_hi << 16) | ep->speed;
 }
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH 2/2] via-rhine: Assign random MAC address if necessary
From: Joe Perches @ 2011-04-17  0:15 UTC (permalink / raw)
  To: Alexandru Gagniuc, Roger Luethi; +Cc: David S. Miller, netdev, linux-kernel
In-Reply-To: <cover.1302998994.git.joe@perches.com>

Roger Luethi has had several reports of Rhine NICs providing
an invalid MAC address.  If so, assign a random MAC address so
the hardware can still be used.

Tested as a standalone interface, as carrier for ppp, and as a
bonding slave.

Original-patch-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/net/via-rhine.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 40f394c..7f23ab9 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -838,13 +838,15 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	if (!is_valid_ether_addr(dev->perm_addr)) {
-		rc = -EIO;
-		dev_err(&pdev->dev, "Invalid MAC address\n");
-		goto err_out_unmap;
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		/* Report it and use a random ethernet address instead */
+		netdev_err(dev, "Invalid MAC address: %pM\n", dev->dev_addr);
+		random_ether_addr(dev->dev_addr);
+		netdev_info(dev, "Using random MAC address: %pM\n",
+			    dev->dev_addr);
 	}
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* For Rhine-I/II, phy_id is loaded from EEPROM */
 	if (!phy_id)
-- 
1.7.4.2.g597a6.dirty


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox