aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ibmveth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ibmveth.c')
-rw-r--r--drivers/net/ibmveth.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 3e6679269400..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;
@@ -930,6 +939,7 @@ static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
930 union ibmveth_buf_desc descs[6]; 939 union ibmveth_buf_desc descs[6];
931 int last, i; 940 int last, i;
932 int force_bounce = 0; 941 int force_bounce = 0;
942 dma_addr_t dma_addr;
933 943
934 /* 944 /*
935 * veth handles a maximum of 6 segments including the header, so 945 * veth handles a maximum of 6 segments including the header, so
@@ -994,17 +1004,16 @@ retry_bounce:
994 } 1004 }
995 1005
996 /* Map the header */ 1006 /* Map the header */
997 descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data, 1007 dma_addr = dma_map_single(&adapter->vdev->dev, skb->data,
998 skb_headlen(skb), 1008 skb_headlen(skb), DMA_TO_DEVICE);
999 DMA_TO_DEVICE); 1009 if (dma_mapping_error(&adapter->vdev->dev, dma_addr))
1000 if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address))
1001 goto map_failed; 1010 goto map_failed;
1002 1011
1003 descs[0].fields.flags_len = desc_flags | skb_headlen(skb); 1012 descs[0].fields.flags_len = desc_flags | skb_headlen(skb);
1013 descs[0].fields.address = dma_addr;
1004 1014
1005 /* Map the frags */ 1015 /* Map the frags */
1006 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1016 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1007 unsigned long dma_addr;
1008 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 1017 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1009 1018
1010 dma_addr = dma_map_page(&adapter->vdev->dev, frag->page, 1019 dma_addr = dma_map_page(&adapter->vdev->dev, frag->page,
@@ -1026,7 +1035,12 @@ retry_bounce:
1026 netdev->stats.tx_bytes += skb->len; 1035 netdev->stats.tx_bytes += skb->len;
1027 } 1036 }
1028 1037
1029 for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++) 1038 dma_unmap_single(&adapter->vdev->dev,
1039 descs[0].fields.address,
1040 descs[0].fields.flags_len & IBMVETH_BUF_LEN_MASK,
1041 DMA_TO_DEVICE);
1042
1043 for (i = 1; i < skb_shinfo(skb)->nr_frags + 1; i++)
1030 dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, 1044 dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address,
1031 descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, 1045 descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK,
1032 DMA_TO_DEVICE); 1046 DMA_TO_DEVICE);