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