static int qed_slowpath_start(struct qed_dev *cdev,
                              struct qed_slowpath_params *params)
 {
+       struct qed_tunn_start_params tunn_info;
        struct qed_mcp_drv_version drv_version;
        const u8 *data = NULL;
        struct qed_hwfn *hwfn;
        /* Start the slowpath */
        data = cdev->firmware->data;
 
-       rc = qed_hw_init(cdev, NULL, true, cdev->int_params.out.int_mode,
+       memset(&tunn_info, 0, sizeof(tunn_info));
+       tunn_info.tunn_mode |=  1 << QED_MODE_VXLAN_TUNN;
+       tunn_info.tunn_clss_vxlan = QED_TUNN_CLSS_MAC_VLAN;
+
+       rc = qed_hw_init(cdev, &tunn_info, true,
+                        cdev->int_params.out.int_mode,
                         true, data);
        if (rc)
                goto err2;
 
 #include <linux/netdev_features.h>
 #include <linux/udp.h>
 #include <linux/tcp.h>
+#ifdef CONFIG_QEDE_VXLAN
 #include <net/vxlan.h>
+#endif
 #include <linux/ip.h>
 #include <net/ipv6.h>
 #include <net/tcp.h>
        edev->accept_any_vlan = false;
 }
 
+#ifdef CONFIG_QEDE_VXLAN
+static void qede_add_vxlan_port(struct net_device *dev,
+                               sa_family_t sa_family, __be16 port)
+{
+       struct qede_dev *edev = netdev_priv(dev);
+       u16 t_port = ntohs(port);
+
+       if (edev->vxlan_dst_port)
+               return;
+
+       edev->vxlan_dst_port = t_port;
+
+       DP_VERBOSE(edev, QED_MSG_DEBUG, "Added vxlan port=%d", t_port);
+
+       set_bit(QEDE_SP_VXLAN_PORT_CONFIG, &edev->sp_flags);
+       schedule_delayed_work(&edev->sp_task, 0);
+}
+
+static void qede_del_vxlan_port(struct net_device *dev,
+                               sa_family_t sa_family, __be16 port)
+{
+       struct qede_dev *edev = netdev_priv(dev);
+       u16 t_port = ntohs(port);
+
+       if (t_port != edev->vxlan_dst_port)
+               return;
+
+       edev->vxlan_dst_port = 0;
+
+       DP_VERBOSE(edev, QED_MSG_DEBUG, "Deleted vxlan port=%d", t_port);
+
+       set_bit(QEDE_SP_VXLAN_PORT_CONFIG, &edev->sp_flags);
+       schedule_delayed_work(&edev->sp_task, 0);
+}
+#endif
+
 static const struct net_device_ops qede_netdev_ops = {
        .ndo_open = qede_open,
        .ndo_stop = qede_close,
        .ndo_vlan_rx_add_vid = qede_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid = qede_vlan_rx_kill_vid,
        .ndo_get_stats64 = qede_get_stats64,
+#ifdef CONFIG_QEDE_VXLAN
+       .ndo_add_vxlan_port = qede_add_vxlan_port,
+       .ndo_del_vxlan_port = qede_del_vxlan_port,
+#endif
 };
 
 /* -------------------------------------------------------------------------
 {
        struct qede_dev *edev = container_of(work, struct qede_dev,
                                             sp_task.work);
+       struct qed_dev *cdev = edev->cdev;
+
        mutex_lock(&edev->qede_lock);
 
        if (edev->state == QEDE_STATE_OPEN) {
                        qede_config_rx_mode(edev->ndev);
        }
 
+       if (test_and_clear_bit(QEDE_SP_VXLAN_PORT_CONFIG, &edev->sp_flags)) {
+               struct qed_tunn_params tunn_params;
+
+               memset(&tunn_params, 0, sizeof(tunn_params));
+               tunn_params.update_vxlan_port = 1;
+               tunn_params.vxlan_port = edev->vxlan_dst_port;
+               qed_ops->tunn_config(cdev, &tunn_params);
+       }
+
        mutex_unlock(&edev->qede_lock);
 }
 
 static int qede_open(struct net_device *ndev)
 {
        struct qede_dev *edev = netdev_priv(ndev);
+       int rc;
 
        netif_carrier_off(ndev);
 
        edev->ops->common->set_power_state(edev->cdev, PCI_D0);
 
-       return qede_load(edev, QEDE_LOAD_NORMAL);
+       rc = qede_load(edev, QEDE_LOAD_NORMAL);
+
+       if (rc)
+               return rc;
+
+#ifdef CONFIG_QEDE_VXLAN
+       vxlan_get_rx_port(ndev);
+#endif
+       return 0;
 }
 
 static int qede_close(struct net_device *ndev)