diff options
| author | Thomas Falcon <tlfalcon@linux.vnet.ibm.com> | 2015-04-29 16:25:47 -0500 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-04-30 16:33:46 -0400 | 
| commit | 9c7e8bc584f52ae42f4528ca459f711ad38a130f (patch) | |
| tree | d793e322f487b3aec97d7f9b794825dc505dd994 /drivers/net/ethernet/ibm/ibmveth.c | |
| parent | 92ec8279f5143b29c5ed8525f7b45df44dd8753c (diff) | |
ibmveth: Add support for Large Receive Offload
Enables receiving large packets from other LPARs. These packets
have a -1 IP header checksum, so we must recalculate to have
a valid checksum.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ibm/ibmveth.c')
| -rw-r--r-- | drivers/net/ethernet/ibm/ibmveth.c | 17 | 
1 files changed, 16 insertions, 1 deletions
| diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 33ffd349fb05..29bbb628d712 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -101,6 +101,7 @@ struct ibmveth_stat ibmveth_stats[] = {  	{ "fw_enabled_ipv4_csum", IBMVETH_STAT_OFF(fw_ipv4_csum_support) },  	{ "fw_enabled_ipv6_csum", IBMVETH_STAT_OFF(fw_ipv6_csum_support) },  	{ "tx_large_packets", IBMVETH_STAT_OFF(tx_large_packets) }, +	{ "rx_large_packets", IBMVETH_STAT_OFF(rx_large_packets) }  };  /* simple methods of getting data from the current rxq entry */ @@ -1094,6 +1095,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)  	struct net_device *netdev = adapter->netdev;  	int frames_processed = 0;  	unsigned long lpar_rc; +	struct iphdr *iph;  restart_poll:  	while (frames_processed < budget) { @@ -1136,8 +1138,21 @@ restart_poll:  			skb_put(skb, length);  			skb->protocol = eth_type_trans(skb, netdev); -			if (csum_good) +			if (csum_good) {  				skb->ip_summed = CHECKSUM_UNNECESSARY; +				if (be16_to_cpu(skb->protocol) == ETH_P_IP) { +					iph = (struct iphdr *)skb->data; + +					/* If the IP checksum is not offloaded and if the packet +					 *  is large send, the checksum must be rebuilt. +					 */ +					if (iph->check == 0xffff) { +						iph->check = 0; +						iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); +						adapter->rx_large_packets++; +					} +				} +			}  			napi_gro_receive(napi, skb);	/* send it up */ | 
