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