diff options
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 42 |
2 files changed, 33 insertions, 10 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 9a2d75235e89..712e7f8e1df7 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
| @@ -522,6 +522,7 @@ struct be_adapter { | |||
| 522 | u8 hba_port_num; | 522 | u8 hba_port_num; |
| 523 | u16 pvid; | 523 | u16 pvid; |
| 524 | __be16 vxlan_port; | 524 | __be16 vxlan_port; |
| 525 | int vxlan_port_count; | ||
| 525 | struct phy_info phy; | 526 | struct phy_info phy; |
| 526 | u8 wol_cap; | 527 | u8 wol_cap; |
| 527 | bool wol_en; | 528 | bool wol_en; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 9461ad8d837b..2aacd4731051 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
| @@ -3124,6 +3124,8 @@ static void be_mac_clear(struct be_adapter *adapter) | |||
| 3124 | #ifdef CONFIG_BE2NET_VXLAN | 3124 | #ifdef CONFIG_BE2NET_VXLAN |
| 3125 | static void be_disable_vxlan_offloads(struct be_adapter *adapter) | 3125 | static void be_disable_vxlan_offloads(struct be_adapter *adapter) |
| 3126 | { | 3126 | { |
| 3127 | struct net_device *netdev = adapter->netdev; | ||
| 3128 | |||
| 3127 | if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) | 3129 | if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) |
| 3128 | be_cmd_manage_iface(adapter, adapter->if_handle, | 3130 | be_cmd_manage_iface(adapter, adapter->if_handle, |
| 3129 | OP_CONVERT_TUNNEL_TO_NORMAL); | 3131 | OP_CONVERT_TUNNEL_TO_NORMAL); |
| @@ -3133,6 +3135,9 @@ static void be_disable_vxlan_offloads(struct be_adapter *adapter) | |||
| 3133 | 3135 | ||
| 3134 | adapter->flags &= ~BE_FLAGS_VXLAN_OFFLOADS; | 3136 | adapter->flags &= ~BE_FLAGS_VXLAN_OFFLOADS; |
| 3135 | adapter->vxlan_port = 0; | 3137 | adapter->vxlan_port = 0; |
| 3138 | |||
| 3139 | netdev->hw_enc_features = 0; | ||
| 3140 | netdev->hw_features &= ~(NETIF_F_GSO_UDP_TUNNEL); | ||
| 3136 | } | 3141 | } |
| 3137 | #endif | 3142 | #endif |
| 3138 | 3143 | ||
| @@ -4371,6 +4376,19 @@ static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | |||
| 4371 | } | 4376 | } |
| 4372 | 4377 | ||
| 4373 | #ifdef CONFIG_BE2NET_VXLAN | 4378 | #ifdef CONFIG_BE2NET_VXLAN |
| 4379 | /* VxLAN offload Notes: | ||
| 4380 | * | ||
| 4381 | * The stack defines tunnel offload flags (hw_enc_features) for IP and doesn't | ||
| 4382 | * distinguish various types of transports (VxLAN, GRE, NVGRE ..). So, offload | ||
| 4383 | * is expected to work across all types of IP tunnels once exported. Skyhawk | ||
| 4384 | * supports offloads for either VxLAN or NVGRE, exclusively. So we export VxLAN | ||
| 4385 | * offloads in hw_enc_features only when a VxLAN port is added. Note this only | ||
| 4386 | * ensures that other tunnels work fine while VxLAN offloads are not enabled. | ||
| 4387 | * | ||
| 4388 | * Skyhawk supports VxLAN offloads only for one UDP dport. So, if the stack | ||
| 4389 | * adds more than one port, disable offloads and don't re-enable them again | ||
| 4390 | * until after all the tunnels are removed. | ||
| 4391 | */ | ||
| 4374 | static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, | 4392 | static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, |
| 4375 | __be16 port) | 4393 | __be16 port) |
| 4376 | { | 4394 | { |
| @@ -4382,13 +4400,16 @@ static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, | |||
| 4382 | return; | 4400 | return; |
| 4383 | 4401 | ||
| 4384 | if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) { | 4402 | if (adapter->flags & BE_FLAGS_VXLAN_OFFLOADS) { |
| 4385 | dev_warn(dev, "Cannot add UDP port %d for VxLAN offloads\n", | ||
| 4386 | be16_to_cpu(port)); | ||
| 4387 | dev_info(dev, | 4403 | dev_info(dev, |
| 4388 | "Only one UDP port supported for VxLAN offloads\n"); | 4404 | "Only one UDP port supported for VxLAN offloads\n"); |
| 4389 | return; | 4405 | dev_info(dev, "Disabling VxLAN offloads\n"); |
| 4406 | adapter->vxlan_port_count++; | ||
| 4407 | goto err; | ||
| 4390 | } | 4408 | } |
| 4391 | 4409 | ||
| 4410 | if (adapter->vxlan_port_count++ >= 1) | ||
| 4411 | return; | ||
| 4412 | |||
| 4392 | status = be_cmd_manage_iface(adapter, adapter->if_handle, | 4413 | status = be_cmd_manage_iface(adapter, adapter->if_handle, |
| 4393 | OP_CONVERT_NORMAL_TO_TUNNEL); | 4414 | OP_CONVERT_NORMAL_TO_TUNNEL); |
| 4394 | if (status) { | 4415 | if (status) { |
| @@ -4404,6 +4425,11 @@ static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, | |||
| 4404 | adapter->flags |= BE_FLAGS_VXLAN_OFFLOADS; | 4425 | adapter->flags |= BE_FLAGS_VXLAN_OFFLOADS; |
| 4405 | adapter->vxlan_port = port; | 4426 | adapter->vxlan_port = port; |
| 4406 | 4427 | ||
| 4428 | netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | ||
| 4429 | NETIF_F_TSO | NETIF_F_TSO6 | | ||
| 4430 | NETIF_F_GSO_UDP_TUNNEL; | ||
| 4431 | netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL; | ||
| 4432 | |||
| 4407 | dev_info(dev, "Enabled VxLAN offloads for UDP port %d\n", | 4433 | dev_info(dev, "Enabled VxLAN offloads for UDP port %d\n", |
| 4408 | be16_to_cpu(port)); | 4434 | be16_to_cpu(port)); |
| 4409 | return; | 4435 | return; |
| @@ -4420,13 +4446,15 @@ static void be_del_vxlan_port(struct net_device *netdev, sa_family_t sa_family, | |||
| 4420 | return; | 4446 | return; |
| 4421 | 4447 | ||
| 4422 | if (adapter->vxlan_port != port) | 4448 | if (adapter->vxlan_port != port) |
| 4423 | return; | 4449 | goto done; |
| 4424 | 4450 | ||
| 4425 | be_disable_vxlan_offloads(adapter); | 4451 | be_disable_vxlan_offloads(adapter); |
| 4426 | 4452 | ||
| 4427 | dev_info(&adapter->pdev->dev, | 4453 | dev_info(&adapter->pdev->dev, |
| 4428 | "Disabled VxLAN offloads for UDP port %d\n", | 4454 | "Disabled VxLAN offloads for UDP port %d\n", |
| 4429 | be16_to_cpu(port)); | 4455 | be16_to_cpu(port)); |
| 4456 | done: | ||
| 4457 | adapter->vxlan_port_count--; | ||
| 4430 | } | 4458 | } |
| 4431 | 4459 | ||
| 4432 | static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) | 4460 | static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) |
| @@ -4470,12 +4498,6 @@ static void be_netdev_init(struct net_device *netdev) | |||
| 4470 | { | 4498 | { |
| 4471 | struct be_adapter *adapter = netdev_priv(netdev); | 4499 | struct be_adapter *adapter = netdev_priv(netdev); |
| 4472 | 4500 | ||
| 4473 | if (skyhawk_chip(adapter)) { | ||
| 4474 | netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | ||
| 4475 | NETIF_F_TSO | NETIF_F_TSO6 | | ||
| 4476 | NETIF_F_GSO_UDP_TUNNEL; | ||
| 4477 | netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL; | ||
| 4478 | } | ||
| 4479 | netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | | 4501 | netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | |
| 4480 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | | 4502 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | |
| 4481 | NETIF_F_HW_VLAN_CTAG_TX; | 4503 | NETIF_F_HW_VLAN_CTAG_TX; |
