Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Description:
  4 * Device Driver for the Infineon Technologies
  5 * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
  6 * Specifications at www.trustedcomputinggroup.org
  7 *
  8 * Copyright (C) 2005, Marcel Selhorst <tpmdd@selhorst.net>
  9 * Sirrix AG - security technologies <tpmdd@sirrix.com> and
 10 * Applied Data Security Group, Ruhr-University Bochum, Germany
 11 * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ 
 
 
 
 
 
 12 */
 13
 14#include <linux/init.h>
 15#include <linux/pnp.h>
 16#include "tpm.h"
 17
 18/* Infineon specific definitions */
 19/* maximum number of WTX-packages */
 20#define	TPM_MAX_WTX_PACKAGES 	50
 21/* msleep-Time for WTX-packages */
 22#define	TPM_WTX_MSLEEP_TIME 	20
 23/* msleep-Time --> Interval to check status register */
 24#define	TPM_MSLEEP_TIME 	3
 25/* gives number of max. msleep()-calls before throwing timeout */
 26#define	TPM_MAX_TRIES		5000
 27#define	TPM_INFINEON_DEV_VEN_VALUE	0x15D1
 28
 29#define TPM_INF_IO_PORT		0x0
 30#define TPM_INF_IO_MEM		0x1
 31
 32#define TPM_INF_ADDR		0x0
 33#define TPM_INF_DATA		0x1
 34
 35struct tpm_inf_dev {
 36	int iotype;
 37
 38	void __iomem *mem_base;	/* MMIO ioremap'd addr */
 39	unsigned long map_base;	/* phys MMIO base */
 40	unsigned long map_size;	/* MMIO region size */
 41	unsigned int index_off;	/* index register offset */
 42
 43	unsigned int data_regs;	/* Data registers */
 44	unsigned int data_size;
 45
 46	unsigned int config_port;	/* IO Port config index reg */
 47	unsigned int config_size;
 48};
 49
 50static struct tpm_inf_dev tpm_dev;
 51
 52static inline void tpm_data_out(unsigned char data, unsigned char offset)
 53{
 54	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 55		outb(data, tpm_dev.data_regs + offset);
 56	else
 57		writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
 58}
 59
 60static inline unsigned char tpm_data_in(unsigned char offset)
 61{
 62	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 63		return inb(tpm_dev.data_regs + offset);
 64	else
 65		return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
 66}
 67
 68static inline void tpm_config_out(unsigned char data, unsigned char offset)
 69{
 70	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 71		outb(data, tpm_dev.config_port + offset);
 72	else
 73		writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
 74}
 75
 76static inline unsigned char tpm_config_in(unsigned char offset)
 77{
 78	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 79		return inb(tpm_dev.config_port + offset);
 80	else
 81		return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
 82}
 83
 84/* TPM header definitions */
 85enum infineon_tpm_header {
 86	TPM_VL_VER = 0x01,
 87	TPM_VL_CHANNEL_CONTROL = 0x07,
 88	TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
 89	TPM_VL_CHANNEL_TPM = 0x0B,
 90	TPM_VL_CONTROL = 0x00,
 91	TPM_INF_NAK = 0x15,
 92	TPM_CTRL_WTX = 0x10,
 93	TPM_CTRL_WTX_ABORT = 0x18,
 94	TPM_CTRL_WTX_ABORT_ACK = 0x18,
 95	TPM_CTRL_ERROR = 0x20,
 96	TPM_CTRL_CHAININGACK = 0x40,
 97	TPM_CTRL_CHAINING = 0x80,
 98	TPM_CTRL_DATA = 0x04,
 99	TPM_CTRL_DATA_CHA = 0x84,
100	TPM_CTRL_DATA_CHA_ACK = 0xC4
101};
102
103enum infineon_tpm_register {
104	WRFIFO = 0x00,
105	RDFIFO = 0x01,
106	STAT = 0x02,
107	CMD = 0x03
108};
109
110enum infineon_tpm_command_bits {
111	CMD_DIS = 0x00,
112	CMD_LP = 0x01,
113	CMD_RES = 0x02,
114	CMD_IRQC = 0x06
115};
116
117enum infineon_tpm_status_bits {
118	STAT_XFE = 0x00,
119	STAT_LPA = 0x01,
120	STAT_FOK = 0x02,
121	STAT_TOK = 0x03,
122	STAT_IRQA = 0x06,
123	STAT_RDA = 0x07
124};
125
126/* some outgoing values */
127enum infineon_tpm_values {
128	CHIP_ID1 = 0x20,
129	CHIP_ID2 = 0x21,
130	TPM_DAR = 0x30,
131	RESET_LP_IRQC_DISABLE = 0x41,
132	ENABLE_REGISTER_PAIR = 0x55,
133	IOLIMH = 0x60,
134	IOLIML = 0x61,
135	DISABLE_REGISTER_PAIR = 0xAA,
136	IDVENL = 0xF1,
137	IDVENH = 0xF2,
138	IDPDL = 0xF3,
139	IDPDH = 0xF4
140};
141
142static int number_of_wtx;
143
144static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
145{
146	int status;
147	int check = 0;
148	int i;
149
150	if (clear_wrfifo) {
151		for (i = 0; i < 4096; i++) {
152			status = tpm_data_in(WRFIFO);
153			if (status == 0xff) {
154				if (check == 5)
155					break;
156				else
157					check++;
158			}
159		}
160	}
161	/* Note: The values which are currently in the FIFO of the TPM
162	   are thrown away since there is no usage for them. Usually,
163	   this has nothing to say, since the TPM will give its answer
164	   immediately or will be aborted anyway, so the data here is
165	   usually garbage and useless.
166	   We have to clean this, because the next communication with
167	   the TPM would be rubbish, if there is still some old data
168	   in the Read FIFO.
169	 */
170	i = 0;
171	do {
172		status = tpm_data_in(RDFIFO);
173		status = tpm_data_in(STAT);
174		i++;
175		if (i == TPM_MAX_TRIES)
176			return -EIO;
177	} while ((status & (1 << STAT_RDA)) != 0);
178	return 0;
179}
180
181static int wait(struct tpm_chip *chip, int wait_for_bit)
182{
183	int status;
184	int i;
185	for (i = 0; i < TPM_MAX_TRIES; i++) {
186		status = tpm_data_in(STAT);
187		/* check the status-register if wait_for_bit is set */
188		if (status & 1 << wait_for_bit)
189			break;
190		tpm_msleep(TPM_MSLEEP_TIME);
191	}
192	if (i == TPM_MAX_TRIES) {	/* timeout occurs */
193		if (wait_for_bit == STAT_XFE)
194			dev_err(&chip->dev, "Timeout in wait(STAT_XFE)\n");
195		if (wait_for_bit == STAT_RDA)
196			dev_err(&chip->dev, "Timeout in wait(STAT_RDA)\n");
197		return -EIO;
198	}
199	return 0;
200};
201
202static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
203{
204	wait(chip, STAT_XFE);
205	tpm_data_out(sendbyte, WRFIFO);
206}
207
208    /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
209       calculation time, it sends a WTX-package, which has to be acknowledged
210       or aborted. This usually occurs if you are hammering the TPM with key
211       creation. Set the maximum number of WTX-packages in the definitions
212       above, if the number is reached, the waiting-time will be denied
213       and the TPM command has to be resend.
214     */
215
216static void tpm_wtx(struct tpm_chip *chip)
217{
218	number_of_wtx++;
219	dev_info(&chip->dev, "Granting WTX (%02d / %02d)\n",
220		 number_of_wtx, TPM_MAX_WTX_PACKAGES);
221	wait_and_send(chip, TPM_VL_VER);
222	wait_and_send(chip, TPM_CTRL_WTX);
223	wait_and_send(chip, 0x00);
224	wait_and_send(chip, 0x00);
225	tpm_msleep(TPM_WTX_MSLEEP_TIME);
226}
227
228static void tpm_wtx_abort(struct tpm_chip *chip)
229{
230	dev_info(&chip->dev, "Aborting WTX\n");
231	wait_and_send(chip, TPM_VL_VER);
232	wait_and_send(chip, TPM_CTRL_WTX_ABORT);
233	wait_and_send(chip, 0x00);
234	wait_and_send(chip, 0x00);
235	number_of_wtx = 0;
236	tpm_msleep(TPM_WTX_MSLEEP_TIME);
237}
238
239static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
240{
241	int i;
242	int ret;
243	u32 size = 0;
244	number_of_wtx = 0;
245
246recv_begin:
247	/* start receiving header */
248	for (i = 0; i < 4; i++) {
249		ret = wait(chip, STAT_RDA);
250		if (ret)
251			return -EIO;
252		buf[i] = tpm_data_in(RDFIFO);
253	}
254
255	if (buf[0] != TPM_VL_VER) {
256		dev_err(&chip->dev,
257			"Wrong transport protocol implementation!\n");
258		return -EIO;
259	}
260
261	if (buf[1] == TPM_CTRL_DATA) {
262		/* size of the data received */
263		size = ((buf[2] << 8) | buf[3]);
264
265		for (i = 0; i < size; i++) {
266			wait(chip, STAT_RDA);
267			buf[i] = tpm_data_in(RDFIFO);
268		}
269
270		if ((size == 0x6D00) && (buf[1] == 0x80)) {
271			dev_err(&chip->dev, "Error handling on vendor layer!\n");
272			return -EIO;
273		}
274
275		for (i = 0; i < size; i++)
276			buf[i] = buf[i + 6];
277
278		size = size - 6;
279		return size;
280	}
281
282	if (buf[1] == TPM_CTRL_WTX) {
283		dev_info(&chip->dev, "WTX-package received\n");
284		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
285			tpm_wtx(chip);
286			goto recv_begin;
287		} else {
288			tpm_wtx_abort(chip);
289			goto recv_begin;
290		}
291	}
292
293	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
294		dev_info(&chip->dev, "WTX-abort acknowledged\n");
295		return size;
296	}
297
298	if (buf[1] == TPM_CTRL_ERROR) {
299		dev_err(&chip->dev, "ERROR-package received:\n");
300		if (buf[4] == TPM_INF_NAK)
301			dev_err(&chip->dev,
302				"-> Negative acknowledgement"
303				" - retransmit command!\n");
304		return -EIO;
305	}
306	return -EIO;
307}
308
309static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
310{
311	int i;
312	int ret;
313	u8 count_high, count_low, count_4, count_3, count_2, count_1;
314
315	/* Disabling Reset, LP and IRQC */
316	tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
317
318	ret = empty_fifo(chip, 1);
319	if (ret) {
320		dev_err(&chip->dev, "Timeout while clearing FIFO\n");
321		return -EIO;
322	}
323
324	ret = wait(chip, STAT_XFE);
325	if (ret)
326		return -EIO;
327
328	count_4 = (count & 0xff000000) >> 24;
329	count_3 = (count & 0x00ff0000) >> 16;
330	count_2 = (count & 0x0000ff00) >> 8;
331	count_1 = (count & 0x000000ff);
332	count_high = ((count + 6) & 0xffffff00) >> 8;
333	count_low = ((count + 6) & 0x000000ff);
334
335	/* Sending Header */
336	wait_and_send(chip, TPM_VL_VER);
337	wait_and_send(chip, TPM_CTRL_DATA);
338	wait_and_send(chip, count_high);
339	wait_and_send(chip, count_low);
340
341	/* Sending Data Header */
342	wait_and_send(chip, TPM_VL_VER);
343	wait_and_send(chip, TPM_VL_CHANNEL_TPM);
344	wait_and_send(chip, count_4);
345	wait_and_send(chip, count_3);
346	wait_and_send(chip, count_2);
347	wait_and_send(chip, count_1);
348
349	/* Sending Data */
350	for (i = 0; i < count; i++) {
351		wait_and_send(chip, buf[i]);
352	}
353	return 0;
354}
355
356static void tpm_inf_cancel(struct tpm_chip *chip)
357{
358	/*
359	   Since we are using the legacy mode to communicate
360	   with the TPM, we have no cancel functions, but have
361	   a workaround for interrupting the TPM through WTX.
362	 */
363}
364
365static u8 tpm_inf_status(struct tpm_chip *chip)
366{
367	return tpm_data_in(STAT);
368}
369
370static const struct tpm_class_ops tpm_inf = {
371	.recv = tpm_inf_recv,
372	.send = tpm_inf_send,
373	.cancel = tpm_inf_cancel,
374	.status = tpm_inf_status,
375	.req_complete_mask = 0,
376	.req_complete_val = 0,
377};
378
379static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
380	/* Infineon TPMs */
381	{"IFX0101", 0},
382	{"IFX0102", 0},
383	{"", 0}
384};
385
386MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
387
388static int tpm_inf_pnp_probe(struct pnp_dev *dev,
389				       const struct pnp_device_id *dev_id)
390{
391	int rc = 0;
392	u8 iol, ioh;
393	int vendorid[2];
394	int version[2];
395	int productid[2];
396	const char *chipname;
397	struct tpm_chip *chip;
398
399	/* read IO-ports through PnP */
400	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
401	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
402
403		tpm_dev.iotype = TPM_INF_IO_PORT;
404
405		tpm_dev.config_port = pnp_port_start(dev, 0);
406		tpm_dev.config_size = pnp_port_len(dev, 0);
407		tpm_dev.data_regs = pnp_port_start(dev, 1);
408		tpm_dev.data_size = pnp_port_len(dev, 1);
409		if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
410			rc = -EINVAL;
411			goto err_last;
412		}
413		dev_info(&dev->dev, "Found %s with ID %s\n",
414			 dev->name, dev_id->id);
415		if (!((tpm_dev.data_regs >> 8) & 0xff)) {
416			rc = -EINVAL;
417			goto err_last;
418		}
419		/* publish my base address and request region */
420		if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
421				   "tpm_infineon0") == NULL) {
422			rc = -EINVAL;
423			goto err_last;
424		}
425		if (request_region(tpm_dev.config_port, tpm_dev.config_size,
426				   "tpm_infineon0") == NULL) {
427			release_region(tpm_dev.data_regs, tpm_dev.data_size);
428			rc = -EINVAL;
429			goto err_last;
430		}
431	} else if (pnp_mem_valid(dev, 0) &&
432		   !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
433
434		tpm_dev.iotype = TPM_INF_IO_MEM;
435
436		tpm_dev.map_base = pnp_mem_start(dev, 0);
437		tpm_dev.map_size = pnp_mem_len(dev, 0);
438
439		dev_info(&dev->dev, "Found %s with ID %s\n",
440			 dev->name, dev_id->id);
441
442		/* publish my base address and request region */
443		if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
444				       "tpm_infineon0") == NULL) {
445			rc = -EINVAL;
446			goto err_last;
447		}
448
449		tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
450		if (tpm_dev.mem_base == NULL) {
451			release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
452			rc = -EINVAL;
453			goto err_last;
454		}
455
456		/*
457		 * The only known MMIO based Infineon TPM system provides
458		 * a single large mem region with the device config
459		 * registers at the default TPM_ADDR.  The data registers
460		 * seem like they could be placed anywhere within the MMIO
461		 * region, but lets just put them at zero offset.
462		 */
463		tpm_dev.index_off = TPM_ADDR;
464		tpm_dev.data_regs = 0x0;
465	} else {
466		rc = -EINVAL;
467		goto err_last;
468	}
469
470	/* query chip for its vendor, its version number a.s.o. */
471	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
472	tpm_config_out(IDVENL, TPM_INF_ADDR);
473	vendorid[1] = tpm_config_in(TPM_INF_DATA);
474	tpm_config_out(IDVENH, TPM_INF_ADDR);
475	vendorid[0] = tpm_config_in(TPM_INF_DATA);
476	tpm_config_out(IDPDL, TPM_INF_ADDR);
477	productid[1] = tpm_config_in(TPM_INF_DATA);
478	tpm_config_out(IDPDH, TPM_INF_ADDR);
479	productid[0] = tpm_config_in(TPM_INF_DATA);
480	tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
481	version[1] = tpm_config_in(TPM_INF_DATA);
482	tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
483	version[0] = tpm_config_in(TPM_INF_DATA);
484
485	switch ((productid[0] << 8) | productid[1]) {
486	case 6:
487		chipname = " (SLD 9630 TT 1.1)";
488		break;
489	case 11:
490		chipname = " (SLB 9635 TT 1.2)";
491		break;
492	default:
493		chipname = " (unknown chip)";
494		break;
495	}
496
497	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
498
499		/* configure TPM with IO-ports */
500		tpm_config_out(IOLIMH, TPM_INF_ADDR);
501		tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
502		tpm_config_out(IOLIML, TPM_INF_ADDR);
503		tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
504
505		/* control if IO-ports are set correctly */
506		tpm_config_out(IOLIMH, TPM_INF_ADDR);
507		ioh = tpm_config_in(TPM_INF_DATA);
508		tpm_config_out(IOLIML, TPM_INF_ADDR);
509		iol = tpm_config_in(TPM_INF_DATA);
510
511		if ((ioh << 8 | iol) != tpm_dev.data_regs) {
512			dev_err(&dev->dev,
513				"Could not set IO-data registers to 0x%x\n",
514				tpm_dev.data_regs);
515			rc = -EIO;
516			goto err_release_region;
517		}
518
519		/* activate register */
520		tpm_config_out(TPM_DAR, TPM_INF_ADDR);
521		tpm_config_out(0x01, TPM_INF_DATA);
522		tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
523
524		/* disable RESET, LP and IRQC */
525		tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
526
527		/* Finally, we're done, print some infos */
528		dev_info(&dev->dev, "TPM found: "
529			 "config base 0x%lx, "
530			 "data base 0x%lx, "
531			 "chip version 0x%02x%02x, "
532			 "vendor id 0x%x%x (Infineon), "
533			 "product id 0x%02x%02x"
534			 "%s\n",
535			 tpm_dev.iotype == TPM_INF_IO_PORT ?
536			 tpm_dev.config_port :
537			 tpm_dev.map_base + tpm_dev.index_off,
538			 tpm_dev.iotype == TPM_INF_IO_PORT ?
539			 tpm_dev.data_regs :
540			 tpm_dev.map_base + tpm_dev.data_regs,
541			 version[0], version[1],
542			 vendorid[0], vendorid[1],
543			 productid[0], productid[1], chipname);
544
545		chip = tpmm_chip_alloc(&dev->dev, &tpm_inf);
546		if (IS_ERR(chip)) {
547			rc = PTR_ERR(chip);
548			goto err_release_region;
549		}
550
551		rc = tpm_chip_register(chip);
552		if (rc)
553			goto err_release_region;
554
555		return 0;
556	} else {
557		rc = -ENODEV;
558		goto err_release_region;
559	}
560
561err_release_region:
562	if (tpm_dev.iotype == TPM_INF_IO_PORT) {
563		release_region(tpm_dev.data_regs, tpm_dev.data_size);
564		release_region(tpm_dev.config_port, tpm_dev.config_size);
565	} else {
566		iounmap(tpm_dev.mem_base);
567		release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
568	}
569
570err_last:
571	return rc;
572}
573
574static void tpm_inf_pnp_remove(struct pnp_dev *dev)
575{
576	struct tpm_chip *chip = pnp_get_drvdata(dev);
577
578	tpm_chip_unregister(chip);
579
580	if (tpm_dev.iotype == TPM_INF_IO_PORT) {
581		release_region(tpm_dev.data_regs, tpm_dev.data_size);
582		release_region(tpm_dev.config_port,
583			       tpm_dev.config_size);
584	} else {
585		iounmap(tpm_dev.mem_base);
586		release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
587	}
588}
589
590#ifdef CONFIG_PM_SLEEP
591static int tpm_inf_resume(struct device *dev)
592{
593	/* Re-configure TPM after suspending */
594	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
595	tpm_config_out(IOLIMH, TPM_INF_ADDR);
596	tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
597	tpm_config_out(IOLIML, TPM_INF_ADDR);
598	tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
599	/* activate register */
600	tpm_config_out(TPM_DAR, TPM_INF_ADDR);
601	tpm_config_out(0x01, TPM_INF_DATA);
602	tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
603	/* disable RESET, LP and IRQC */
604	tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
605	return tpm_pm_resume(dev);
606}
607#endif
608static SIMPLE_DEV_PM_OPS(tpm_inf_pm, tpm_pm_suspend, tpm_inf_resume);
609
610static struct pnp_driver tpm_inf_pnp_driver = {
611	.name = "tpm_inf_pnp",
612	.id_table = tpm_inf_pnp_tbl,
613	.probe = tpm_inf_pnp_probe,
614	.remove = tpm_inf_pnp_remove,
615	.driver = {
616		.pm = &tpm_inf_pm,
617	}
618};
619
620module_pnp_driver(tpm_inf_pnp_driver);
621
622MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
623MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
624MODULE_VERSION("1.9.2");
625MODULE_LICENSE("GPL");
v4.10.11
 
  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 <tpmdd@selhorst.net>
  8 * Sirrix AG - security technologies <tpmdd@sirrix.com> and
  9 * Applied Data Security Group, Ruhr-University Bochum, Germany
 10 * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-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/init.h>
 19#include <linux/pnp.h>
 20#include "tpm.h"
 21
 22/* Infineon specific definitions */
 23/* maximum number of WTX-packages */
 24#define	TPM_MAX_WTX_PACKAGES 	50
 25/* msleep-Time for WTX-packages */
 26#define	TPM_WTX_MSLEEP_TIME 	20
 27/* msleep-Time --> Interval to check status register */
 28#define	TPM_MSLEEP_TIME 	3
 29/* gives number of max. msleep()-calls before throwing timeout */
 30#define	TPM_MAX_TRIES		5000
 31#define	TPM_INFINEON_DEV_VEN_VALUE	0x15D1
 32
 33#define TPM_INF_IO_PORT		0x0
 34#define TPM_INF_IO_MEM		0x1
 35
 36#define TPM_INF_ADDR		0x0
 37#define TPM_INF_DATA		0x1
 38
 39struct tpm_inf_dev {
 40	int iotype;
 41
 42	void __iomem *mem_base;	/* MMIO ioremap'd addr */
 43	unsigned long map_base;	/* phys MMIO base */
 44	unsigned long map_size;	/* MMIO region size */
 45	unsigned int index_off;	/* index register offset */
 46
 47	unsigned int data_regs;	/* Data registers */
 48	unsigned int data_size;
 49
 50	unsigned int config_port;	/* IO Port config index reg */
 51	unsigned int config_size;
 52};
 53
 54static struct tpm_inf_dev tpm_dev;
 55
 56static inline void tpm_data_out(unsigned char data, unsigned char offset)
 57{
 58	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 59		outb(data, tpm_dev.data_regs + offset);
 60	else
 61		writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
 62}
 63
 64static inline unsigned char tpm_data_in(unsigned char offset)
 65{
 66	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 67		return inb(tpm_dev.data_regs + offset);
 68	else
 69		return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
 70}
 71
 72static inline void tpm_config_out(unsigned char data, unsigned char offset)
 73{
 74	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 75		outb(data, tpm_dev.config_port + offset);
 76	else
 77		writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
 78}
 79
 80static inline unsigned char tpm_config_in(unsigned char offset)
 81{
 82	if (tpm_dev.iotype == TPM_INF_IO_PORT)
 83		return inb(tpm_dev.config_port + offset);
 84	else
 85		return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
 86}
 87
 88/* TPM header definitions */
 89enum infineon_tpm_header {
 90	TPM_VL_VER = 0x01,
 91	TPM_VL_CHANNEL_CONTROL = 0x07,
 92	TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
 93	TPM_VL_CHANNEL_TPM = 0x0B,
 94	TPM_VL_CONTROL = 0x00,
 95	TPM_INF_NAK = 0x15,
 96	TPM_CTRL_WTX = 0x10,
 97	TPM_CTRL_WTX_ABORT = 0x18,
 98	TPM_CTRL_WTX_ABORT_ACK = 0x18,
 99	TPM_CTRL_ERROR = 0x20,
100	TPM_CTRL_CHAININGACK = 0x40,
101	TPM_CTRL_CHAINING = 0x80,
102	TPM_CTRL_DATA = 0x04,
103	TPM_CTRL_DATA_CHA = 0x84,
104	TPM_CTRL_DATA_CHA_ACK = 0xC4
105};
106
107enum infineon_tpm_register {
108	WRFIFO = 0x00,
109	RDFIFO = 0x01,
110	STAT = 0x02,
111	CMD = 0x03
112};
113
114enum infineon_tpm_command_bits {
115	CMD_DIS = 0x00,
116	CMD_LP = 0x01,
117	CMD_RES = 0x02,
118	CMD_IRQC = 0x06
119};
120
121enum infineon_tpm_status_bits {
122	STAT_XFE = 0x00,
123	STAT_LPA = 0x01,
124	STAT_FOK = 0x02,
125	STAT_TOK = 0x03,
126	STAT_IRQA = 0x06,
127	STAT_RDA = 0x07
128};
129
130/* some outgoing values */
131enum infineon_tpm_values {
132	CHIP_ID1 = 0x20,
133	CHIP_ID2 = 0x21,
134	TPM_DAR = 0x30,
135	RESET_LP_IRQC_DISABLE = 0x41,
136	ENABLE_REGISTER_PAIR = 0x55,
137	IOLIMH = 0x60,
138	IOLIML = 0x61,
139	DISABLE_REGISTER_PAIR = 0xAA,
140	IDVENL = 0xF1,
141	IDVENH = 0xF2,
142	IDPDL = 0xF3,
143	IDPDH = 0xF4
144};
145
146static int number_of_wtx;
147
148static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
149{
150	int status;
151	int check = 0;
152	int i;
153
154	if (clear_wrfifo) {
155		for (i = 0; i < 4096; i++) {
156			status = tpm_data_in(WRFIFO);
157			if (status == 0xff) {
158				if (check == 5)
159					break;
160				else
161					check++;
162			}
163		}
164	}
165	/* Note: The values which are currently in the FIFO of the TPM
166	   are thrown away since there is no usage for them. Usually,
167	   this has nothing to say, since the TPM will give its answer
168	   immediately or will be aborted anyway, so the data here is
169	   usually garbage and useless.
170	   We have to clean this, because the next communication with
171	   the TPM would be rubbish, if there is still some old data
172	   in the Read FIFO.
173	 */
174	i = 0;
175	do {
176		status = tpm_data_in(RDFIFO);
177		status = tpm_data_in(STAT);
178		i++;
179		if (i == TPM_MAX_TRIES)
180			return -EIO;
181	} while ((status & (1 << STAT_RDA)) != 0);
182	return 0;
183}
184
185static int wait(struct tpm_chip *chip, int wait_for_bit)
186{
187	int status;
188	int i;
189	for (i = 0; i < TPM_MAX_TRIES; i++) {
190		status = tpm_data_in(STAT);
191		/* check the status-register if wait_for_bit is set */
192		if (status & 1 << wait_for_bit)
193			break;
194		msleep(TPM_MSLEEP_TIME);
195	}
196	if (i == TPM_MAX_TRIES) {	/* timeout occurs */
197		if (wait_for_bit == STAT_XFE)
198			dev_err(&chip->dev, "Timeout in wait(STAT_XFE)\n");
199		if (wait_for_bit == STAT_RDA)
200			dev_err(&chip->dev, "Timeout in wait(STAT_RDA)\n");
201		return -EIO;
202	}
203	return 0;
204};
205
206static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
207{
208	wait(chip, STAT_XFE);
209	tpm_data_out(sendbyte, WRFIFO);
210}
211
212    /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
213       calculation time, it sends a WTX-package, which has to be acknowledged
214       or aborted. This usually occurs if you are hammering the TPM with key
215       creation. Set the maximum number of WTX-packages in the definitions
216       above, if the number is reached, the waiting-time will be denied
217       and the TPM command has to be resend.
218     */
219
220static void tpm_wtx(struct tpm_chip *chip)
221{
222	number_of_wtx++;
223	dev_info(&chip->dev, "Granting WTX (%02d / %02d)\n",
224		 number_of_wtx, TPM_MAX_WTX_PACKAGES);
225	wait_and_send(chip, TPM_VL_VER);
226	wait_and_send(chip, TPM_CTRL_WTX);
227	wait_and_send(chip, 0x00);
228	wait_and_send(chip, 0x00);
229	msleep(TPM_WTX_MSLEEP_TIME);
230}
231
232static void tpm_wtx_abort(struct tpm_chip *chip)
233{
234	dev_info(&chip->dev, "Aborting WTX\n");
235	wait_and_send(chip, TPM_VL_VER);
236	wait_and_send(chip, TPM_CTRL_WTX_ABORT);
237	wait_and_send(chip, 0x00);
238	wait_and_send(chip, 0x00);
239	number_of_wtx = 0;
240	msleep(TPM_WTX_MSLEEP_TIME);
241}
242
243static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
244{
245	int i;
246	int ret;
247	u32 size = 0;
248	number_of_wtx = 0;
249
250recv_begin:
251	/* start receiving header */
252	for (i = 0; i < 4; i++) {
253		ret = wait(chip, STAT_RDA);
254		if (ret)
255			return -EIO;
256		buf[i] = tpm_data_in(RDFIFO);
257	}
258
259	if (buf[0] != TPM_VL_VER) {
260		dev_err(&chip->dev,
261			"Wrong transport protocol implementation!\n");
262		return -EIO;
263	}
264
265	if (buf[1] == TPM_CTRL_DATA) {
266		/* size of the data received */
267		size = ((buf[2] << 8) | buf[3]);
268
269		for (i = 0; i < size; i++) {
270			wait(chip, STAT_RDA);
271			buf[i] = tpm_data_in(RDFIFO);
272		}
273
274		if ((size == 0x6D00) && (buf[1] == 0x80)) {
275			dev_err(&chip->dev, "Error handling on vendor layer!\n");
276			return -EIO;
277		}
278
279		for (i = 0; i < size; i++)
280			buf[i] = buf[i + 6];
281
282		size = size - 6;
283		return size;
284	}
285
286	if (buf[1] == TPM_CTRL_WTX) {
287		dev_info(&chip->dev, "WTX-package received\n");
288		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
289			tpm_wtx(chip);
290			goto recv_begin;
291		} else {
292			tpm_wtx_abort(chip);
293			goto recv_begin;
294		}
295	}
296
297	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
298		dev_info(&chip->dev, "WTX-abort acknowledged\n");
299		return size;
300	}
301
302	if (buf[1] == TPM_CTRL_ERROR) {
303		dev_err(&chip->dev, "ERROR-package received:\n");
304		if (buf[4] == TPM_INF_NAK)
305			dev_err(&chip->dev,
306				"-> Negative acknowledgement"
307				" - retransmit command!\n");
308		return -EIO;
309	}
310	return -EIO;
311}
312
313static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
314{
315	int i;
316	int ret;
317	u8 count_high, count_low, count_4, count_3, count_2, count_1;
318
319	/* Disabling Reset, LP and IRQC */
320	tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
321
322	ret = empty_fifo(chip, 1);
323	if (ret) {
324		dev_err(&chip->dev, "Timeout while clearing FIFO\n");
325		return -EIO;
326	}
327
328	ret = wait(chip, STAT_XFE);
329	if (ret)
330		return -EIO;
331
332	count_4 = (count & 0xff000000) >> 24;
333	count_3 = (count & 0x00ff0000) >> 16;
334	count_2 = (count & 0x0000ff00) >> 8;
335	count_1 = (count & 0x000000ff);
336	count_high = ((count + 6) & 0xffffff00) >> 8;
337	count_low = ((count + 6) & 0x000000ff);
338
339	/* Sending Header */
340	wait_and_send(chip, TPM_VL_VER);
341	wait_and_send(chip, TPM_CTRL_DATA);
342	wait_and_send(chip, count_high);
343	wait_and_send(chip, count_low);
344
345	/* Sending Data Header */
346	wait_and_send(chip, TPM_VL_VER);
347	wait_and_send(chip, TPM_VL_CHANNEL_TPM);
348	wait_and_send(chip, count_4);
349	wait_and_send(chip, count_3);
350	wait_and_send(chip, count_2);
351	wait_and_send(chip, count_1);
352
353	/* Sending Data */
354	for (i = 0; i < count; i++) {
355		wait_and_send(chip, buf[i]);
356	}
357	return count;
358}
359
360static void tpm_inf_cancel(struct tpm_chip *chip)
361{
362	/*
363	   Since we are using the legacy mode to communicate
364	   with the TPM, we have no cancel functions, but have
365	   a workaround for interrupting the TPM through WTX.
366	 */
367}
368
369static u8 tpm_inf_status(struct tpm_chip *chip)
370{
371	return tpm_data_in(STAT);
372}
373
374static const struct tpm_class_ops tpm_inf = {
375	.recv = tpm_inf_recv,
376	.send = tpm_inf_send,
377	.cancel = tpm_inf_cancel,
378	.status = tpm_inf_status,
379	.req_complete_mask = 0,
380	.req_complete_val = 0,
381};
382
383static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
384	/* Infineon TPMs */
385	{"IFX0101", 0},
386	{"IFX0102", 0},
387	{"", 0}
388};
389
390MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
391
392static int tpm_inf_pnp_probe(struct pnp_dev *dev,
393				       const struct pnp_device_id *dev_id)
394{
395	int rc = 0;
396	u8 iol, ioh;
397	int vendorid[2];
398	int version[2];
399	int productid[2];
400	char chipname[20];
401	struct tpm_chip *chip;
402
403	/* read IO-ports through PnP */
404	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
405	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
406
407		tpm_dev.iotype = TPM_INF_IO_PORT;
408
409		tpm_dev.config_port = pnp_port_start(dev, 0);
410		tpm_dev.config_size = pnp_port_len(dev, 0);
411		tpm_dev.data_regs = pnp_port_start(dev, 1);
412		tpm_dev.data_size = pnp_port_len(dev, 1);
413		if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
414			rc = -EINVAL;
415			goto err_last;
416		}
417		dev_info(&dev->dev, "Found %s with ID %s\n",
418			 dev->name, dev_id->id);
419		if (!((tpm_dev.data_regs >> 8) & 0xff)) {
420			rc = -EINVAL;
421			goto err_last;
422		}
423		/* publish my base address and request region */
424		if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
425				   "tpm_infineon0") == NULL) {
426			rc = -EINVAL;
427			goto err_last;
428		}
429		if (request_region(tpm_dev.config_port, tpm_dev.config_size,
430				   "tpm_infineon0") == NULL) {
431			release_region(tpm_dev.data_regs, tpm_dev.data_size);
432			rc = -EINVAL;
433			goto err_last;
434		}
435	} else if (pnp_mem_valid(dev, 0) &&
436		   !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
437
438		tpm_dev.iotype = TPM_INF_IO_MEM;
439
440		tpm_dev.map_base = pnp_mem_start(dev, 0);
441		tpm_dev.map_size = pnp_mem_len(dev, 0);
442
443		dev_info(&dev->dev, "Found %s with ID %s\n",
444			 dev->name, dev_id->id);
445
446		/* publish my base address and request region */
447		if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
448				       "tpm_infineon0") == NULL) {
449			rc = -EINVAL;
450			goto err_last;
451		}
452
453		tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
454		if (tpm_dev.mem_base == NULL) {
455			release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
456			rc = -EINVAL;
457			goto err_last;
458		}
459
460		/*
461		 * The only known MMIO based Infineon TPM system provides
462		 * a single large mem region with the device config
463		 * registers at the default TPM_ADDR.  The data registers
464		 * seem like they could be placed anywhere within the MMIO
465		 * region, but lets just put them at zero offset.
466		 */
467		tpm_dev.index_off = TPM_ADDR;
468		tpm_dev.data_regs = 0x0;
469	} else {
470		rc = -EINVAL;
471		goto err_last;
472	}
473
474	/* query chip for its vendor, its version number a.s.o. */
475	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
476	tpm_config_out(IDVENL, TPM_INF_ADDR);
477	vendorid[1] = tpm_config_in(TPM_INF_DATA);
478	tpm_config_out(IDVENH, TPM_INF_ADDR);
479	vendorid[0] = tpm_config_in(TPM_INF_DATA);
480	tpm_config_out(IDPDL, TPM_INF_ADDR);
481	productid[1] = tpm_config_in(TPM_INF_DATA);
482	tpm_config_out(IDPDH, TPM_INF_ADDR);
483	productid[0] = tpm_config_in(TPM_INF_DATA);
484	tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
485	version[1] = tpm_config_in(TPM_INF_DATA);
486	tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
487	version[0] = tpm_config_in(TPM_INF_DATA);
488
489	switch ((productid[0] << 8) | productid[1]) {
490	case 6:
491		snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");
492		break;
493	case 11:
494		snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");
495		break;
496	default:
497		snprintf(chipname, sizeof(chipname), " (unknown chip)");
498		break;
499	}
500
501	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
502
503		/* configure TPM with IO-ports */
504		tpm_config_out(IOLIMH, TPM_INF_ADDR);
505		tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
506		tpm_config_out(IOLIML, TPM_INF_ADDR);
507		tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
508
509		/* control if IO-ports are set correctly */
510		tpm_config_out(IOLIMH, TPM_INF_ADDR);
511		ioh = tpm_config_in(TPM_INF_DATA);
512		tpm_config_out(IOLIML, TPM_INF_ADDR);
513		iol = tpm_config_in(TPM_INF_DATA);
514
515		if ((ioh << 8 | iol) != tpm_dev.data_regs) {
516			dev_err(&dev->dev,
517				"Could not set IO-data registers to 0x%x\n",
518				tpm_dev.data_regs);
519			rc = -EIO;
520			goto err_release_region;
521		}
522
523		/* activate register */
524		tpm_config_out(TPM_DAR, TPM_INF_ADDR);
525		tpm_config_out(0x01, TPM_INF_DATA);
526		tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
527
528		/* disable RESET, LP and IRQC */
529		tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
530
531		/* Finally, we're done, print some infos */
532		dev_info(&dev->dev, "TPM found: "
533			 "config base 0x%lx, "
534			 "data base 0x%lx, "
535			 "chip version 0x%02x%02x, "
536			 "vendor id 0x%x%x (Infineon), "
537			 "product id 0x%02x%02x"
538			 "%s\n",
539			 tpm_dev.iotype == TPM_INF_IO_PORT ?
540			 tpm_dev.config_port :
541			 tpm_dev.map_base + tpm_dev.index_off,
542			 tpm_dev.iotype == TPM_INF_IO_PORT ?
543			 tpm_dev.data_regs :
544			 tpm_dev.map_base + tpm_dev.data_regs,
545			 version[0], version[1],
546			 vendorid[0], vendorid[1],
547			 productid[0], productid[1], chipname);
548
549		chip = tpmm_chip_alloc(&dev->dev, &tpm_inf);
550		if (IS_ERR(chip)) {
551			rc = PTR_ERR(chip);
552			goto err_release_region;
553		}
554
555		rc = tpm_chip_register(chip);
556		if (rc)
557			goto err_release_region;
558
559		return 0;
560	} else {
561		rc = -ENODEV;
562		goto err_release_region;
563	}
564
565err_release_region:
566	if (tpm_dev.iotype == TPM_INF_IO_PORT) {
567		release_region(tpm_dev.data_regs, tpm_dev.data_size);
568		release_region(tpm_dev.config_port, tpm_dev.config_size);
569	} else {
570		iounmap(tpm_dev.mem_base);
571		release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
572	}
573
574err_last:
575	return rc;
576}
577
578static void tpm_inf_pnp_remove(struct pnp_dev *dev)
579{
580	struct tpm_chip *chip = pnp_get_drvdata(dev);
581
582	tpm_chip_unregister(chip);
583
584	if (tpm_dev.iotype == TPM_INF_IO_PORT) {
585		release_region(tpm_dev.data_regs, tpm_dev.data_size);
586		release_region(tpm_dev.config_port,
587			       tpm_dev.config_size);
588	} else {
589		iounmap(tpm_dev.mem_base);
590		release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
591	}
592}
593
594#ifdef CONFIG_PM_SLEEP
595static int tpm_inf_resume(struct device *dev)
596{
597	/* Re-configure TPM after suspending */
598	tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
599	tpm_config_out(IOLIMH, TPM_INF_ADDR);
600	tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
601	tpm_config_out(IOLIML, TPM_INF_ADDR);
602	tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
603	/* activate register */
604	tpm_config_out(TPM_DAR, TPM_INF_ADDR);
605	tpm_config_out(0x01, TPM_INF_DATA);
606	tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
607	/* disable RESET, LP and IRQC */
608	tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
609	return tpm_pm_resume(dev);
610}
611#endif
612static SIMPLE_DEV_PM_OPS(tpm_inf_pm, tpm_pm_suspend, tpm_inf_resume);
613
614static struct pnp_driver tpm_inf_pnp_driver = {
615	.name = "tpm_inf_pnp",
616	.id_table = tpm_inf_pnp_tbl,
617	.probe = tpm_inf_pnp_probe,
618	.remove = tpm_inf_pnp_remove,
619	.driver = {
620		.pm = &tpm_inf_pm,
621	}
622};
623
624module_pnp_driver(tpm_inf_pnp_driver);
625
626MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
627MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
628MODULE_VERSION("1.9.2");
629MODULE_LICENSE("GPL");