diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-04-15 00:50:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-15 18:50:40 -0400 |
commit | 569e146396cb3b378d2957b94671bf30cd777c67 (patch) | |
tree | 9a310a2bdbda632a810d35ec9fb854ae5f59d937 /drivers/net | |
parent | c88fcb3d8265cf473c73bc147a2aa21ae03abf67 (diff) |
net: forcedeth: convert to hw_features
This also fixes a race around np->txrxctl_bits while changing RXCSUM offload.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/forcedeth.c | 78 |
1 files changed, 26 insertions, 52 deletions
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 { | |||
774 | u32 driver_data; | 774 | u32 driver_data; |
775 | u32 device_id; | 775 | u32 device_id; |
776 | u32 register_size; | 776 | u32 register_size; |
777 | int rx_csum; | ||
778 | u32 mac_in_use; | 777 | u32 mac_in_use; |
779 | int mgmt_version; | 778 | int mgmt_version; |
780 | int mgmt_sema; | 779 | int mgmt_sema; |
@@ -4480,58 +4479,36 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* | |||
4480 | return 0; | 4479 | return 0; |
4481 | } | 4480 | } |
4482 | 4481 | ||
4483 | static u32 nv_get_rx_csum(struct net_device *dev) | 4482 | static u32 nv_fix_features(struct net_device *dev, u32 features) |
4484 | { | 4483 | { |
4485 | struct fe_priv *np = netdev_priv(dev); | 4484 | /* vlan is dependent on rx checksum offload */ |
4486 | return np->rx_csum != 0; | 4485 | if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) |
4486 | features |= NETIF_F_RXCSUM; | ||
4487 | |||
4488 | return features; | ||
4487 | } | 4489 | } |
4488 | 4490 | ||
4489 | static int nv_set_rx_csum(struct net_device *dev, u32 data) | 4491 | static int nv_set_features(struct net_device *dev, u32 features) |
4490 | { | 4492 | { |
4491 | struct fe_priv *np = netdev_priv(dev); | 4493 | struct fe_priv *np = netdev_priv(dev); |
4492 | u8 __iomem *base = get_hwbase(dev); | 4494 | u8 __iomem *base = get_hwbase(dev); |
4493 | int retcode = 0; | 4495 | u32 changed = dev->features ^ features; |
4494 | 4496 | ||
4495 | if (np->driver_data & DEV_HAS_CHECKSUM) { | 4497 | if (changed & NETIF_F_RXCSUM) { |
4496 | if (data) { | 4498 | spin_lock_irq(&np->lock); |
4497 | np->rx_csum = 1; | ||
4498 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; | ||
4499 | } else { | ||
4500 | np->rx_csum = 0; | ||
4501 | /* vlan is dependent on rx checksum offload */ | ||
4502 | if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE)) | ||
4503 | np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; | ||
4504 | } | ||
4505 | if (netif_running(dev)) { | ||
4506 | spin_lock_irq(&np->lock); | ||
4507 | writel(np->txrxctl_bits, base + NvRegTxRxControl); | ||
4508 | spin_unlock_irq(&np->lock); | ||
4509 | } | ||
4510 | } else { | ||
4511 | return -EINVAL; | ||
4512 | } | ||
4513 | |||
4514 | return retcode; | ||
4515 | } | ||
4516 | 4499 | ||
4517 | static int nv_set_tx_csum(struct net_device *dev, u32 data) | 4500 | if (features & NETIF_F_RXCSUM) |
4518 | { | 4501 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; |
4519 | struct fe_priv *np = netdev_priv(dev); | 4502 | else |
4503 | np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK; | ||
4520 | 4504 | ||
4521 | if (np->driver_data & DEV_HAS_CHECKSUM) | 4505 | if (netif_running(dev)) |
4522 | return ethtool_op_set_tx_csum(dev, data); | 4506 | writel(np->txrxctl_bits, base + NvRegTxRxControl); |
4523 | else | ||
4524 | return -EOPNOTSUPP; | ||
4525 | } | ||
4526 | 4507 | ||
4527 | static int nv_set_sg(struct net_device *dev, u32 data) | 4508 | spin_unlock_irq(&np->lock); |
4528 | { | 4509 | } |
4529 | struct fe_priv *np = netdev_priv(dev); | ||
4530 | 4510 | ||
4531 | if (np->driver_data & DEV_HAS_CHECKSUM) | 4511 | return 0; |
4532 | return ethtool_op_set_sg(dev, data); | ||
4533 | else | ||
4534 | return -EOPNOTSUPP; | ||
4535 | } | 4512 | } |
4536 | 4513 | ||
4537 | static int nv_get_sset_count(struct net_device *dev, int sset) | 4514 | static int nv_get_sset_count(struct net_device *dev, int sset) |
@@ -4896,15 +4873,10 @@ static const struct ethtool_ops ops = { | |||
4896 | .get_regs_len = nv_get_regs_len, | 4873 | .get_regs_len = nv_get_regs_len, |
4897 | .get_regs = nv_get_regs, | 4874 | .get_regs = nv_get_regs, |
4898 | .nway_reset = nv_nway_reset, | 4875 | .nway_reset = nv_nway_reset, |
4899 | .set_tso = nv_set_tso, | ||
4900 | .get_ringparam = nv_get_ringparam, | 4876 | .get_ringparam = nv_get_ringparam, |
4901 | .set_ringparam = nv_set_ringparam, | 4877 | .set_ringparam = nv_set_ringparam, |
4902 | .get_pauseparam = nv_get_pauseparam, | 4878 | .get_pauseparam = nv_get_pauseparam, |
4903 | .set_pauseparam = nv_set_pauseparam, | 4879 | .set_pauseparam = nv_set_pauseparam, |
4904 | .get_rx_csum = nv_get_rx_csum, | ||
4905 | .set_rx_csum = nv_set_rx_csum, | ||
4906 | .set_tx_csum = nv_set_tx_csum, | ||
4907 | .set_sg = nv_set_sg, | ||
4908 | .get_strings = nv_get_strings, | 4880 | .get_strings = nv_get_strings, |
4909 | .get_ethtool_stats = nv_get_ethtool_stats, | 4881 | .get_ethtool_stats = nv_get_ethtool_stats, |
4910 | .get_sset_count = nv_get_sset_count, | 4882 | .get_sset_count = nv_get_sset_count, |
@@ -5235,6 +5207,8 @@ static const struct net_device_ops nv_netdev_ops = { | |||
5235 | .ndo_start_xmit = nv_start_xmit, | 5207 | .ndo_start_xmit = nv_start_xmit, |
5236 | .ndo_tx_timeout = nv_tx_timeout, | 5208 | .ndo_tx_timeout = nv_tx_timeout, |
5237 | .ndo_change_mtu = nv_change_mtu, | 5209 | .ndo_change_mtu = nv_change_mtu, |
5210 | .ndo_fix_features = nv_fix_features, | ||
5211 | .ndo_set_features = nv_set_features, | ||
5238 | .ndo_validate_addr = eth_validate_addr, | 5212 | .ndo_validate_addr = eth_validate_addr, |
5239 | .ndo_set_mac_address = nv_set_mac_address, | 5213 | .ndo_set_mac_address = nv_set_mac_address, |
5240 | .ndo_set_multicast_list = nv_set_multicast, | 5214 | .ndo_set_multicast_list = nv_set_multicast, |
@@ -5251,6 +5225,8 @@ static const struct net_device_ops nv_netdev_ops_optimized = { | |||
5251 | .ndo_start_xmit = nv_start_xmit_optimized, | 5225 | .ndo_start_xmit = nv_start_xmit_optimized, |
5252 | .ndo_tx_timeout = nv_tx_timeout, | 5226 | .ndo_tx_timeout = nv_tx_timeout, |
5253 | .ndo_change_mtu = nv_change_mtu, | 5227 | .ndo_change_mtu = nv_change_mtu, |
5228 | .ndo_fix_features = nv_fix_features, | ||
5229 | .ndo_set_features = nv_set_features, | ||
5254 | .ndo_validate_addr = eth_validate_addr, | 5230 | .ndo_validate_addr = eth_validate_addr, |
5255 | .ndo_set_mac_address = nv_set_mac_address, | 5231 | .ndo_set_mac_address = nv_set_mac_address, |
5256 | .ndo_set_multicast_list = nv_set_multicast, | 5232 | .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 | |||
5364 | np->pkt_limit = NV_PKTLIMIT_2; | 5340 | np->pkt_limit = NV_PKTLIMIT_2; |
5365 | 5341 | ||
5366 | if (id->driver_data & DEV_HAS_CHECKSUM) { | 5342 | if (id->driver_data & DEV_HAS_CHECKSUM) { |
5367 | np->rx_csum = 1; | ||
5368 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; | 5343 | np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; |
5369 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 5344 | dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | |
5370 | dev->features |= NETIF_F_TSO; | 5345 | NETIF_F_TSO | NETIF_F_RXCSUM; |
5371 | dev->features |= NETIF_F_GRO; | 5346 | dev->features |= dev->hw_features; |
5372 | } | 5347 | } |
5373 | 5348 | ||
5374 | np->vlanctl_bits = 0; | 5349 | np->vlanctl_bits = 0; |
@@ -5384,7 +5359,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5384 | np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ; | 5359 | np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ; |
5385 | } | 5360 | } |
5386 | 5361 | ||
5387 | |||
5388 | err = -ENOMEM; | 5362 | err = -ENOMEM; |
5389 | np->base = ioremap(addr, np->register_size); | 5363 | np->base = ioremap(addr, np->register_size); |
5390 | if (!np->base) | 5364 | if (!np->base) |