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