/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __TSM_H
#define __TSM_H

#include <linux/sizes.h>
#include <linux/types.h>
#include <linux/uuid.h>
#include <linux/device.h>

#define TSM_REPORT_INBLOB_MAX 64
#define TSM_REPORT_OUTBLOB_MAX SZ_16M


#define TSM_REPORT_PRIVLEVEL_MAX 3


struct tsm_report_desc {
	unsigned int privlevel;
	size_t inblob_len;
	u8 inblob[TSM_REPORT_INBLOB_MAX];
	char *service_provider;
	guid_t service_guid;
	unsigned int service_manifest_version;
};


struct tsm_report {
	struct tsm_report_desc desc;
	size_t outblob_len;
	u8 *outblob;
	size_t auxblob_len;
	u8 *auxblob;
	size_t manifestblob_len;
	u8 *manifestblob;
};


enum tsm_attr_index {
	TSM_REPORT_GENERATION,
	TSM_REPORT_PROVIDER,
	TSM_REPORT_PRIVLEVEL,
	TSM_REPORT_PRIVLEVEL_FLOOR,
	TSM_REPORT_SERVICE_PROVIDER,
	TSM_REPORT_SERVICE_GUID,
	TSM_REPORT_SERVICE_MANIFEST_VER,
};


enum tsm_bin_attr_index {
	TSM_REPORT_INBLOB,
	TSM_REPORT_OUTBLOB,
	TSM_REPORT_AUXBLOB,
	TSM_REPORT_MANIFESTBLOB,
};


struct tsm_report_ops {
	const char *name;
	unsigned int privlevel_floor;
	int (*report_new)(struct tsm_report *report, void *data);
	bool (*report_attr_visible)(int n);
	bool (*report_bin_attr_visible)(int n);
};

struct pci_tsm_ops;
struct tsm_dev {
	struct device dev;
	int id;
	const struct pci_tsm_ops *pci_ops;
};

DEFINE_FREE(put_tsm_dev, struct tsm_dev *,
	    if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev))

int tsm_report_register(const struct tsm_report_ops *ops, void *priv);
int tsm_report_unregister(const struct tsm_report_ops *ops);
struct tsm_dev *tsm_register(struct device *parent, struct pci_tsm_ops *ops);
void tsm_unregister(struct tsm_dev *tsm_dev);
struct tsm_dev *find_tsm_dev(int id);
#endif 
