xref: /linux/drivers/char/tpm/tpm_tis_core.h (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2005, 2006 IBM Corporation
4  * Copyright (C) 2014, 2015 Intel Corporation
5  *
6  * Authors:
7  * Leendert van Doorn <leendert@watson.ibm.com>
8  * Kylene Hall <kjhall@us.ibm.com>
9  *
10  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
11  *
12  * Device driver for TCG/TCPA TPM (trusted platform module).
13  * Specifications at www.trustedcomputinggroup.org
14  *
15  * This device driver implements the TPM interface as defined in
16  * the TCG TPM Interface Spec version 1.2, revision 1.0.
17  */
18 
19 #ifndef __TPM_TIS_CORE_H__
20 #define __TPM_TIS_CORE_H__
21 
22 #include <linux/tpm_ptp.h>
23 #include "tpm.h"
24 
25 enum tpm_tis_flags {
26 	TPM_TIS_ITPM_WORKAROUND		= 0,
27 	TPM_TIS_INVALID_STATUS		= 1,
28 	TPM_TIS_DEFAULT_CANCELLATION	= 2,
29 	TPM_TIS_IRQ_TESTED		= 3,
30 	TPM_TIS_STATUS_VALID_RETRY	= 4,
31 	TPM_TIS_SETTLE_AFTER_RELINQUISH	= 5,
32 };
33 
34 struct tpm_tis_data {
35 	struct tpm_chip *chip;
36 	u32 did_vid;
37 	struct mutex locality_count_mutex;
38 	unsigned int locality_count;
39 	int locality;
40 	int irq;
41 	struct work_struct free_irq_work;
42 	unsigned long last_unhandled_irq;
43 	unsigned int unhandled_irqs;
44 	unsigned int int_mask;
45 	unsigned long flags;
46 	void __iomem *ilb_base_addr;
47 	u16 clkrun_enabled;
48 	wait_queue_head_t int_queue;
49 	wait_queue_head_t read_queue;
50 	const struct tpm_tis_phy_ops *phy_ops;
51 	unsigned short rng_quality;
52 	unsigned int timeout_min; /* usecs */
53 	unsigned int timeout_max; /* usecs */
54 };
55 
56 /*
57  * IO modes to indicate how many bytes should be read/written at once in the
58  * tpm_tis_phy_ops read_bytes/write_bytes calls. Use TPM_TIS_PHYS_8 to
59  * receive/transmit byte-wise, TPM_TIS_PHYS_16 for two bytes etc.
60  */
61 enum tpm_tis_io_mode {
62 	TPM_TIS_PHYS_8,
63 	TPM_TIS_PHYS_16,
64 	TPM_TIS_PHYS_32,
65 };
66 
67 struct tpm_tis_phy_ops {
68 	/* data is passed in little endian */
69 	int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
70 			  u8 *result, enum tpm_tis_io_mode mode);
71 	int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
72 			   const u8 *value, enum tpm_tis_io_mode mode);
73 	int (*verify_crc)(struct tpm_tis_data *data, size_t len,
74 			  const u8 *value);
75 };
76 
77 static inline int tpm_tis_read_bytes(struct tpm_tis_data *data, u32 addr,
78 				     u16 len, u8 *result)
79 {
80 	return data->phy_ops->read_bytes(data, addr, len, result,
81 					 TPM_TIS_PHYS_8);
82 }
83 
84 static inline int tpm_tis_read8(struct tpm_tis_data *data, u32 addr, u8 *result)
85 {
86 	return data->phy_ops->read_bytes(data, addr, 1, result, TPM_TIS_PHYS_8);
87 }
88 
89 static inline int tpm_tis_read16(struct tpm_tis_data *data, u32 addr,
90 				 u16 *result)
91 {
92 	__le16 result_le;
93 	int rc;
94 
95 	rc = data->phy_ops->read_bytes(data, addr, sizeof(u16),
96 				       (u8 *)&result_le, TPM_TIS_PHYS_16);
97 	if (!rc)
98 		*result = le16_to_cpu(result_le);
99 
100 	return rc;
101 }
102 
103 static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr,
104 				 u32 *result)
105 {
106 	__le32 result_le;
107 	int rc;
108 
109 	rc = data->phy_ops->read_bytes(data, addr, sizeof(u32),
110 				       (u8 *)&result_le, TPM_TIS_PHYS_32);
111 	if (!rc)
112 		*result = le32_to_cpu(result_le);
113 
114 	return rc;
115 }
116 
117 static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
118 				      u16 len, const u8 *value)
119 {
120 	return data->phy_ops->write_bytes(data, addr, len, value,
121 					  TPM_TIS_PHYS_8);
122 }
123 
124 static inline int tpm_tis_write8(struct tpm_tis_data *data, u32 addr, u8 value)
125 {
126 	return data->phy_ops->write_bytes(data, addr, 1, &value,
127 					  TPM_TIS_PHYS_8);
128 }
129 
130 static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr,
131 				  u32 value)
132 {
133 	__le32 value_le;
134 	int rc;
135 
136 	value_le = cpu_to_le32(value);
137 	rc =  data->phy_ops->write_bytes(data, addr, sizeof(u32),
138 					 (u8 *)&value_le, TPM_TIS_PHYS_32);
139 	return rc;
140 }
141 
142 static inline int tpm_tis_verify_crc(struct tpm_tis_data *data, size_t len,
143 				     const u8 *value)
144 {
145 	if (!data->phy_ops->verify_crc)
146 		return 0;
147 	return data->phy_ops->verify_crc(data, len, value);
148 }
149 
150 static inline bool is_bsw(void)
151 {
152 #ifdef CONFIG_X86
153 	return (boot_cpu_data.x86_vfm == INTEL_ATOM_AIRMONT) ? 1 : 0;
154 #else
155 	return false;
156 #endif
157 }
158 
159 void tpm_tis_remove(struct tpm_chip *chip);
160 int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
161 		      const struct tpm_tis_phy_ops *phy_ops,
162 		      acpi_handle acpi_dev_handle);
163 
164 #ifdef CONFIG_PM_SLEEP
165 int tpm_tis_resume(struct device *dev);
166 #endif
167 
168 #endif
169