From 569e146396cb3b378d2957b94671bf30cd777c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 15 Apr 2011 04:50:49 +0000 Subject: net: forcedeth: convert to hw_features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This also fixes a race around np->txrxctl_bits while changing RXCSUM offload. Signed-off-by: Michał Mirosław Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 78 +++++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) (limited to 'drivers/net/forcedeth.c') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d5ab4dad5051..ec9a32d01e61 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -774,7 +774,6 @@ struct fe_priv { u32 driver_data; u32 device_id; u32 register_size; - int rx_csum; u32 mac_in_use; int mgmt_version; int mgmt_sema; @@ -4480,58 +4479,36 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* return 0; } -static u32 nv_get_rx_csum(struct net_device *dev) +static u32 nv_fix_features(struct net_device *dev, u32 features) { - struct fe_priv *np = netdev_priv(dev); - return np->rx_csum != 0; + /* vlan is dependent on rx checksum offload */ + if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) + features |= NETIF_F_RXCSUM; + + return features; } -static int nv_set_rx_csum(struct net_device *dev, u32 data) +static int nv_set_features(struct net_device *dev, u32 features) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - int retcode = 0; + u32 changed = dev->features ^ features; - if (np->driver_data & DEV_HAS_CHECKSUM) { - if (data) { - np->rx_csum = 1; - np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; - } else { - np->rx_csum = 0; - /* vlan is dependent on rx checksum offload */ - if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) - np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; - } - if (netif_running(dev)) { - spin_lock_irq(&np->lock); - writel(np->txrxctl_bits, base + NvRegTxRxControl); - spin_unlock_irq(&np->lock); - } - } else { - return -EINVAL; - } - - return retcode; -} + if (changed & NETIF_F_RXCSUM) { + spin_lock_irq(&np->lock); -static int nv_set_tx_csum(struct net_device *dev, u32 data) -{ - struct fe_priv *np = netdev_priv(dev); + if (features & NETIF_F_RXCSUM) + np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; + else + np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; - if (np->driver_data & DEV_HAS_CHECKSUM) - return ethtool_op_set_tx_csum(dev, data); - else - return -EOPNOTSUPP; -} + if (netif_running(dev)) + writel(np->txrxctl_bits, base + NvRegTxRxControl); -static int nv_set_sg(struct net_device *dev, u32 data) -{ - struct fe_priv *np = netdev_priv(dev); + spin_unlock_irq(&np->lock); + } - if (np->driver_data & DEV_HAS_CHECKSUM) - return ethtool_op_set_sg(dev, data); - else - return -EOPNOTSUPP; + return 0; } static int nv_get_sset_count(struct net_device *dev, int sset) @@ -4896,15 +4873,10 @@ static const struct ethtool_ops ops = { .get_regs_len = nv_get_regs_len, .get_regs = nv_get_regs, .nway_reset = nv_nway_reset, - .set_tso = nv_set_tso, .get_ringparam = nv_get_ringparam, .set_ringparam = nv_set_ringparam, .get_pauseparam = nv_get_pauseparam, .set_pauseparam = nv_set_pauseparam, - .get_rx_csum = nv_get_rx_csum, - .set_rx_csum = nv_set_rx_csum, - .set_tx_csum = nv_set_tx_csum, - .set_sg = nv_set_sg, .get_strings = nv_get_strings, .get_ethtool_stats = nv_get_ethtool_stats, .get_sset_count = nv_get_sset_count, @@ -5235,6 +5207,8 @@ static const struct net_device_ops nv_netdev_ops = { .ndo_start_xmit = nv_start_xmit, .ndo_tx_timeout = nv_tx_timeout, .ndo_change_mtu = nv_change_mtu, + .ndo_fix_features = nv_fix_features, + .ndo_set_features = nv_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, @@ -5251,6 +5225,8 @@ static const struct net_device_ops nv_netdev_ops_optimized = { .ndo_start_xmit = nv_start_xmit_optimized, .ndo_tx_timeout = nv_tx_timeout, .ndo_change_mtu = nv_change_mtu, + .ndo_fix_features = nv_fix_features, + .ndo_set_features = nv_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = nv_set_mac_address, .ndo_set_multicast_list = nv_set_multicast, @@ -5364,11 +5340,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->pkt_limit = NV_PKTLIMIT_2; if (id->driver_data & DEV_HAS_CHECKSUM) { - np->rx_csum = 1; np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; - dev->features |= NETIF_F_TSO; - dev->features |= NETIF_F_GRO; + dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | + NETIF_F_TSO | NETIF_F_RXCSUM; + dev->features |= dev->hw_features; } np->vlanctl_bits = 0; @@ -5384,7 +5359,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ; } - err = -ENOMEM; np->base = ioremap(addr, np->register_size); if (!np->base) -- cgit v1.2.1 From 985762b2df4bcb4accc29fda76fc863dd79b8b58 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Tue, 19 Apr 2011 15:31:20 +0000 Subject: net: forcedeth: fix compile warning of not used nv_set_tso function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the below compile warning: drivers/net/forcedeth.c:4266: warning: ‘nv_set_tso’ defined but not used commit 569e146 converts forcedeth driver to use hw_features. So, implement function of .set_tso is abandoned. Signed-off-by: Shan Wei Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/net/forcedeth.c') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index ec9a32d01e61..0e1c76a8c045 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -4263,16 +4263,6 @@ static int nv_nway_reset(struct net_device *dev) return ret; } -static int nv_set_tso(struct net_device *dev, u32 value) -{ - struct fe_priv *np = netdev_priv(dev); - - if ((np->driver_data & DEV_HAS_CHECKSUM)) - return ethtool_op_set_tso(dev, value); - else - return -EOPNOTSUPP; -} - static void nv_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) { struct fe_priv *np = netdev_priv(dev); -- cgit v1.2.1 From 25db0338813a8915457636b1f6abe6a28fa73f8d Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 27 Apr 2011 18:32:39 +0000 Subject: ethtool: Use full 32 bit speed range in ethtool's set_settings 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 drivers compiled with make allyesconfig on x86_64 have been updated. Signed-off-by: David Decotigny Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net/forcedeth.c') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 0e1c76a8c045..d24b3f3e646b 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 */ -- cgit v1.2.1 From 707394972093e2056e1e8cc39be19cf9bcb3e7b3 Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Wed, 27 Apr 2011 18:32:40 +0000 Subject: ethtool: cosmetic: Use ethtool ethtool_cmd_speed API This updates the network drivers so that they don't access the ethtool_cmd::speed field directly, but use ethtool_cmd_speed() instead. For most of the drivers, these changes are purely cosmetic and don't fix any problem, such as for those 1GbE/10GbE drivers that indirectly call their own ethtool get_settings()/mii_ethtool_gset(). The changes are meant to enforce code consistency and provide robustness with future larger throughputs, at the expense of a few CPU cycles for each ethtool operation. All 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 Signed-off-by: David S. Miller --- drivers/net/forcedeth.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/net/forcedeth.c') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index d24b3f3e646b..d09e8b0add01 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; -- cgit v1.2.1