| .. | .. |
|---|
| 39 | 39 | #include <linux/slab.h> |
|---|
| 40 | 40 | #include <linux/hash.h> |
|---|
| 41 | 41 | #include <net/ip.h> |
|---|
| 42 | | -#include <net/busy_poll.h> |
|---|
| 43 | 42 | #include <net/vxlan.h> |
|---|
| 44 | 43 | #include <net/devlink.h> |
|---|
| 45 | 44 | |
|---|
| .. | .. |
|---|
| 52 | 51 | #include "en_port.h" |
|---|
| 53 | 52 | |
|---|
| 54 | 53 | #define MLX4_EN_MAX_XDP_MTU ((int)(PAGE_SIZE - ETH_HLEN - (2 * VLAN_HLEN) - \ |
|---|
| 55 | | - XDP_PACKET_HEADROOM)) |
|---|
| 54 | + XDP_PACKET_HEADROOM - \ |
|---|
| 55 | + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))) |
|---|
| 56 | 56 | |
|---|
| 57 | 57 | int mlx4_en_setup_tc(struct net_device *dev, u8 up) |
|---|
| 58 | 58 | { |
|---|
| .. | .. |
|---|
| 1367 | 1367 | } |
|---|
| 1368 | 1368 | } |
|---|
| 1369 | 1369 | |
|---|
| 1370 | | -static void mlx4_en_tx_timeout(struct net_device *dev) |
|---|
| 1370 | +static void mlx4_en_tx_timeout(struct net_device *dev, unsigned int txqueue) |
|---|
| 1371 | 1371 | { |
|---|
| 1372 | 1372 | struct mlx4_en_priv *priv = netdev_priv(dev); |
|---|
| 1373 | 1373 | struct mlx4_en_dev *mdev = priv->mdev; |
|---|
| 1374 | | - int i; |
|---|
| 1374 | + struct mlx4_en_tx_ring *tx_ring = priv->tx_ring[TX][txqueue]; |
|---|
| 1375 | 1375 | |
|---|
| 1376 | 1376 | if (netif_msg_timer(priv)) |
|---|
| 1377 | 1377 | en_warn(priv, "Tx timeout called on port:%d\n", priv->port); |
|---|
| 1378 | 1378 | |
|---|
| 1379 | | - for (i = 0; i < priv->tx_ring_num[TX]; i++) { |
|---|
| 1380 | | - struct mlx4_en_tx_ring *tx_ring = priv->tx_ring[TX][i]; |
|---|
| 1381 | | - |
|---|
| 1382 | | - if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, i))) |
|---|
| 1383 | | - continue; |
|---|
| 1384 | | - en_warn(priv, "TX timeout on queue: %d, QP: 0x%x, CQ: 0x%x, Cons: 0x%x, Prod: 0x%x\n", |
|---|
| 1385 | | - i, tx_ring->qpn, tx_ring->sp_cqn, |
|---|
| 1386 | | - tx_ring->cons, tx_ring->prod); |
|---|
| 1387 | | - } |
|---|
| 1379 | + en_warn(priv, "TX timeout on queue: %d, QP: 0x%x, CQ: 0x%x, Cons: 0x%x, Prod: 0x%x\n", |
|---|
| 1380 | + txqueue, tx_ring->qpn, tx_ring->sp_cqn, |
|---|
| 1381 | + tx_ring->cons, tx_ring->prod); |
|---|
| 1388 | 1382 | |
|---|
| 1389 | 1383 | priv->port_stats.tx_timeout++; |
|---|
| 1390 | 1384 | if (!test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state)) { |
|---|
| .. | .. |
|---|
| 1828 | 1822 | queue_work(mdev->workqueue, &priv->rx_mode_task); |
|---|
| 1829 | 1823 | |
|---|
| 1830 | 1824 | if (priv->mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) |
|---|
| 1831 | | - udp_tunnel_get_rx_info(dev); |
|---|
| 1825 | + udp_tunnel_nic_reset_ntf(dev); |
|---|
| 1832 | 1826 | |
|---|
| 1833 | 1827 | priv->port_up = true; |
|---|
| 1834 | 1828 | |
|---|
| .. | .. |
|---|
| 2308 | 2302 | lockdep_is_held(&priv->mdev->state_lock)); |
|---|
| 2309 | 2303 | |
|---|
| 2310 | 2304 | if (xdp_prog && carry_xdp_prog) { |
|---|
| 2311 | | - xdp_prog = bpf_prog_add(xdp_prog, tmp->rx_ring_num); |
|---|
| 2312 | | - if (IS_ERR(xdp_prog)) { |
|---|
| 2313 | | - mlx4_en_free_resources(tmp); |
|---|
| 2314 | | - return PTR_ERR(xdp_prog); |
|---|
| 2315 | | - } |
|---|
| 2305 | + bpf_prog_add(xdp_prog, tmp->rx_ring_num); |
|---|
| 2316 | 2306 | for (i = 0; i < tmp->rx_ring_num; i++) |
|---|
| 2317 | 2307 | rcu_assign_pointer(tmp->rx_ring[i]->xdp_prog, |
|---|
| 2318 | 2308 | xdp_prog); |
|---|
| .. | .. |
|---|
| 2652 | 2642 | return 0; |
|---|
| 2653 | 2643 | } |
|---|
| 2654 | 2644 | |
|---|
| 2655 | | -static void mlx4_en_add_vxlan_offloads(struct work_struct *work) |
|---|
| 2645 | +static int mlx4_udp_tunnel_sync(struct net_device *dev, unsigned int table) |
|---|
| 2656 | 2646 | { |
|---|
| 2647 | + struct mlx4_en_priv *priv = netdev_priv(dev); |
|---|
| 2648 | + struct udp_tunnel_info ti; |
|---|
| 2657 | 2649 | int ret; |
|---|
| 2658 | | - struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, |
|---|
| 2659 | | - vxlan_add_task); |
|---|
| 2650 | + |
|---|
| 2651 | + udp_tunnel_nic_get_port(dev, table, 0, &ti); |
|---|
| 2652 | + priv->vxlan_port = ti.port; |
|---|
| 2660 | 2653 | |
|---|
| 2661 | 2654 | ret = mlx4_config_vxlan_port(priv->mdev->dev, priv->vxlan_port); |
|---|
| 2662 | 2655 | if (ret) |
|---|
| 2663 | | - goto out; |
|---|
| 2656 | + return ret; |
|---|
| 2664 | 2657 | |
|---|
| 2665 | | - ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port, |
|---|
| 2666 | | - VXLAN_STEER_BY_OUTER_MAC, 1); |
|---|
| 2667 | | -out: |
|---|
| 2668 | | - if (ret) { |
|---|
| 2669 | | - en_err(priv, "failed setting L2 tunnel configuration ret %d\n", ret); |
|---|
| 2670 | | - return; |
|---|
| 2671 | | - } |
|---|
| 2672 | | - |
|---|
| 2673 | | - /* set offloads */ |
|---|
| 2674 | | - priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
|---|
| 2675 | | - NETIF_F_RXCSUM | |
|---|
| 2676 | | - NETIF_F_TSO | NETIF_F_TSO6 | |
|---|
| 2677 | | - NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 2678 | | - NETIF_F_GSO_UDP_TUNNEL_CSUM | |
|---|
| 2679 | | - NETIF_F_GSO_PARTIAL; |
|---|
| 2658 | + return mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port, |
|---|
| 2659 | + VXLAN_STEER_BY_OUTER_MAC, |
|---|
| 2660 | + !!priv->vxlan_port); |
|---|
| 2680 | 2661 | } |
|---|
| 2681 | 2662 | |
|---|
| 2682 | | -static void mlx4_en_del_vxlan_offloads(struct work_struct *work) |
|---|
| 2683 | | -{ |
|---|
| 2684 | | - int ret; |
|---|
| 2685 | | - struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, |
|---|
| 2686 | | - vxlan_del_task); |
|---|
| 2687 | | - /* unset offloads */ |
|---|
| 2688 | | - priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
|---|
| 2689 | | - NETIF_F_RXCSUM | |
|---|
| 2690 | | - NETIF_F_TSO | NETIF_F_TSO6 | |
|---|
| 2691 | | - NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 2692 | | - NETIF_F_GSO_UDP_TUNNEL_CSUM | |
|---|
| 2693 | | - NETIF_F_GSO_PARTIAL); |
|---|
| 2694 | | - |
|---|
| 2695 | | - ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port, |
|---|
| 2696 | | - VXLAN_STEER_BY_OUTER_MAC, 0); |
|---|
| 2697 | | - if (ret) |
|---|
| 2698 | | - en_err(priv, "failed setting L2 tunnel configuration ret %d\n", ret); |
|---|
| 2699 | | - |
|---|
| 2700 | | - priv->vxlan_port = 0; |
|---|
| 2701 | | -} |
|---|
| 2702 | | - |
|---|
| 2703 | | -static void mlx4_en_add_vxlan_port(struct net_device *dev, |
|---|
| 2704 | | - struct udp_tunnel_info *ti) |
|---|
| 2705 | | -{ |
|---|
| 2706 | | - struct mlx4_en_priv *priv = netdev_priv(dev); |
|---|
| 2707 | | - __be16 port = ti->port; |
|---|
| 2708 | | - __be16 current_port; |
|---|
| 2709 | | - |
|---|
| 2710 | | - if (ti->type != UDP_TUNNEL_TYPE_VXLAN) |
|---|
| 2711 | | - return; |
|---|
| 2712 | | - |
|---|
| 2713 | | - if (ti->sa_family != AF_INET) |
|---|
| 2714 | | - return; |
|---|
| 2715 | | - |
|---|
| 2716 | | - if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) |
|---|
| 2717 | | - return; |
|---|
| 2718 | | - |
|---|
| 2719 | | - current_port = priv->vxlan_port; |
|---|
| 2720 | | - if (current_port && current_port != port) { |
|---|
| 2721 | | - en_warn(priv, "vxlan port %d configured, can't add port %d\n", |
|---|
| 2722 | | - ntohs(current_port), ntohs(port)); |
|---|
| 2723 | | - return; |
|---|
| 2724 | | - } |
|---|
| 2725 | | - |
|---|
| 2726 | | - priv->vxlan_port = port; |
|---|
| 2727 | | - queue_work(priv->mdev->workqueue, &priv->vxlan_add_task); |
|---|
| 2728 | | -} |
|---|
| 2729 | | - |
|---|
| 2730 | | -static void mlx4_en_del_vxlan_port(struct net_device *dev, |
|---|
| 2731 | | - struct udp_tunnel_info *ti) |
|---|
| 2732 | | -{ |
|---|
| 2733 | | - struct mlx4_en_priv *priv = netdev_priv(dev); |
|---|
| 2734 | | - __be16 port = ti->port; |
|---|
| 2735 | | - __be16 current_port; |
|---|
| 2736 | | - |
|---|
| 2737 | | - if (ti->type != UDP_TUNNEL_TYPE_VXLAN) |
|---|
| 2738 | | - return; |
|---|
| 2739 | | - |
|---|
| 2740 | | - if (ti->sa_family != AF_INET) |
|---|
| 2741 | | - return; |
|---|
| 2742 | | - |
|---|
| 2743 | | - if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) |
|---|
| 2744 | | - return; |
|---|
| 2745 | | - |
|---|
| 2746 | | - current_port = priv->vxlan_port; |
|---|
| 2747 | | - if (current_port != port) { |
|---|
| 2748 | | - en_dbg(DRV, priv, "vxlan port %d isn't configured, ignoring\n", ntohs(port)); |
|---|
| 2749 | | - return; |
|---|
| 2750 | | - } |
|---|
| 2751 | | - |
|---|
| 2752 | | - queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); |
|---|
| 2753 | | -} |
|---|
| 2663 | +static const struct udp_tunnel_nic_info mlx4_udp_tunnels = { |
|---|
| 2664 | + .sync_table = mlx4_udp_tunnel_sync, |
|---|
| 2665 | + .flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP | |
|---|
| 2666 | + UDP_TUNNEL_NIC_INFO_IPV4_ONLY, |
|---|
| 2667 | + .tables = { |
|---|
| 2668 | + { .n_entries = 1, .tunnel_types = UDP_TUNNEL_TYPE_VXLAN, }, |
|---|
| 2669 | + }, |
|---|
| 2670 | +}; |
|---|
| 2754 | 2671 | |
|---|
| 2755 | 2672 | static netdev_features_t mlx4_en_features_check(struct sk_buff *skb, |
|---|
| 2756 | 2673 | struct net_device *dev, |
|---|
| .. | .. |
|---|
| 2822 | 2739 | * program for a new one. |
|---|
| 2823 | 2740 | */ |
|---|
| 2824 | 2741 | if (priv->tx_ring_num[TX_XDP] == xdp_ring_num) { |
|---|
| 2825 | | - if (prog) { |
|---|
| 2826 | | - prog = bpf_prog_add(prog, priv->rx_ring_num - 1); |
|---|
| 2827 | | - if (IS_ERR(prog)) |
|---|
| 2828 | | - return PTR_ERR(prog); |
|---|
| 2829 | | - } |
|---|
| 2742 | + if (prog) |
|---|
| 2743 | + bpf_prog_add(prog, priv->rx_ring_num - 1); |
|---|
| 2744 | + |
|---|
| 2830 | 2745 | mutex_lock(&mdev->state_lock); |
|---|
| 2831 | 2746 | for (i = 0; i < priv->rx_ring_num; i++) { |
|---|
| 2832 | 2747 | old_prog = rcu_dereference_protected( |
|---|
| .. | .. |
|---|
| 2847 | 2762 | if (!tmp) |
|---|
| 2848 | 2763 | return -ENOMEM; |
|---|
| 2849 | 2764 | |
|---|
| 2850 | | - if (prog) { |
|---|
| 2851 | | - prog = bpf_prog_add(prog, priv->rx_ring_num - 1); |
|---|
| 2852 | | - if (IS_ERR(prog)) { |
|---|
| 2853 | | - err = PTR_ERR(prog); |
|---|
| 2854 | | - goto out; |
|---|
| 2855 | | - } |
|---|
| 2856 | | - } |
|---|
| 2765 | + if (prog) |
|---|
| 2766 | + bpf_prog_add(prog, priv->rx_ring_num - 1); |
|---|
| 2857 | 2767 | |
|---|
| 2858 | 2768 | mutex_lock(&mdev->state_lock); |
|---|
| 2859 | 2769 | memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile)); |
|---|
| .. | .. |
|---|
| 2903 | 2813 | |
|---|
| 2904 | 2814 | unlock_out: |
|---|
| 2905 | 2815 | mutex_unlock(&mdev->state_lock); |
|---|
| 2906 | | -out: |
|---|
| 2907 | 2816 | kfree(tmp); |
|---|
| 2908 | 2817 | return err; |
|---|
| 2909 | | -} |
|---|
| 2910 | | - |
|---|
| 2911 | | -static u32 mlx4_xdp_query(struct net_device *dev) |
|---|
| 2912 | | -{ |
|---|
| 2913 | | - struct mlx4_en_priv *priv = netdev_priv(dev); |
|---|
| 2914 | | - struct mlx4_en_dev *mdev = priv->mdev; |
|---|
| 2915 | | - const struct bpf_prog *xdp_prog; |
|---|
| 2916 | | - u32 prog_id = 0; |
|---|
| 2917 | | - |
|---|
| 2918 | | - if (!priv->tx_ring_num[TX_XDP]) |
|---|
| 2919 | | - return prog_id; |
|---|
| 2920 | | - |
|---|
| 2921 | | - mutex_lock(&mdev->state_lock); |
|---|
| 2922 | | - xdp_prog = rcu_dereference_protected( |
|---|
| 2923 | | - priv->rx_ring[0]->xdp_prog, |
|---|
| 2924 | | - lockdep_is_held(&mdev->state_lock)); |
|---|
| 2925 | | - if (xdp_prog) |
|---|
| 2926 | | - prog_id = xdp_prog->aux->id; |
|---|
| 2927 | | - mutex_unlock(&mdev->state_lock); |
|---|
| 2928 | | - |
|---|
| 2929 | | - return prog_id; |
|---|
| 2930 | 2818 | } |
|---|
| 2931 | 2819 | |
|---|
| 2932 | 2820 | static int mlx4_xdp(struct net_device *dev, struct netdev_bpf *xdp) |
|---|
| .. | .. |
|---|
| 2934 | 2822 | switch (xdp->command) { |
|---|
| 2935 | 2823 | case XDP_SETUP_PROG: |
|---|
| 2936 | 2824 | return mlx4_xdp_set(dev, xdp->prog); |
|---|
| 2937 | | - case XDP_QUERY_PROG: |
|---|
| 2938 | | - xdp->prog_id = mlx4_xdp_query(dev); |
|---|
| 2939 | | - return 0; |
|---|
| 2940 | 2825 | default: |
|---|
| 2941 | 2826 | return -EINVAL; |
|---|
| 2942 | 2827 | } |
|---|
| .. | .. |
|---|
| 2963 | 2848 | .ndo_rx_flow_steer = mlx4_en_filter_rfs, |
|---|
| 2964 | 2849 | #endif |
|---|
| 2965 | 2850 | .ndo_get_phys_port_id = mlx4_en_get_phys_port_id, |
|---|
| 2966 | | - .ndo_udp_tunnel_add = mlx4_en_add_vxlan_port, |
|---|
| 2967 | | - .ndo_udp_tunnel_del = mlx4_en_del_vxlan_port, |
|---|
| 2851 | + .ndo_udp_tunnel_add = udp_tunnel_nic_add_port, |
|---|
| 2852 | + .ndo_udp_tunnel_del = udp_tunnel_nic_del_port, |
|---|
| 2968 | 2853 | .ndo_features_check = mlx4_en_features_check, |
|---|
| 2969 | 2854 | .ndo_set_tx_maxrate = mlx4_en_set_tx_maxrate, |
|---|
| 2970 | 2855 | .ndo_bpf = mlx4_xdp, |
|---|
| .. | .. |
|---|
| 2997 | 2882 | .ndo_rx_flow_steer = mlx4_en_filter_rfs, |
|---|
| 2998 | 2883 | #endif |
|---|
| 2999 | 2884 | .ndo_get_phys_port_id = mlx4_en_get_phys_port_id, |
|---|
| 3000 | | - .ndo_udp_tunnel_add = mlx4_en_add_vxlan_port, |
|---|
| 3001 | | - .ndo_udp_tunnel_del = mlx4_en_del_vxlan_port, |
|---|
| 2885 | + .ndo_udp_tunnel_add = udp_tunnel_nic_add_port, |
|---|
| 2886 | + .ndo_udp_tunnel_del = udp_tunnel_nic_del_port, |
|---|
| 3002 | 2887 | .ndo_features_check = mlx4_en_features_check, |
|---|
| 3003 | 2888 | .ndo_set_tx_maxrate = mlx4_en_set_tx_maxrate, |
|---|
| 3004 | 2889 | .ndo_bpf = mlx4_xdp, |
|---|
| .. | .. |
|---|
| 3299 | 3184 | INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); |
|---|
| 3300 | 3185 | INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); |
|---|
| 3301 | 3186 | INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); |
|---|
| 3302 | | - INIT_WORK(&priv->vxlan_add_task, mlx4_en_add_vxlan_offloads); |
|---|
| 3303 | | - INIT_WORK(&priv->vxlan_del_task, mlx4_en_del_vxlan_offloads); |
|---|
| 3304 | 3187 | #ifdef CONFIG_RFS_ACCEL |
|---|
| 3305 | 3188 | INIT_LIST_HEAD(&priv->filters); |
|---|
| 3306 | 3189 | spin_lock_init(&priv->filters_lock); |
|---|
| .. | .. |
|---|
| 3385 | 3268 | dev->addr_len = ETH_ALEN; |
|---|
| 3386 | 3269 | mlx4_en_u64_to_mac(dev->dev_addr, mdev->dev->caps.def_mac[priv->port]); |
|---|
| 3387 | 3270 | if (!is_valid_ether_addr(dev->dev_addr)) { |
|---|
| 3388 | | - en_err(priv, "Port: %d, invalid mac burned: %pM, quiting\n", |
|---|
| 3271 | + en_err(priv, "Port: %d, invalid mac burned: %pM, quitting\n", |
|---|
| 3389 | 3272 | priv->port, dev->dev_addr); |
|---|
| 3390 | 3273 | err = -EINVAL; |
|---|
| 3391 | 3274 | goto out; |
|---|
| .. | .. |
|---|
| 3439 | 3322 | dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
|---|
| 3440 | 3323 | if (mdev->LSO_support) |
|---|
| 3441 | 3324 | dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6; |
|---|
| 3325 | + |
|---|
| 3326 | + if (mdev->dev->caps.tunnel_offload_mode == |
|---|
| 3327 | + MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) { |
|---|
| 3328 | + dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 3329 | + NETIF_F_GSO_UDP_TUNNEL_CSUM | |
|---|
| 3330 | + NETIF_F_GSO_PARTIAL; |
|---|
| 3331 | + dev->features |= NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 3332 | + NETIF_F_GSO_UDP_TUNNEL_CSUM | |
|---|
| 3333 | + NETIF_F_GSO_PARTIAL; |
|---|
| 3334 | + dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM; |
|---|
| 3335 | + dev->hw_enc_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
|---|
| 3336 | + NETIF_F_RXCSUM | |
|---|
| 3337 | + NETIF_F_TSO | NETIF_F_TSO6 | |
|---|
| 3338 | + NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 3339 | + NETIF_F_GSO_UDP_TUNNEL_CSUM | |
|---|
| 3340 | + NETIF_F_GSO_PARTIAL; |
|---|
| 3341 | + |
|---|
| 3342 | + dev->udp_tunnel_nic_info = &mlx4_udp_tunnels; |
|---|
| 3343 | + } |
|---|
| 3442 | 3344 | |
|---|
| 3443 | 3345 | dev->vlan_features = dev->hw_features; |
|---|
| 3444 | 3346 | |
|---|
| .. | .. |
|---|
| 3506 | 3408 | en_warn(priv, |
|---|
| 3507 | 3409 | "No RSS hash capabilities exposed, using Toeplitz\n"); |
|---|
| 3508 | 3410 | priv->rss_hash_fn = ETH_RSS_HASH_TOP; |
|---|
| 3509 | | - } |
|---|
| 3510 | | - |
|---|
| 3511 | | - if (mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) { |
|---|
| 3512 | | - dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 3513 | | - NETIF_F_GSO_UDP_TUNNEL_CSUM | |
|---|
| 3514 | | - NETIF_F_GSO_PARTIAL; |
|---|
| 3515 | | - dev->features |= NETIF_F_GSO_UDP_TUNNEL | |
|---|
| 3516 | | - NETIF_F_GSO_UDP_TUNNEL_CSUM | |
|---|
| 3517 | | - NETIF_F_GSO_PARTIAL; |
|---|
| 3518 | | - dev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM; |
|---|
| 3519 | 3411 | } |
|---|
| 3520 | 3412 | |
|---|
| 3521 | 3413 | /* MTU range: 68 - hw-specific max */ |
|---|