This source file includes following definitions.
- tpm_data_out
- tpm_data_in
- tpm_config_out
- tpm_config_in
- empty_fifo
- wait
- wait_and_send
- tpm_wtx
- tpm_wtx_abort
- tpm_inf_recv
- tpm_inf_send
- tpm_inf_cancel
- tpm_inf_status
- tpm_inf_pnp_probe
- tpm_inf_pnp_remove
- tpm_inf_resume
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/init.h>
15 #include <linux/pnp.h>
16 #include "tpm.h"
17
18
19
20 #define TPM_MAX_WTX_PACKAGES 50
21
22 #define TPM_WTX_MSLEEP_TIME 20
23
24 #define TPM_MSLEEP_TIME 3
25
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
35 struct tpm_inf_dev {
36 int iotype;
37
38 void __iomem *mem_base;
39 unsigned long map_base;
40 unsigned long map_size;
41 unsigned int index_off;
42
43 unsigned int data_regs;
44 unsigned int data_size;
45
46 unsigned int config_port;
47 unsigned int config_size;
48 };
49
50 static struct tpm_inf_dev tpm_dev;
51
52 static 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
60 static 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
68 static 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
76 static 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
85 enum 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
103 enum infineon_tpm_register {
104 WRFIFO = 0x00,
105 RDFIFO = 0x01,
106 STAT = 0x02,
107 CMD = 0x03
108 };
109
110 enum infineon_tpm_command_bits {
111 CMD_DIS = 0x00,
112 CMD_LP = 0x01,
113 CMD_RES = 0x02,
114 CMD_IRQC = 0x06
115 };
116
117 enum 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
127 enum 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
142 static int number_of_wtx;
143
144 static 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
162
163
164
165
166
167
168
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
181 static 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
188 if (status & 1 << wait_for_bit)
189 break;
190 tpm_msleep(TPM_MSLEEP_TIME);
191 }
192 if (i == TPM_MAX_TRIES) {
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
202 static 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
209
210
211
212
213
214
215
216 static 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
228 static 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
239 static 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
246 recv_begin:
247
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
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
309 static 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
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
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
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
350 for (i = 0; i < count; i++) {
351 wait_and_send(chip, buf[i]);
352 }
353 return 0;
354 }
355
356 static void tpm_inf_cancel(struct tpm_chip *chip)
357 {
358
359
360
361
362
363 }
364
365 static u8 tpm_inf_status(struct tpm_chip *chip)
366 {
367 return tpm_data_in(STAT);
368 }
369
370 static 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
379 static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
380
381 {"IFX0101", 0},
382 {"IFX0102", 0},
383 {"", 0}
384 };
385
386 MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
387
388 static 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
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
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
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
458
459
460
461
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
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
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
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
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
525 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
526
527
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
561 err_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
570 err_last:
571 return rc;
572 }
573
574 static 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
591 static int tpm_inf_resume(struct device *dev)
592 {
593
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
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
604 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
605 return tpm_pm_resume(dev);
606 }
607 #endif
608 static SIMPLE_DEV_PM_OPS(tpm_inf_pm, tpm_pm_suspend, tpm_inf_resume);
609
610 static 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
620 module_pnp_driver(tpm_inf_pnp_driver);
621
622 MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
623 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
624 MODULE_VERSION("1.9.2");
625 MODULE_LICENSE("GPL");