diff options
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be_main.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 5c378b5e8e41..ae2f6b58ba25 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -637,6 +637,22 @@ static void be_rx_stats_update(struct be_adapter *adapter, | |||
637 | stats->be_rx_bytes += pktsize; | 637 | stats->be_rx_bytes += pktsize; |
638 | } | 638 | } |
639 | 639 | ||
640 | static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) | ||
641 | { | ||
642 | u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk; | ||
643 | |||
644 | l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); | ||
645 | ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp); | ||
646 | ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp); | ||
647 | if (ip_version) { | ||
648 | tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); | ||
649 | udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp); | ||
650 | } | ||
651 | ipv6_chk = (ip_version && (tcpf || udpf)); | ||
652 | |||
653 | return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true; | ||
654 | } | ||
655 | |||
640 | static struct be_rx_page_info * | 656 | static struct be_rx_page_info * |
641 | get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) | 657 | get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) |
642 | { | 658 | { |
@@ -752,9 +768,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
752 | { | 768 | { |
753 | struct sk_buff *skb; | 769 | struct sk_buff *skb; |
754 | u32 vtp, vid; | 770 | u32 vtp, vid; |
755 | int l4_cksm; | ||
756 | 771 | ||
757 | l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); | ||
758 | vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | 772 | vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); |
759 | 773 | ||
760 | skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN); | 774 | skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN); |
@@ -769,10 +783,10 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
769 | 783 | ||
770 | skb_fill_rx_data(adapter, skb, rxcp); | 784 | skb_fill_rx_data(adapter, skb, rxcp); |
771 | 785 | ||
772 | if (l4_cksm && adapter->rx_csum) | 786 | if (do_pkt_csum(rxcp, adapter->rx_csum)) |
773 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
774 | else | ||
775 | skb->ip_summed = CHECKSUM_NONE; | 787 | skb->ip_summed = CHECKSUM_NONE; |
788 | else | ||
789 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
776 | 790 | ||
777 | skb->truesize = skb->len + sizeof(struct sk_buff); | 791 | skb->truesize = skb->len + sizeof(struct sk_buff); |
778 | skb->protocol = eth_type_trans(skb, adapter->netdev); | 792 | skb->protocol = eth_type_trans(skb, adapter->netdev); |
@@ -1626,10 +1640,12 @@ static void be_netdev_init(struct net_device *netdev) | |||
1626 | 1640 | ||
1627 | netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | | 1641 | netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | |
1628 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM | | 1642 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM | |
1629 | NETIF_F_IPV6_CSUM | NETIF_F_TSO6; | 1643 | NETIF_F_IPV6_CSUM; |
1630 | 1644 | ||
1631 | netdev->flags |= IFF_MULTICAST; | 1645 | netdev->flags |= IFF_MULTICAST; |
1632 | 1646 | ||
1647 | adapter->rx_csum = true; | ||
1648 | |||
1633 | BE_SET_NETDEV_OPS(netdev, &be_netdev_ops); | 1649 | BE_SET_NETDEV_OPS(netdev, &be_netdev_ops); |
1634 | 1650 | ||
1635 | SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); | 1651 | SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); |