diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 536b39ba9c..585e880f3c 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -963,7 +963,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	int err = 0;
 	unsigned int hw_padding = 0;
 	unsigned int mps;
-	unsigned int tunnel_en = 0;
 	unsigned int mpls_en = 0;
 	unsigned int swp = 0;
 	unsigned int mprq = 0;
@@ -1145,7 +1144,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	config->cqe_comp = 1;
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
 	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
-		tunnel_en = ((dv_attr.tunnel_offloads_caps &
+		config->tunnel_en = ((dv_attr.tunnel_offloads_caps &
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN) &&
 			     (dv_attr.tunnel_offloads_caps &
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE) &&
@@ -1153,12 +1152,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE));
 	}
 	DRV_LOG(DEBUG, "tunnel offloading is %ssupported",
-		tunnel_en ? "" : "not ");
+		config->tunnel_en ? "" : "not ");
 #else
 	DRV_LOG(WARNING,
 		"tunnel offloading disabled due to old OFED/rdma-core version");
 #endif
-	config->tunnel_en = tunnel_en;
 #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
 	mpls_en = ((dv_attr.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
diff --git a/drivers/net/mlx5/linux/mlx5_os.h b/drivers/net/mlx5/linux/mlx5_os.h
index da036edb72..80c70d713a 100644
--- a/drivers/net/mlx5/linux/mlx5_os.h
+++ b/drivers/net/mlx5/linux/mlx5_os.h
@@ -33,4 +33,19 @@ enum mlx5_sw_parsing_offloads {
 	MLX5_SW_PARSING_TSO_CAP  = 0,
 #endif
 };
+
+enum mlx5_tunnel_offloads {
+#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
+	MLX5_TUNNELED_OFFLOADS_VXLAN_CAP  =
+		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN,
+	MLX5_TUNNELED_OFFLOADS_GRE_CAP    =
+		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE,
+	MLX5_TUNNELED_OFFLOADS_GENEVE_CAP =
+		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE,
+#else
+	MLX5_TUNNELED_OFFLOADS_VXLAN_CAP  = 0,
+	MLX5_TUNNELED_OFFLOADS_GRE_CAP	  = 0,
+	MLX5_TUNNELED_OFFLOADS_GENEVE_CAP = 0,
+#endif
+};
 #endif /* RTE_PMD_MLX5_OS_H_ */
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 45713d1709..42688b2dc3 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -244,7 +244,7 @@ struct mlx5_dev_config {
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
 	unsigned int vf:1; /* This is a VF. */
 	unsigned int sf:1; /* This is a SF. */
-	unsigned int tunnel_en:1;
+	unsigned int tunnel_en:3;
 	/* Whether tunnel stateless offloads are supported. */
 	unsigned int mpls_en:1; /* MPLS over GRE/UDP is enabled. */
 	unsigned int cqe_comp:1; /* CQE compression is enabled. */
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 8dca2b7f79..54f42292ac 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -120,10 +120,17 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 	if (config->tunnel_en) {
 		if (config->hw_csum)
 			offloads |= DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
-		if (config->tso)
-			offloads |= (DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
-				     DEV_TX_OFFLOAD_GRE_TNL_TSO |
-				     DEV_TX_OFFLOAD_GENEVE_TNL_TSO);
+		if (config->tso) {
+			if (config->tunnel_en &
+				MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)
+				offloads |= DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+			if (config->tunnel_en &
+				MLX5_TUNNELED_OFFLOADS_GRE_CAP)
+				offloads |= DEV_TX_OFFLOAD_GRE_TNL_TSO;
+			if (config->tunnel_en &
+				MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)
+				offloads |= DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
+		}
 	}
 	if (!config->mprq.enabled)
 		offloads |= DEV_TX_OFFLOAD_MBUF_FAST_FREE;
@@ -978,7 +985,14 @@ txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 						    MLX5_MAX_TSO_HEADER);
 		txq_ctrl->txq.tso_en = 1;
 	}
-	txq_ctrl->txq.tunnel_en = config->tunnel_en | config->swp;
+	if (((DEV_TX_OFFLOAD_VXLAN_TNL_TSO & txq_ctrl->txq.offloads) &&
+	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)) |
+	   ((DEV_TX_OFFLOAD_GRE_TNL_TSO & txq_ctrl->txq.offloads) &&
+	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GRE_CAP)) |
+	   ((DEV_TX_OFFLOAD_GENEVE_TNL_TSO & txq_ctrl->txq.offloads) &&
+	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)) |
+	   (config->swp  & MLX5_SW_PARSING_TSO_CAP))
+		txq_ctrl->txq.tunnel_en = 1;
 	txq_ctrl->txq.swp_en = (((DEV_TX_OFFLOAD_IP_TNL_TSO |
 				  DEV_TX_OFFLOAD_UDP_TNL_TSO) &
 				  txq_ctrl->txq.offloads) && (config->swp &
