fm10k: add support for Rx offloads on one Geneve tunnel
authorJacob Keller <jacob.e.keller@intel.com>
Thu, 23 Jun 2016 20:54:03 +0000 (13:54 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 29 Aug 2016 08:31:03 +0000 (01:31 -0700)
Similar to how we handle VXLAN offload, enable support for a single
Geneve tunnel.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <Krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/fm10k/fm10k.h
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c
drivers/net/ethernet/intel/fm10k/fm10k_type.h

index 209268a1471208ff5c0f081d259f15d2cf04c935..67ff01aeb11a6b29f17c38a80448bbd261daf46d 100644 (file)
@@ -335,6 +335,7 @@ struct fm10k_intfc {
 
        /* UDP encapsulation port tracking information */
        struct list_head vxlan_port;
+       struct list_head geneve_port;
 
 #ifdef CONFIG_DEBUG_FS
        struct dentry *dbg_intfc;
index 07c5a685f0e94689fb81202cc8b2ef699d18eaa8..05629381be6be5de004680f6f27fd5b577851e63 100644 (file)
@@ -387,7 +387,7 @@ static void fm10k_request_glort_range(struct fm10k_intfc *interface)
  * fm10k_free_udp_port_info
  * @interface: board private structure
  *
- * This function frees the entire vxlan_port list
+ * This function frees both geneve_port and vxlan_port structures
  **/
 static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
 {
@@ -403,6 +403,17 @@ static void fm10k_free_udp_port_info(struct fm10k_intfc *interface)
                                                struct fm10k_udp_port,
                                                list);
        }
+
+       /* flush all entries from geneve list */
+       port = list_first_entry_or_null(&interface->geneve_port,
+                                       struct fm10k_udp_port, list);
+       while (port) {
+               list_del(&port->list);
+               kfree(port);
+               port = list_first_entry_or_null(&interface->vxlan_port,
+                                               struct fm10k_udp_port,
+                                               list);
+       }
 }
 
 /**
@@ -427,6 +438,13 @@ static void fm10k_restore_udp_port_info(struct fm10k_intfc *interface)
        fm10k_write_reg(hw, FM10K_TUNNEL_CFG,
                        (port ? ntohs(port->port) : 0) |
                        (ETH_P_TEB << FM10K_TUNNEL_CFG_NVGRE_SHIFT));
+
+       port = list_first_entry_or_null(&interface->geneve_port,
+                                       struct fm10k_udp_port, list);
+
+       /* restore Geneve tunnel configuration register */
+       fm10k_write_reg(hw, FM10K_TUNNEL_CFG_GENEVE,
+                       (port ? ntohs(port->port) : 0));
 }
 
 static struct fm10k_udp_port *
@@ -472,8 +490,8 @@ static void fm10k_insert_tunnel_port(struct list_head *ports,
  * @ti: Tunnel endpoint information
  *
  * This function is called when a new UDP tunnel port has been added.
- * Currently we only support VXLAN and only one port will actually be
- * offloaded due to hardware restrictions.
+ * Due to hardware restrictions, only one port per type can be offloaded at
+ * once.
  **/
 static void fm10k_udp_tunnel_add(struct net_device *dev,
                                 struct udp_tunnel_info *ti)
@@ -488,6 +506,9 @@ static void fm10k_udp_tunnel_add(struct net_device *dev,
        case UDP_TUNNEL_TYPE_VXLAN:
                fm10k_insert_tunnel_port(&interface->vxlan_port, ti);
                break;
+       case UDP_TUNNEL_TYPE_GENEVE:
+               fm10k_insert_tunnel_port(&interface->geneve_port, ti);
+               break;
        default:
                return;
        }
@@ -517,6 +538,9 @@ static void fm10k_udp_tunnel_del(struct net_device *dev,
        case UDP_TUNNEL_TYPE_VXLAN:
                port = fm10k_remove_tunnel_port(&interface->vxlan_port, ti);
                break;
+       case UDP_TUNNEL_TYPE_GENEVE:
+               port = fm10k_remove_tunnel_port(&interface->geneve_port, ti);
+               break;
        default:
                return;
        }
index 860fe04f4c72b490e28a680e6f41da499f7b9a9a..0a20ca16853543e24d99758fb5bab9cc72aa93bd 100644 (file)
@@ -1835,8 +1835,9 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
        interface->tx_itr = FM10K_TX_ITR_DEFAULT;
        interface->rx_itr = FM10K_ITR_ADAPTIVE | FM10K_RX_ITR_DEFAULT;
 
-       /* initialize vxlan_port list */
+       /* initialize udp port lists */
        INIT_LIST_HEAD(&interface->vxlan_port);
+       INIT_LIST_HEAD(&interface->geneve_port);
 
        netdev_rss_key_fill(rss_key, sizeof(rss_key));
        memcpy(interface->rssrk, rss_key, sizeof(rss_key));
index f4e75c498287ccfcbade6c24361fabac14811b3d..6bb16c13d9d6c957fd3eec3fc4431381966a4dfe 100644 (file)
@@ -154,6 +154,7 @@ struct fm10k_hw;
 #define FM10K_DGLORTDEC_INNERRSS_ENABLE                0x08000000
 #define FM10K_TUNNEL_CFG       0x0040
 #define FM10K_TUNNEL_CFG_NVGRE_SHIFT           16
+#define FM10K_TUNNEL_CFG_GENEVE        0x0041
 #define FM10K_SWPRI_MAP(_n)    ((_n) + 0x0050)
 #define FM10K_SWPRI_MAX                16
 #define FM10K_RSSRK(_n, _m)    (((_n) * 0x10) + (_m) + 0x0800)