xref: /openbmc/linux/drivers/char/tpm/tpm_infineon.c (revision 87c2ce3b)
1 /*
2  * Description:
3  * Device Driver for the Infineon Technologies
4  * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
5  * Specifications at www.trustedcomputinggroup.org
6  *
7  * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
8  * Sirrix AG - security technologies, http://www.sirrix.com and
9  * Applied Data Security Group, Ruhr-University Bochum, Germany
10  * Project-Homepage: http://www.prosec.rub.de/tpm
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation, version 2 of the
15  * License.
16  */
17 
18 #include <linux/pnp.h>
19 #include "tpm.h"
20 
21 /* Infineon specific definitions */
22 /* maximum number of WTX-packages */
23 #define	TPM_MAX_WTX_PACKAGES 	50
24 /* msleep-Time for WTX-packages */
25 #define	TPM_WTX_MSLEEP_TIME 	20
26 /* msleep-Time --> Interval to check status register */
27 #define	TPM_MSLEEP_TIME 	3
28 /* gives number of max. msleep()-calls before throwing timeout */
29 #define	TPM_MAX_TRIES		5000
30 #define	TPM_INFINEON_DEV_VEN_VALUE	0x15D1
31 
32 /* These values will be filled after PnP-call */
33 static int TPM_INF_DATA;
34 static int TPM_INF_ADDR;
35 static int TPM_INF_BASE;
36 static int TPM_INF_PORT_LEN;
37 
38 /* TPM header definitions */
39 enum infineon_tpm_header {
40 	TPM_VL_VER = 0x01,
41 	TPM_VL_CHANNEL_CONTROL = 0x07,
42 	TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
43 	TPM_VL_CHANNEL_TPM = 0x0B,
44 	TPM_VL_CONTROL = 0x00,
45 	TPM_INF_NAK = 0x15,
46 	TPM_CTRL_WTX = 0x10,
47 	TPM_CTRL_WTX_ABORT = 0x18,
48 	TPM_CTRL_WTX_ABORT_ACK = 0x18,
49 	TPM_CTRL_ERROR = 0x20,
50 	TPM_CTRL_CHAININGACK = 0x40,
51 	TPM_CTRL_CHAINING = 0x80,
52 	TPM_CTRL_DATA = 0x04,
53 	TPM_CTRL_DATA_CHA = 0x84,
54 	TPM_CTRL_DATA_CHA_ACK = 0xC4
55 };
56 
57 enum infineon_tpm_register {
58 	WRFIFO = 0x00,
59 	RDFIFO = 0x01,
60 	STAT = 0x02,
61 	CMD = 0x03
62 };
63 
64 enum infineon_tpm_command_bits {
65 	CMD_DIS = 0x00,
66 	CMD_LP = 0x01,
67 	CMD_RES = 0x02,
68 	CMD_IRQC = 0x06
69 };
70 
71 enum infineon_tpm_status_bits {
72 	STAT_XFE = 0x00,
73 	STAT_LPA = 0x01,
74 	STAT_FOK = 0x02,
75 	STAT_TOK = 0x03,
76 	STAT_IRQA = 0x06,
77 	STAT_RDA = 0x07
78 };
79 
80 /* some outgoing values */
81 enum infineon_tpm_values {
82 	CHIP_ID1 = 0x20,
83 	CHIP_ID2 = 0x21,
84 	TPM_DAR = 0x30,
85 	RESET_LP_IRQC_DISABLE = 0x41,
86 	ENABLE_REGISTER_PAIR = 0x55,
87 	IOLIMH = 0x60,
88 	IOLIML = 0x61,
89 	DISABLE_REGISTER_PAIR = 0xAA,
90 	IDVENL = 0xF1,
91 	IDVENH = 0xF2,
92 	IDPDL = 0xF3,
93 	IDPDH = 0xF4
94 };
95 
96 static int number_of_wtx;
97 
98 static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
99 {
100 	int status;
101 	int check = 0;
102 	int i;
103 
104 	if (clear_wrfifo) {
105 		for (i = 0; i < 4096; i++) {
106 			status = inb(chip->vendor->base + WRFIFO);
107 			if (status == 0xff) {
108 				if (check == 5)
109 					break;
110 				else
111 					check++;
112 			}
113 		}
114 	}
115 	/* Note: The values which are currently in the FIFO of the TPM
116 	   are thrown away since there is no usage for them. Usually,
117 	   this has nothing to say, since the TPM will give its answer
118 	   immediately or will be aborted anyway, so the data here is
119 	   usually garbage and useless.
120 	   We have to clean this, because the next communication with
121 	   the TPM would be rubbish, if there is still some old data
122 	   in the Read FIFO.
123 	 */
124 	i = 0;
125 	do {
126 		status = inb(chip->vendor->base + RDFIFO);
127 		status = inb(chip->vendor->base + STAT);
128 		i++;
129 		if (i == TPM_MAX_TRIES)
130 			return -EIO;
131 	} while ((status & (1 << STAT_RDA)) != 0);
132 	return 0;
133 }
134 
135 static int wait(struct tpm_chip *chip, int wait_for_bit)
136 {
137 	int status;
138 	int i;
139 	for (i = 0; i < TPM_MAX_TRIES; i++) {
140 		status = inb(chip->vendor->base + STAT);
141 		/* check the status-register if wait_for_bit is set */
142 		if (status & 1 << wait_for_bit)
143 			break;
144 		msleep(TPM_MSLEEP_TIME);
145 	}
146 	if (i == TPM_MAX_TRIES) {	/* timeout occurs */
147 		if (wait_for_bit == STAT_XFE)
148 			dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");
149 		if (wait_for_bit == STAT_RDA)
150 			dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");
151 		return -EIO;
152 	}
153 	return 0;
154 };
155 
156 static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
157 {
158 	wait(chip, STAT_XFE);
159 	outb(sendbyte, chip->vendor->base + WRFIFO);
160 }
161 
162     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
163        calculation time, it sends a WTX-package, which has to be acknowledged
164        or aborted. This usually occurs if you are hammering the TPM with key
165        creation. Set the maximum number of WTX-packages in the definitions
166        above, if the number is reached, the waiting-time will be denied
167        and the TPM command has to be resend.
168      */
169 
170 static void tpm_wtx(struct tpm_chip *chip)
171 {
172 	number_of_wtx++;
173 	dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",
174 		 number_of_wtx, TPM_MAX_WTX_PACKAGES);
175 	wait_and_send(chip, TPM_VL_VER);
176 	wait_and_send(chip, TPM_CTRL_WTX);
177 	wait_and_send(chip, 0x00);
178 	wait_and_send(chip, 0x00);
179 	msleep(TPM_WTX_MSLEEP_TIME);
180 }
181 
182 static void tpm_wtx_abort(struct tpm_chip *chip)
183 {
184 	dev_info(chip->dev, "Aborting WTX\n");
185 	wait_and_send(chip, TPM_VL_VER);
186 	wait_and_send(chip, TPM_CTRL_WTX_ABORT);
187 	wait_and_send(chip, 0x00);
188 	wait_and_send(chip, 0x00);
189 	number_of_wtx = 0;
190 	msleep(TPM_WTX_MSLEEP_TIME);
191 }
192 
193 static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
194 {
195 	int i;
196 	int ret;
197 	u32 size = 0;
198 
199 recv_begin:
200 	/* start receiving header */
201 	for (i = 0; i < 4; i++) {
202 		ret = wait(chip, STAT_RDA);
203 		if (ret)
204 			return -EIO;
205 		buf[i] = inb(chip->vendor->base + RDFIFO);
206 	}
207 
208 	if (buf[0] != TPM_VL_VER) {
209 		dev_err(chip->dev,
210 			"Wrong transport protocol implementation!\n");
211 		return -EIO;
212 	}
213 
214 	if (buf[1] == TPM_CTRL_DATA) {
215 		/* size of the data received */
216 		size = ((buf[2] << 8) | buf[3]);
217 
218 		for (i = 0; i < size; i++) {
219 			wait(chip, STAT_RDA);
220 			buf[i] = inb(chip->vendor->base + RDFIFO);
221 		}
222 
223 		if ((size == 0x6D00) && (buf[1] == 0x80)) {
224 			dev_err(chip->dev, "Error handling on vendor layer!\n");
225 			return -EIO;
226 		}
227 
228 		for (i = 0; i < size; i++)
229 			buf[i] = buf[i + 6];
230 
231 		size = size - 6;
232 		return size;
233 	}
234 
235 	if (buf[1] == TPM_CTRL_WTX) {
236 		dev_info(chip->dev, "WTX-package received\n");
237 		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
238 			tpm_wtx(chip);
239 			goto recv_begin;
240 		} else {
241 			tpm_wtx_abort(chip);
242 			goto recv_begin;
243 		}
244 	}
245 
246 	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
247 		dev_info(chip->dev, "WTX-abort acknowledged\n");
248 		return size;
249 	}
250 
251 	if (buf[1] == TPM_CTRL_ERROR) {
252 		dev_err(chip->dev, "ERROR-package received:\n");
253 		if (buf[4] == TPM_INF_NAK)
254 			dev_err(chip->dev,
255 				"-> Negative acknowledgement"
256 				" - retransmit command!\n");
257 		return -EIO;
258 	}
259 	return -EIO;
260 }
261 
262 static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
263 {
264 	int i;
265 	int ret;
266 	u8 count_high, count_low, count_4, count_3, count_2, count_1;
267 
268 	/* Disabling Reset, LP and IRQC */
269 	outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
270 
271 	ret = empty_fifo(chip, 1);
272 	if (ret) {
273 		dev_err(chip->dev, "Timeout while clearing FIFO\n");
274 		return -EIO;
275 	}
276 
277 	ret = wait(chip, STAT_XFE);
278 	if (ret)
279 		return -EIO;
280 
281 	count_4 = (count & 0xff000000) >> 24;
282 	count_3 = (count & 0x00ff0000) >> 16;
283 	count_2 = (count & 0x0000ff00) >> 8;
284 	count_1 = (count & 0x000000ff);
285 	count_high = ((count + 6) & 0xffffff00) >> 8;
286 	count_low = ((count + 6) & 0x000000ff);
287 
288 	/* Sending Header */
289 	wait_and_send(chip, TPM_VL_VER);
290 	wait_and_send(chip, TPM_CTRL_DATA);
291 	wait_and_send(chip, count_high);
292 	wait_and_send(chip, count_low);
293 
294 	/* Sending Data Header */
295 	wait_and_send(chip, TPM_VL_VER);
296 	wait_and_send(chip, TPM_VL_CHANNEL_TPM);
297 	wait_and_send(chip, count_4);
298 	wait_and_send(chip, count_3);
299 	wait_and_send(chip, count_2);
300 	wait_and_send(chip, count_1);
301 
302 	/* Sending Data */
303 	for (i = 0; i < count; i++) {
304 		wait_and_send(chip, buf[i]);
305 	}
306 	return count;
307 }
308 
309 static void tpm_inf_cancel(struct tpm_chip *chip)
310 {
311 	/*
312 	   Since we are using the legacy mode to communicate
313 	   with the TPM, we have no cancel functions, but have
314 	   a workaround for interrupting the TPM through WTX.
315 	 */
316 }
317 
318 static u8 tpm_inf_status(struct tpm_chip *chip)
319 {
320 	return inb(chip->vendor->base + STAT);
321 }
322 
323 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
324 static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
325 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
326 static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
327 
328 static struct attribute *inf_attrs[] = {
329 	&dev_attr_pubek.attr,
330 	&dev_attr_pcrs.attr,
331 	&dev_attr_caps.attr,
332 	&dev_attr_cancel.attr,
333 	NULL,
334 };
335 
336 static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
337 
338 static struct file_operations inf_ops = {
339 	.owner = THIS_MODULE,
340 	.llseek = no_llseek,
341 	.open = tpm_open,
342 	.read = tpm_read,
343 	.write = tpm_write,
344 	.release = tpm_release,
345 };
346 
347 static struct tpm_vendor_specific tpm_inf = {
348 	.recv = tpm_inf_recv,
349 	.send = tpm_inf_send,
350 	.cancel = tpm_inf_cancel,
351 	.status = tpm_inf_status,
352 	.req_complete_mask = 0,
353 	.req_complete_val = 0,
354 	.attr_group = &inf_attr_grp,
355 	.miscdev = {.fops = &inf_ops,},
356 };
357 
358 static const struct pnp_device_id tpm_pnp_tbl[] = {
359 	/* Infineon TPMs */
360 	{"IFX0101", 0},
361 	{"IFX0102", 0},
362 	{"", 0}
363 };
364 
365 MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
366 
367 static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
368 				       const struct pnp_device_id *dev_id)
369 {
370 	int rc = 0;
371 	u8 iol, ioh;
372 	int vendorid[2];
373 	int version[2];
374 	int productid[2];
375 	char chipname[20];
376 
377 	/* read IO-ports through PnP */
378 	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
379 	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
380 		TPM_INF_ADDR = pnp_port_start(dev, 0);
381 		TPM_INF_DATA = (TPM_INF_ADDR + 1);
382 		TPM_INF_BASE = pnp_port_start(dev, 1);
383 		TPM_INF_PORT_LEN = pnp_port_len(dev, 1);
384 		if (!TPM_INF_PORT_LEN)
385 			return -EINVAL;
386 		dev_info(&dev->dev, "Found %s with ID %s\n",
387 			 dev->name, dev_id->id);
388 		if (!((TPM_INF_BASE >> 8) & 0xff))
389 			return -EINVAL;
390 		/* publish my base address and request region */
391 		tpm_inf.base = TPM_INF_BASE;
392 		if (request_region
393 		    (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
394 			release_region(tpm_inf.base, TPM_INF_PORT_LEN);
395 			return -EINVAL;
396 		}
397 	} else {
398 		return -EINVAL;
399 	}
400 
401 	/* query chip for its vendor, its version number a.s.o. */
402 	outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
403 	outb(IDVENL, TPM_INF_ADDR);
404 	vendorid[1] = inb(TPM_INF_DATA);
405 	outb(IDVENH, TPM_INF_ADDR);
406 	vendorid[0] = inb(TPM_INF_DATA);
407 	outb(IDPDL, TPM_INF_ADDR);
408 	productid[1] = inb(TPM_INF_DATA);
409 	outb(IDPDH, TPM_INF_ADDR);
410 	productid[0] = inb(TPM_INF_DATA);
411 	outb(CHIP_ID1, TPM_INF_ADDR);
412 	version[1] = inb(TPM_INF_DATA);
413 	outb(CHIP_ID2, TPM_INF_ADDR);
414 	version[0] = inb(TPM_INF_DATA);
415 
416 	switch ((productid[0] << 8) | productid[1]) {
417 	case 6:
418 		snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");
419 		break;
420 	case 11:
421 		snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");
422 		break;
423 	default:
424 		snprintf(chipname, sizeof(chipname), " (unknown chip)");
425 		break;
426 	}
427 
428 	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
429 
430 		/* configure TPM with IO-ports */
431 		outb(IOLIMH, TPM_INF_ADDR);
432 		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
433 		outb(IOLIML, TPM_INF_ADDR);
434 		outb((tpm_inf.base & 0xff), TPM_INF_DATA);
435 
436 		/* control if IO-ports are set correctly */
437 		outb(IOLIMH, TPM_INF_ADDR);
438 		ioh = inb(TPM_INF_DATA);
439 		outb(IOLIML, TPM_INF_ADDR);
440 		iol = inb(TPM_INF_DATA);
441 
442 		if ((ioh << 8 | iol) != tpm_inf.base) {
443 			dev_err(&dev->dev,
444 				"Could not set IO-ports to %04x\n",
445 				tpm_inf.base);
446 			release_region(tpm_inf.base, TPM_INF_PORT_LEN);
447 			return -EIO;
448 		}
449 
450 		/* activate register */
451 		outb(TPM_DAR, TPM_INF_ADDR);
452 		outb(0x01, TPM_INF_DATA);
453 		outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
454 
455 		/* disable RESET, LP and IRQC */
456 		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
457 
458 		/* Finally, we're done, print some infos */
459 		dev_info(&dev->dev, "TPM found: "
460 			 "config base 0x%x, "
461 			 "io base 0x%x, "
462 			 "chip version %02x%02x, "
463 			 "vendor id %x%x (Infineon), "
464 			 "product id %02x%02x"
465 			 "%s\n",
466 			 TPM_INF_ADDR,
467 			 TPM_INF_BASE,
468 			 version[0], version[1],
469 			 vendorid[0], vendorid[1],
470 			 productid[0], productid[1], chipname);
471 
472 		rc = tpm_register_hardware(&dev->dev, &tpm_inf);
473 		if (rc < 0) {
474 			release_region(tpm_inf.base, TPM_INF_PORT_LEN);
475 			return -ENODEV;
476 		}
477 		return 0;
478 	} else {
479 		dev_info(&dev->dev, "No Infineon TPM found!\n");
480 		return -ENODEV;
481 	}
482 }
483 
484 static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
485 {
486 	struct tpm_chip *chip = pnp_get_drvdata(dev);
487 
488 	if (chip) {
489 		release_region(chip->vendor->base, TPM_INF_PORT_LEN);
490 		tpm_remove_hardware(chip->dev);
491 	}
492 }
493 
494 static struct pnp_driver tpm_inf_pnp = {
495 	.name = "tpm_inf_pnp",
496 	.driver = {
497 		.owner = THIS_MODULE,
498 		.suspend = tpm_pm_suspend,
499 		.resume = tpm_pm_resume,
500 	},
501 	.id_table = tpm_pnp_tbl,
502 	.probe = tpm_inf_pnp_probe,
503 	.remove = tpm_inf_pnp_remove,
504 };
505 
506 static int __init init_inf(void)
507 {
508 	return pnp_register_driver(&tpm_inf_pnp);
509 }
510 
511 static void __exit cleanup_inf(void)
512 {
513 	pnp_unregister_driver(&tpm_inf_pnp);
514 }
515 
516 module_init(init_inf);
517 module_exit(cleanup_inf);
518 
519 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
520 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
521 MODULE_VERSION("1.6");
522 MODULE_LICENSE("GPL");
523