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