diff options
author | Jakub Kicinski <kuba@kernel.org> | 2020-10-15 05:16:36 +0200 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-10-15 05:18:08 +0200 |
commit | 15f0d2922dceabd9e622feae26e88a7d3b2d6ba0 (patch) | |
tree | 0aee47ec3e5923f8c738c877d17b7efbc7a016a1 | |
parent | cxgb4: handle 4-tuple PEDIT to NAT mode translation (diff) | |
parent | ibmveth: Identify ingress large send packets. (diff) | |
download | linux-15f0d2922dceabd9e622feae26e88a7d3b2d6ba0.tar.xz linux-15f0d2922dceabd9e622feae26e88a7d3b2d6ba0.zip |
Merge branch 'ibmveth-gso-fix'
David Wilder says:
====================
ibmveth gso fix
The ibmveth driver is a virtual Ethernet driver used on IBM pSeries systems.
Gso packets can be sent between LPARS (virtual hosts) without segmentation,
by flagging gso packets using one of two methods depending on the firmware
version. Some gso packet were not correctly identified by the receiver.
This patch-set corrects this issue.
V2:
- Added fix tags.
- Byteswap the constant at compilation time.
- Updated the commit message to clarify what frame validation is performed
by the hypervisor.
====================
Link: https://lore.kernel.org/r/20201013232014.26044-1-dwilder@us.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | drivers/net/ethernet/ibm/ibmveth.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index c5c732601e35..7ef3369953b6 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -1349,6 +1349,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) int offset = ibmveth_rxq_frame_offset(adapter); int csum_good = ibmveth_rxq_csum_good(adapter); int lrg_pkt = ibmveth_rxq_large_packet(adapter); + __sum16 iph_check = 0; skb = ibmveth_rxq_get_buffer(adapter); @@ -1385,16 +1386,26 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) skb_put(skb, length); skb->protocol = eth_type_trans(skb, netdev); - if (csum_good) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - ibmveth_rx_csum_helper(skb, adapter); + /* PHYP without PLSO support places a -1 in the ip + * checksum for large send frames. + */ + if (skb->protocol == cpu_to_be16(ETH_P_IP)) { + struct iphdr *iph = (struct iphdr *)skb->data; + + iph_check = iph->check; } - if (length > netdev->mtu + ETH_HLEN) { + if ((length > netdev->mtu + ETH_HLEN) || + lrg_pkt || iph_check == 0xffff) { ibmveth_rx_mss_helper(skb, mss, lrg_pkt); adapter->rx_large_packets++; } + if (csum_good) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + ibmveth_rx_csum_helper(skb, adapter); + } + napi_gro_receive(napi, skb); /* send it up */ netdev->stats.rx_packets++; |