diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ibmveth.c | 96 |
1 files changed, 27 insertions, 69 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 5522d459654..4855f1fdff5 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -729,45 +729,24 @@ static void netdev_get_drvinfo(struct net_device *dev, sizeof(info->version) - 1); } -static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data) +static u32 ibmveth_fix_features(struct net_device *dev, u32 features) { - struct ibmveth_adapter *adapter = netdev_priv(dev); - - if (data) { - adapter->rx_csum = 1; - } else { - /* - * Since the ibmveth firmware interface does not have the - * concept of separate tx/rx checksum offload enable, if rx - * checksum is disabled we also have to disable tx checksum - * offload. Once we disable rx checksum offload, we are no - * longer allowed to send tx buffers that are not properly - * checksummed. - */ - adapter->rx_csum = 0; - dev->features &= ~NETIF_F_IP_CSUM; - dev->features &= ~NETIF_F_IPV6_CSUM; - } -} + /* + * Since the ibmveth firmware interface does not have the + * concept of separate tx/rx checksum offload enable, if rx + * checksum is disabled we also have to disable tx checksum + * offload. Once we disable rx checksum offload, we are no + * longer allowed to send tx buffers that are not properly + * checksummed. + */ -static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data) -{ - struct ibmveth_adapter *adapter = netdev_priv(dev); + if (!(features & NETIF_F_RXCSUM)) + features &= ~NETIF_F_ALL_CSUM; - if (data) { - if (adapter->fw_ipv4_csum_support) - dev->features |= NETIF_F_IP_CSUM; - if (adapter->fw_ipv6_csum_support) - dev->features |= NETIF_F_IPV6_CSUM; - adapter->rx_csum = 1; - } else { - dev->features &= ~NETIF_F_IP_CSUM; - dev->features &= ~NETIF_F_IPV6_CSUM; - } + return features; } -static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, - void (*done) (struct net_device *, u32)) +static int ibmveth_set_csum_offload(struct net_device *dev, u32 data) { struct ibmveth_adapter *adapter = netdev_priv(dev); unsigned long set_attr, clr_attr, ret_attr; @@ -827,8 +806,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, } else adapter->fw_ipv6_csum_support = data; - if (ret == H_SUCCESS || ret6 == H_SUCCESS) - done(dev, data); + if (ret != H_SUCCESS || ret6 != H_SUCCESS) + adapter->rx_csum = data; else rc1 = -EIO; } else { @@ -844,41 +823,22 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, return rc1 ? rc1 : rc2; } -static int ibmveth_set_rx_csum(struct net_device *dev, u32 data) +static int ibmveth_set_features(struct net_device *dev, u32 features) { struct ibmveth_adapter *adapter = netdev_priv(dev); + int rx_csum = !!(features & NETIF_F_RXCSUM); + int rc; - if ((data && adapter->rx_csum) || (!data && !adapter->rx_csum)) - return 0; - - return ibmveth_set_csum_offload(dev, data, ibmveth_set_rx_csum_flags); -} - -static int ibmveth_set_tx_csum(struct net_device *dev, u32 data) -{ - struct ibmveth_adapter *adapter = netdev_priv(dev); - int rc = 0; - - if (data && (dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) - return 0; - if (!data && !(dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) + if (rx_csum == adapter->rx_csum) return 0; - if (data && !adapter->rx_csum) - rc = ibmveth_set_csum_offload(dev, data, - ibmveth_set_tx_csum_flags); - else - ibmveth_set_tx_csum_flags(dev, data); + rc = ibmveth_set_csum_offload(dev, rx_csum); + if (rc && !adapter->rx_csum) + dev->features = features & ~(NETIF_F_ALL_CSUM | NETIF_F_RXCSUM); return rc; } -static u32 ibmveth_get_rx_csum(struct net_device *dev) -{ - struct ibmveth_adapter *adapter = netdev_priv(dev); - return adapter->rx_csum; -} - static void ibmveth_get_strings(struct net_device *dev, u32 stringset, u8 *data) { int i; @@ -914,13 +874,9 @@ static const struct ethtool_ops netdev_ethtool_ops = { .get_drvinfo = netdev_get_drvinfo, .get_settings = netdev_get_settings, .get_link = ethtool_op_get_link, - .set_tx_csum = ibmveth_set_tx_csum, - .get_rx_csum = ibmveth_get_rx_csum, - .set_rx_csum = ibmveth_set_rx_csum, .get_strings = ibmveth_get_strings, .get_sset_count = ibmveth_get_sset_count, .get_ethtool_stats = ibmveth_get_ethtool_stats, - .set_sg = ethtool_op_set_sg, }; static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -1345,6 +1301,8 @@ static const struct net_device_ops ibmveth_netdev_ops = { .ndo_set_multicast_list = ibmveth_set_multicast_list, .ndo_do_ioctl = ibmveth_ioctl, .ndo_change_mtu = ibmveth_change_mtu, + .ndo_fix_features = ibmveth_fix_features, + .ndo_set_features = ibmveth_set_features, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -1412,7 +1370,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, netdev->netdev_ops = &ibmveth_netdev_ops; netdev->ethtool_ops = &netdev_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->dev); - netdev->features |= NETIF_F_SG; + netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | + NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + netdev->features |= netdev->hw_features; memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); @@ -1437,8 +1397,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, netdev_dbg(netdev, "registering netdev...\n"); - ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags); - rc = register_netdev(netdev); if (rc) { |