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