struct sk_buff *skb)
 {
        __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
-       __le16 hdr_info = rx_desc->wb.lower.lo_dword.hs_rss.hdr_info;
        bool encap_pkt = false;
 
        skb_checksum_none_assert(skb);
        if (!(ring->netdev->features & NETIF_F_RXCSUM))
                return;
 
-       if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) &&
-           (hdr_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_TUNNEL >> 16))) {
+       /* check for VXLAN and Geneve packets */
+       if (pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) {
                encap_pkt = true;
                skb->encapsulation = 1;
        }
        rfctl &= ~IXGBE_RFCTL_RSC_DIS;
        if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))
                rfctl |= IXGBE_RFCTL_RSC_DIS;
+
+       /* disable NFS filtering */
+       rfctl |= (IXGBE_RFCTL_NFSW_DIS | IXGBE_RFCTL_NFSR_DIS);
        IXGBE_WRITE_REG(hw, IXGBE_RFCTL, rfctl);
 
        /* Program registers for the distribution of queues */
        }
 }
 
-static void ixgbe_clear_vxlan_port(struct ixgbe_adapter *adapter)
+static void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *adapter, u32 mask)
 {
-       switch (adapter->hw.mac.type) {
-       case ixgbe_mac_X550:
-       case ixgbe_mac_X550EM_x:
-       case ixgbe_mac_x550em_a:
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_VXLANCTRL, 0);
+       struct ixgbe_hw *hw = &adapter->hw;
+       u32 vxlanctrl;
+
+       if (!(adapter->flags & (IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE |
+                               IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)))
+               return;
+
+       vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) && ~mask;
+       IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl);
+
+       if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK)
                adapter->vxlan_port = 0;
-               break;
-       default:
-               break;
-       }
+
+       if (mask & IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK)
+               adapter->geneve_port = 0;
 }
 
 #ifdef CONFIG_IXGBE_DCB
                if (fwsm & IXGBE_FWSM_TS_ENABLED)
                        adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
                break;
-       case ixgbe_mac_X550EM_x:
        case ixgbe_mac_x550em_a:
+               adapter->flags |= IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE;
+       /* fall through */
+       case ixgbe_mac_X550EM_x:
 #ifdef CONFIG_IXGBE_DCB
                adapter->flags &= ~IXGBE_FLAG_DCB_CAPABLE;
 #endif
 
        ixgbe_up_complete(adapter);
 
-       ixgbe_clear_vxlan_port(adapter);
+       ixgbe_clear_udp_tunnel_port(adapter, IXGBE_VXLANCTRL_ALL_UDPPORT_MASK);
        udp_tunnel_get_rx_info(netdev);
 
        return 0;
                ixgbe_service_event_complete(adapter);
                return;
        }
-       if (adapter->flags2 & IXGBE_FLAG2_VXLAN_REREG_NEEDED) {
+       if (adapter->flags2 & IXGBE_FLAG2_UDP_TUN_REREG_NEEDED) {
                rtnl_lock();
-               adapter->flags2 &= ~IXGBE_FLAG2_VXLAN_REREG_NEEDED;
+               adapter->flags2 &= ~IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
                udp_tunnel_get_rx_info(adapter->netdev);
                rtnl_unlock();
        }
                if (adapter->vxlan_port &&
                    udp_hdr(skb)->dest == adapter->vxlan_port)
                        hdr.network = skb_inner_network_header(skb);
+
+               if (adapter->geneve_port &&
+                   udp_hdr(skb)->dest == adapter->geneve_port)
+                       hdr.network = skb_inner_network_header(skb);
        }
 
        /* Currently only IPv4/IPv6 with TCP is supported */
        netdev->features = features;
 
        if ((adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE)) {
-               if (features & NETIF_F_RXCSUM)
-                       adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
-               else
-                       ixgbe_clear_vxlan_port(adapter);
+               if (features & NETIF_F_RXCSUM) {
+                       adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
+               } else {
+                       u32 port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
+
+                       ixgbe_clear_udp_tunnel_port(adapter, port_mask);
+               }
+       }
+
+       if ((adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE)) {
+               if (features & NETIF_F_RXCSUM) {
+                       adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
+               } else {
+                       u32 port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
+
+                       ixgbe_clear_udp_tunnel_port(adapter, port_mask);
+               }
        }
 
        if (need_reset)
 }
 
 /**
- * ixgbe_add_vxlan_port - Get notifications about VXLAN ports that come up
+ * ixgbe_add_udp_tunnel_port - Get notifications about adding UDP tunnel ports
  * @dev: The port's netdev
  * @ti: Tunnel endpoint information
  **/
-static void ixgbe_add_vxlan_port(struct net_device *dev,
-                                struct udp_tunnel_info *ti)
+static void ixgbe_add_udp_tunnel_port(struct net_device *dev,
+                                     struct udp_tunnel_info *ti)
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
        struct ixgbe_hw *hw = &adapter->hw;
        __be16 port = ti->port;
-
-       if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
-               return;
+       u32 port_shift = 0;
+       u32 reg;
 
        if (ti->sa_family != AF_INET)
                return;
 
-       if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
-               return;
+       switch (ti->type) {
+       case UDP_TUNNEL_TYPE_VXLAN:
+               if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
+                       return;
 
-       if (adapter->vxlan_port == port)
-               return;
+               if (adapter->vxlan_port == port)
+                       return;
+
+               if (adapter->vxlan_port) {
+                       netdev_info(dev,
+                                   "VXLAN port %d set, not adding port %d\n",
+                                   ntohs(adapter->vxlan_port),
+                                   ntohs(port));
+                       return;
+               }
+
+               adapter->vxlan_port = port;
+               break;
+       case UDP_TUNNEL_TYPE_GENEVE:
+               if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
+                       return;
+
+               if (adapter->geneve_port == port)
+                       return;
+
+               if (adapter->geneve_port) {
+                       netdev_info(dev,
+                                   "GENEVE port %d set, not adding port %d\n",
+                                   ntohs(adapter->geneve_port),
+                                   ntohs(port));
+                       return;
+               }
 
-       if (adapter->vxlan_port) {
-               netdev_info(dev,
-                           "Hit Max num of VXLAN ports, not adding port %d\n",
-                           ntohs(port));
+               port_shift = IXGBE_VXLANCTRL_GENEVE_UDPPORT_SHIFT;
+               adapter->geneve_port = port;
+               break;
+       default:
                return;
        }
 
-       adapter->vxlan_port = port;
-       IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, ntohs(port));
+       reg = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) | ntohs(port) << port_shift;
+       IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, reg);
 }
 
 /**
- * ixgbe_del_vxlan_port - Get notifications about VXLAN ports that go away
+ * ixgbe_del_udp_tunnel_port - Get notifications about removing UDP tunnel ports
  * @dev: The port's netdev
  * @ti: Tunnel endpoint information
  **/
-static void ixgbe_del_vxlan_port(struct net_device *dev,
-                                struct udp_tunnel_info *ti)
+static void ixgbe_del_udp_tunnel_port(struct net_device *dev,
+                                     struct udp_tunnel_info *ti)
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
+       u32 port_mask;
 
-       if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
+       if (ti->type != UDP_TUNNEL_TYPE_VXLAN &&
+           ti->type != UDP_TUNNEL_TYPE_GENEVE)
                return;
 
        if (ti->sa_family != AF_INET)
                return;
 
-       if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
-               return;
+       switch (ti->type) {
+       case UDP_TUNNEL_TYPE_VXLAN:
+               if (!(adapter->flags & IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE))
+                       return;
 
-       if (adapter->vxlan_port != ti->port) {
-               netdev_info(dev, "Port %d was not found, not deleting\n",
-                           ntohs(ti->port));
+               if (adapter->vxlan_port != ti->port) {
+                       netdev_info(dev, "VXLAN port %d not found\n",
+                                   ntohs(ti->port));
+                       return;
+               }
+
+               port_mask = IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK;
+               break;
+       case UDP_TUNNEL_TYPE_GENEVE:
+               if (!(adapter->flags & IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))
+                       return;
+
+               if (adapter->geneve_port != ti->port) {
+                       netdev_info(dev, "GENEVE port %d not found\n",
+                                   ntohs(ti->port));
+                       return;
+               }
+
+               port_mask = IXGBE_VXLANCTRL_GENEVE_UDPPORT_MASK;
+               break;
+       default:
                return;
        }
 
-       ixgbe_clear_vxlan_port(adapter);
-       adapter->flags2 |= IXGBE_FLAG2_VXLAN_REREG_NEEDED;
+       ixgbe_clear_udp_tunnel_port(adapter, port_mask);
+       adapter->flags2 |= IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
 }
 
 static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
        .ndo_bridge_getlink     = ixgbe_ndo_bridge_getlink,
        .ndo_dfwd_add_station   = ixgbe_fwd_add,
        .ndo_dfwd_del_station   = ixgbe_fwd_del,
-       .ndo_udp_tunnel_add     = ixgbe_add_vxlan_port,
-       .ndo_udp_tunnel_del     = ixgbe_del_vxlan_port,
+       .ndo_udp_tunnel_add     = ixgbe_add_udp_tunnel_port,
+       .ndo_udp_tunnel_del     = ixgbe_del_udp_tunnel_port,
        .ndo_features_check     = ixgbe_features_check,
 };