diff options
author | Anton Blanchard <anton@samba.org> | 2011-09-07 10:41:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-16 15:26:32 -0400 |
commit | fb82fd204b6e6c67661bbd37df032edafb2da56e (patch) | |
tree | a97071b481dd80b553b98e2158c951e618cecb80 | |
parent | 91aae1e5c407d4fc79f6983e6c6ba04756c004cb (diff) |
ibmveth: Fix checksum offload failure handling
Fix a number of issues in ibmveth_set_csum_offload:
- set_attr6 and clr_attr6 may be used uninitialised
- We store the result of the IPV4 checksum change in ret but overwrite
it in a couple of places before checking it again later. Add ret4
to make it obvious what we are doing.
- We weren't clearing the NETIF_F_IP_CSUM and NETIF_F_IPV6_CSUM flags
if the enable of that hypervisor feature failed.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ibmveth.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 07830f918aed..8dd5fccef725 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -757,7 +757,7 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data) | |||
757 | struct ibmveth_adapter *adapter = netdev_priv(dev); | 757 | struct ibmveth_adapter *adapter = netdev_priv(dev); |
758 | unsigned long set_attr, clr_attr, ret_attr; | 758 | unsigned long set_attr, clr_attr, ret_attr; |
759 | unsigned long set_attr6, clr_attr6; | 759 | unsigned long set_attr6, clr_attr6; |
760 | long ret, ret6; | 760 | long ret, ret4, ret6; |
761 | int rc1 = 0, rc2 = 0; | 761 | int rc1 = 0, rc2 = 0; |
762 | int restart = 0; | 762 | int restart = 0; |
763 | 763 | ||
@@ -770,6 +770,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data) | |||
770 | 770 | ||
771 | set_attr = 0; | 771 | set_attr = 0; |
772 | clr_attr = 0; | 772 | clr_attr = 0; |
773 | set_attr6 = 0; | ||
774 | clr_attr6 = 0; | ||
773 | 775 | ||
774 | if (data) { | 776 | if (data) { |
775 | set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; | 777 | set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; |
@@ -784,16 +786,20 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data) | |||
784 | if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) && | 786 | if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) && |
785 | !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) && | 787 | !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) && |
786 | (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) { | 788 | (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) { |
787 | ret = h_illan_attributes(adapter->vdev->unit_address, clr_attr, | 789 | ret4 = h_illan_attributes(adapter->vdev->unit_address, clr_attr, |
788 | set_attr, &ret_attr); | 790 | set_attr, &ret_attr); |
789 | 791 | ||
790 | if (ret != H_SUCCESS) { | 792 | if (ret4 != H_SUCCESS) { |
791 | netdev_err(dev, "unable to change IPv4 checksum " | 793 | netdev_err(dev, "unable to change IPv4 checksum " |
792 | "offload settings. %d rc=%ld\n", | 794 | "offload settings. %d rc=%ld\n", |
793 | data, ret); | 795 | data, ret4); |
796 | |||
797 | h_illan_attributes(adapter->vdev->unit_address, | ||
798 | set_attr, clr_attr, &ret_attr); | ||
799 | |||
800 | if (data == 1) | ||
801 | dev->features &= ~NETIF_F_IP_CSUM; | ||
794 | 802 | ||
795 | ret = h_illan_attributes(adapter->vdev->unit_address, | ||
796 | set_attr, clr_attr, &ret_attr); | ||
797 | } else { | 803 | } else { |
798 | adapter->fw_ipv4_csum_support = data; | 804 | adapter->fw_ipv4_csum_support = data; |
799 | } | 805 | } |
@@ -804,15 +810,18 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data) | |||
804 | if (ret6 != H_SUCCESS) { | 810 | if (ret6 != H_SUCCESS) { |
805 | netdev_err(dev, "unable to change IPv6 checksum " | 811 | netdev_err(dev, "unable to change IPv6 checksum " |
806 | "offload settings. %d rc=%ld\n", | 812 | "offload settings. %d rc=%ld\n", |
807 | data, ret); | 813 | data, ret6); |
814 | |||
815 | h_illan_attributes(adapter->vdev->unit_address, | ||
816 | set_attr6, clr_attr6, &ret_attr); | ||
817 | |||
818 | if (data == 1) | ||
819 | dev->features &= ~NETIF_F_IPV6_CSUM; | ||
808 | 820 | ||
809 | ret = h_illan_attributes(adapter->vdev->unit_address, | ||
810 | set_attr6, clr_attr6, | ||
811 | &ret_attr); | ||
812 | } else | 821 | } else |
813 | adapter->fw_ipv6_csum_support = data; | 822 | adapter->fw_ipv6_csum_support = data; |
814 | 823 | ||
815 | if (ret == H_SUCCESS || ret6 == H_SUCCESS) | 824 | if (ret4 == H_SUCCESS || ret6 == H_SUCCESS) |
816 | adapter->rx_csum = data; | 825 | adapter->rx_csum = data; |
817 | else | 826 | else |
818 | rc1 = -EIO; | 827 | rc1 = -EIO; |