aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
authorSriharsha Basavapatna <sriharsha.basavapatna@emulex.com>2014-12-11 03:24:47 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-11 14:37:24 -0500
commit630f4b70567fa0e2dc9283829f7cee04a5de3be2 (patch)
tree577b5d263b8d50ebdf8a3cf4d2dfd5c147070236 /drivers/net/ethernet/emulex
parent0a4b5a2488347a53ad695cf6a87e4b8fbede9eaa (diff)
be2net: Export tunnel offloads only when a VxLAN tunnel is created
The encapsulated offload flags shouldn't be unconditionally exported to the stack. The stack expects offloading to work across all tunnel types when those flags are set. This would break other tunnels (like GRE) since be2net currently supports tunnel offload for VxLAN only. Also, with VxLANs Skyhawk-R can offload only 1 UDP dport. If more than 1 UDP port is added, we should disable offloads in that case too. Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@emulex.com> Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c42
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
3125static void be_disable_vxlan_offloads(struct be_adapter *adapter) 3125static 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 */
4374static void be_add_vxlan_port(struct net_device *netdev, sa_family_t sa_family, 4392static 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));
4456done:
4457 adapter->vxlan_port_count--;
4430} 4458}
4431 4459
4432static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) 4460static 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;