diff options
Diffstat (limited to 'drivers/net/vmxnet3')
-rw-r--r-- | drivers/net/vmxnet3/vmxnet3_drv.c | 26 | ||||
-rw-r--r-- | drivers/net/vmxnet3/vmxnet3_ethtool.c | 74 |
2 files changed, 51 insertions, 49 deletions
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 2440e30c5bd1..0572f6a9bdb6 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1572,6 +1572,30 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb, return (hlen + (hdr.tcp->doff << 2)); } +static void +vmxnet3_lro_tunnel(struct sk_buff *skb, __be16 ip_proto) +{ + struct udphdr *uh = NULL; + + if (ip_proto == htons(ETH_P_IP)) { + struct iphdr *iph = (struct iphdr *)skb->data; + + if (iph->protocol == IPPROTO_UDP) + uh = (struct udphdr *)(iph + 1); + } else { + struct ipv6hdr *iph = (struct ipv6hdr *)skb->data; + + if (iph->nexthdr == IPPROTO_UDP) + uh = (struct udphdr *)(iph + 1); + } + if (uh) { + if (uh->check) + skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL_CSUM; + else + skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL; + } +} + static int vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter, int quota) @@ -1885,6 +1909,8 @@ sop_done: if (segCnt != 0 && mss != 0) { skb_shinfo(skb)->gso_type = rcd->v4 ? SKB_GSO_TCPV4 : SKB_GSO_TCPV6; + if (encap_lro) + vmxnet3_lro_tunnel(skb, skb->protocol); skb_shinfo(skb)->gso_size = mss; skb_shinfo(skb)->gso_segs = segCnt; } else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) { diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index 471f91c4204a..cc4d7573839d 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -833,11 +833,19 @@ out: } static int -vmxnet3_get_rss_hash_opts(struct vmxnet3_adapter *adapter, - struct ethtool_rxnfc *info) +vmxnet3_get_rss_hash_opts(struct net_device *netdev, + struct ethtool_rxfh_fields *info) { + struct vmxnet3_adapter *adapter = netdev_priv(netdev); enum Vmxnet3_RSSField rss_fields; + if (!VMXNET3_VERSION_GE_4(adapter)) + return -EOPNOTSUPP; +#ifdef VMXNET3_RSS + if (!adapter->rss) + return -EOPNOTSUPP; +#endif + if (netif_running(adapter->netdev)) { unsigned long flags; @@ -900,10 +908,20 @@ vmxnet3_get_rss_hash_opts(struct vmxnet3_adapter *adapter, static int vmxnet3_set_rss_hash_opt(struct net_device *netdev, - struct vmxnet3_adapter *adapter, - struct ethtool_rxnfc *nfc) + const struct ethtool_rxfh_fields *nfc, + struct netlink_ext_ack *extack) { - enum Vmxnet3_RSSField rss_fields = adapter->rss_fields; + struct vmxnet3_adapter *adapter = netdev_priv(netdev); + enum Vmxnet3_RSSField rss_fields; + + if (!VMXNET3_VERSION_GE_4(adapter)) + return -EOPNOTSUPP; +#ifdef VMXNET3_RSS + if (!adapter->rss) + return -EOPNOTSUPP; +#endif + + rss_fields = adapter->rss_fields; /* RSS does not support anything other than hashing * to queues on src and dst IPs and ports @@ -1074,54 +1092,11 @@ vmxnet3_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info, case ETHTOOL_GRXRINGS: info->data = adapter->num_rx_queues; break; - case ETHTOOL_GRXFH: - if (!VMXNET3_VERSION_GE_4(adapter)) { - err = -EOPNOTSUPP; - break; - } -#ifdef VMXNET3_RSS - if (!adapter->rss) { - err = -EOPNOTSUPP; - break; - } -#endif - err = vmxnet3_get_rss_hash_opts(adapter, info); - break; - default: - err = -EOPNOTSUPP; - break; - } - - return err; -} - -static int -vmxnet3_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *info) -{ - struct vmxnet3_adapter *adapter = netdev_priv(netdev); - int err = 0; - - if (!VMXNET3_VERSION_GE_4(adapter)) { - err = -EOPNOTSUPP; - goto done; - } -#ifdef VMXNET3_RSS - if (!adapter->rss) { - err = -EOPNOTSUPP; - goto done; - } -#endif - - switch (info->cmd) { - case ETHTOOL_SRXFH: - err = vmxnet3_set_rss_hash_opt(netdev, adapter, info); - break; default: err = -EOPNOTSUPP; break; } -done: return err; } @@ -1361,12 +1336,13 @@ static const struct ethtool_ops vmxnet3_ethtool_ops = { .get_ringparam = vmxnet3_get_ringparam, .set_ringparam = vmxnet3_set_ringparam, .get_rxnfc = vmxnet3_get_rxnfc, - .set_rxnfc = vmxnet3_set_rxnfc, #ifdef VMXNET3_RSS .get_rxfh_indir_size = vmxnet3_get_rss_indir_size, .get_rxfh = vmxnet3_get_rss, .set_rxfh = vmxnet3_set_rss, #endif + .get_rxfh_fields = vmxnet3_get_rss_hash_opts, + .set_rxfh_fields = vmxnet3_set_rss_hash_opt, .get_link_ksettings = vmxnet3_get_link_ksettings, .get_channels = vmxnet3_get_channels, }; |