0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/init.h>
0015 #include <linux/pnp.h>
0016 #include "tpm.h"
0017
0018
0019
0020 #define TPM_MAX_WTX_PACKAGES 50
0021
0022 #define TPM_WTX_MSLEEP_TIME 20
0023
0024 #define TPM_MSLEEP_TIME 3
0025
0026 #define TPM_MAX_TRIES 5000
0027 #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
0028
0029 #define TPM_INF_IO_PORT 0x0
0030 #define TPM_INF_IO_MEM 0x1
0031
0032 #define TPM_INF_ADDR 0x0
0033 #define TPM_INF_DATA 0x1
0034
0035 struct tpm_inf_dev {
0036 int iotype;
0037
0038 void __iomem *mem_base;
0039 unsigned long map_base;
0040 unsigned long map_size;
0041 unsigned int index_off;
0042
0043 unsigned int data_regs;
0044 unsigned int data_size;
0045
0046 unsigned int config_port;
0047 unsigned int config_size;
0048 };
0049
0050 static struct tpm_inf_dev tpm_dev;
0051
0052 static inline void tpm_data_out(unsigned char data, unsigned char offset)
0053 {
0054 if (tpm_dev.iotype == TPM_INF_IO_PORT)
0055 outb(data, tpm_dev.data_regs + offset);
0056 else
0057 writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
0058 }
0059
0060 static inline unsigned char tpm_data_in(unsigned char offset)
0061 {
0062 if (tpm_dev.iotype == TPM_INF_IO_PORT)
0063 return inb(tpm_dev.data_regs + offset);
0064 else
0065 return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
0066 }
0067
0068 static inline void tpm_config_out(unsigned char data, unsigned char offset)
0069 {
0070 if (tpm_dev.iotype == TPM_INF_IO_PORT)
0071 outb(data, tpm_dev.config_port + offset);
0072 else
0073 writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
0074 }
0075
0076 static inline unsigned char tpm_config_in(unsigned char offset)
0077 {
0078 if (tpm_dev.iotype == TPM_INF_IO_PORT)
0079 return inb(tpm_dev.config_port + offset);
0080 else
0081 return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
0082 }
0083
0084
0085 enum infineon_tpm_header {
0086 TPM_VL_VER = 0x01,
0087 TPM_VL_CHANNEL_CONTROL = 0x07,
0088 TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
0089 TPM_VL_CHANNEL_TPM = 0x0B,
0090 TPM_VL_CONTROL = 0x00,
0091 TPM_INF_NAK = 0x15,
0092 TPM_CTRL_WTX = 0x10,
0093 TPM_CTRL_WTX_ABORT = 0x18,
0094 TPM_CTRL_WTX_ABORT_ACK = 0x18,
0095 TPM_CTRL_ERROR = 0x20,
0096 TPM_CTRL_CHAININGACK = 0x40,
0097 TPM_CTRL_CHAINING = 0x80,
0098 TPM_CTRL_DATA = 0x04,
0099 TPM_CTRL_DATA_CHA = 0x84,
0100 TPM_CTRL_DATA_CHA_ACK = 0xC4
0101 };
0102
0103 enum infineon_tpm_register {
0104 WRFIFO = 0x00,
0105 RDFIFO = 0x01,
0106 STAT = 0x02,
0107 CMD = 0x03
0108 };
0109
0110 enum infineon_tpm_command_bits {
0111 CMD_DIS = 0x00,
0112 CMD_LP = 0x01,
0113 CMD_RES = 0x02,
0114 CMD_IRQC = 0x06
0115 };
0116
0117 enum infineon_tpm_status_bits {
0118 STAT_XFE = 0x00,
0119 STAT_LPA = 0x01,
0120 STAT_FOK = 0x02,
0121 STAT_TOK = 0x03,
0122 STAT_IRQA = 0x06,
0123 STAT_RDA = 0x07
0124 };
0125
0126
0127 enum infineon_tpm_values {
0128 CHIP_ID1 = 0x20,
0129 CHIP_ID2 = 0x21,
0130 TPM_DAR = 0x30,
0131 RESET_LP_IRQC_DISABLE = 0x41,
0132 ENABLE_REGISTER_PAIR = 0x55,
0133 IOLIMH = 0x60,
0134 IOLIML = 0x61,
0135 DISABLE_REGISTER_PAIR = 0xAA,
0136 IDVENL = 0xF1,
0137 IDVENH = 0xF2,
0138 IDPDL = 0xF3,
0139 IDPDH = 0xF4
0140 };
0141
0142 static int number_of_wtx;
0143
0144 static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
0145 {
0146 int status;
0147 int check = 0;
0148 int i;
0149
0150 if (clear_wrfifo) {
0151 for (i = 0; i < 4096; i++) {
0152 status = tpm_data_in(WRFIFO);
0153 if (status == 0xff) {
0154 if (check == 5)
0155 break;
0156 else
0157 check++;
0158 }
0159 }
0160 }
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170 i = 0;
0171 do {
0172 status = tpm_data_in(RDFIFO);
0173 status = tpm_data_in(STAT);
0174 i++;
0175 if (i == TPM_MAX_TRIES)
0176 return -EIO;
0177 } while ((status & (1 << STAT_RDA)) != 0);
0178 return 0;
0179 }
0180
0181 static int wait(struct tpm_chip *chip, int wait_for_bit)
0182 {
0183 int status;
0184 int i;
0185 for (i = 0; i < TPM_MAX_TRIES; i++) {
0186 status = tpm_data_in(STAT);
0187
0188 if (status & 1 << wait_for_bit)
0189 break;
0190 tpm_msleep(TPM_MSLEEP_TIME);
0191 }
0192 if (i == TPM_MAX_TRIES) {
0193 if (wait_for_bit == STAT_XFE)
0194 dev_err(&chip->dev, "Timeout in wait(STAT_XFE)\n");
0195 if (wait_for_bit == STAT_RDA)
0196 dev_err(&chip->dev, "Timeout in wait(STAT_RDA)\n");
0197 return -EIO;
0198 }
0199 return 0;
0200 };
0201
0202 static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
0203 {
0204 wait(chip, STAT_XFE);
0205 tpm_data_out(sendbyte, WRFIFO);
0206 }
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216 static void tpm_wtx(struct tpm_chip *chip)
0217 {
0218 number_of_wtx++;
0219 dev_info(&chip->dev, "Granting WTX (%02d / %02d)\n",
0220 number_of_wtx, TPM_MAX_WTX_PACKAGES);
0221 wait_and_send(chip, TPM_VL_VER);
0222 wait_and_send(chip, TPM_CTRL_WTX);
0223 wait_and_send(chip, 0x00);
0224 wait_and_send(chip, 0x00);
0225 tpm_msleep(TPM_WTX_MSLEEP_TIME);
0226 }
0227
0228 static void tpm_wtx_abort(struct tpm_chip *chip)
0229 {
0230 dev_info(&chip->dev, "Aborting WTX\n");
0231 wait_and_send(chip, TPM_VL_VER);
0232 wait_and_send(chip, TPM_CTRL_WTX_ABORT);
0233 wait_and_send(chip, 0x00);
0234 wait_and_send(chip, 0x00);
0235 number_of_wtx = 0;
0236 tpm_msleep(TPM_WTX_MSLEEP_TIME);
0237 }
0238
0239 static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
0240 {
0241 int i;
0242 int ret;
0243 u32 size = 0;
0244 number_of_wtx = 0;
0245
0246 recv_begin:
0247
0248 for (i = 0; i < 4; i++) {
0249 ret = wait(chip, STAT_RDA);
0250 if (ret)
0251 return -EIO;
0252 buf[i] = tpm_data_in(RDFIFO);
0253 }
0254
0255 if (buf[0] != TPM_VL_VER) {
0256 dev_err(&chip->dev,
0257 "Wrong transport protocol implementation!\n");
0258 return -EIO;
0259 }
0260
0261 if (buf[1] == TPM_CTRL_DATA) {
0262
0263 size = ((buf[2] << 8) | buf[3]);
0264
0265 for (i = 0; i < size; i++) {
0266 wait(chip, STAT_RDA);
0267 buf[i] = tpm_data_in(RDFIFO);
0268 }
0269
0270 if ((size == 0x6D00) && (buf[1] == 0x80)) {
0271 dev_err(&chip->dev, "Error handling on vendor layer!\n");
0272 return -EIO;
0273 }
0274
0275 for (i = 0; i < size; i++)
0276 buf[i] = buf[i + 6];
0277
0278 size = size - 6;
0279 return size;
0280 }
0281
0282 if (buf[1] == TPM_CTRL_WTX) {
0283 dev_info(&chip->dev, "WTX-package received\n");
0284 if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
0285 tpm_wtx(chip);
0286 goto recv_begin;
0287 } else {
0288 tpm_wtx_abort(chip);
0289 goto recv_begin;
0290 }
0291 }
0292
0293 if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
0294 dev_info(&chip->dev, "WTX-abort acknowledged\n");
0295 return size;
0296 }
0297
0298 if (buf[1] == TPM_CTRL_ERROR) {
0299 dev_err(&chip->dev, "ERROR-package received:\n");
0300 if (buf[4] == TPM_INF_NAK)
0301 dev_err(&chip->dev,
0302 "-> Negative acknowledgement"
0303 " - retransmit command!\n");
0304 return -EIO;
0305 }
0306 return -EIO;
0307 }
0308
0309 static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
0310 {
0311 int i;
0312 int ret;
0313 u8 count_high, count_low, count_4, count_3, count_2, count_1;
0314
0315
0316 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
0317
0318 ret = empty_fifo(chip, 1);
0319 if (ret) {
0320 dev_err(&chip->dev, "Timeout while clearing FIFO\n");
0321 return -EIO;
0322 }
0323
0324 ret = wait(chip, STAT_XFE);
0325 if (ret)
0326 return -EIO;
0327
0328 count_4 = (count & 0xff000000) >> 24;
0329 count_3 = (count & 0x00ff0000) >> 16;
0330 count_2 = (count & 0x0000ff00) >> 8;
0331 count_1 = (count & 0x000000ff);
0332 count_high = ((count + 6) & 0xffffff00) >> 8;
0333 count_low = ((count + 6) & 0x000000ff);
0334
0335
0336 wait_and_send(chip, TPM_VL_VER);
0337 wait_and_send(chip, TPM_CTRL_DATA);
0338 wait_and_send(chip, count_high);
0339 wait_and_send(chip, count_low);
0340
0341
0342 wait_and_send(chip, TPM_VL_VER);
0343 wait_and_send(chip, TPM_VL_CHANNEL_TPM);
0344 wait_and_send(chip, count_4);
0345 wait_and_send(chip, count_3);
0346 wait_and_send(chip, count_2);
0347 wait_and_send(chip, count_1);
0348
0349
0350 for (i = 0; i < count; i++) {
0351 wait_and_send(chip, buf[i]);
0352 }
0353 return 0;
0354 }
0355
0356 static void tpm_inf_cancel(struct tpm_chip *chip)
0357 {
0358
0359
0360
0361
0362
0363 }
0364
0365 static u8 tpm_inf_status(struct tpm_chip *chip)
0366 {
0367 return tpm_data_in(STAT);
0368 }
0369
0370 static const struct tpm_class_ops tpm_inf = {
0371 .recv = tpm_inf_recv,
0372 .send = tpm_inf_send,
0373 .cancel = tpm_inf_cancel,
0374 .status = tpm_inf_status,
0375 .req_complete_mask = 0,
0376 .req_complete_val = 0,
0377 };
0378
0379 static const struct pnp_device_id tpm_inf_pnp_tbl[] = {
0380
0381 {"IFX0101", 0},
0382 {"IFX0102", 0},
0383 {"", 0}
0384 };
0385
0386 MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl);
0387
0388 static int tpm_inf_pnp_probe(struct pnp_dev *dev,
0389 const struct pnp_device_id *dev_id)
0390 {
0391 int rc = 0;
0392 u8 iol, ioh;
0393 int vendorid[2];
0394 int version[2];
0395 int productid[2];
0396 const char *chipname;
0397 struct tpm_chip *chip;
0398
0399
0400 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
0401 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
0402
0403 tpm_dev.iotype = TPM_INF_IO_PORT;
0404
0405 tpm_dev.config_port = pnp_port_start(dev, 0);
0406 tpm_dev.config_size = pnp_port_len(dev, 0);
0407 tpm_dev.data_regs = pnp_port_start(dev, 1);
0408 tpm_dev.data_size = pnp_port_len(dev, 1);
0409 if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
0410 rc = -EINVAL;
0411 goto err_last;
0412 }
0413 dev_info(&dev->dev, "Found %s with ID %s\n",
0414 dev->name, dev_id->id);
0415 if (!((tpm_dev.data_regs >> 8) & 0xff)) {
0416 rc = -EINVAL;
0417 goto err_last;
0418 }
0419
0420 if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
0421 "tpm_infineon0") == NULL) {
0422 rc = -EINVAL;
0423 goto err_last;
0424 }
0425 if (request_region(tpm_dev.config_port, tpm_dev.config_size,
0426 "tpm_infineon0") == NULL) {
0427 release_region(tpm_dev.data_regs, tpm_dev.data_size);
0428 rc = -EINVAL;
0429 goto err_last;
0430 }
0431 } else if (pnp_mem_valid(dev, 0) &&
0432 !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
0433
0434 tpm_dev.iotype = TPM_INF_IO_MEM;
0435
0436 tpm_dev.map_base = pnp_mem_start(dev, 0);
0437 tpm_dev.map_size = pnp_mem_len(dev, 0);
0438
0439 dev_info(&dev->dev, "Found %s with ID %s\n",
0440 dev->name, dev_id->id);
0441
0442
0443 if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
0444 "tpm_infineon0") == NULL) {
0445 rc = -EINVAL;
0446 goto err_last;
0447 }
0448
0449 tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
0450 if (tpm_dev.mem_base == NULL) {
0451 release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
0452 rc = -EINVAL;
0453 goto err_last;
0454 }
0455
0456
0457
0458
0459
0460
0461
0462
0463 tpm_dev.index_off = TPM_ADDR;
0464 tpm_dev.data_regs = 0x0;
0465 } else {
0466 rc = -EINVAL;
0467 goto err_last;
0468 }
0469
0470
0471 tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
0472 tpm_config_out(IDVENL, TPM_INF_ADDR);
0473 vendorid[1] = tpm_config_in(TPM_INF_DATA);
0474 tpm_config_out(IDVENH, TPM_INF_ADDR);
0475 vendorid[0] = tpm_config_in(TPM_INF_DATA);
0476 tpm_config_out(IDPDL, TPM_INF_ADDR);
0477 productid[1] = tpm_config_in(TPM_INF_DATA);
0478 tpm_config_out(IDPDH, TPM_INF_ADDR);
0479 productid[0] = tpm_config_in(TPM_INF_DATA);
0480 tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
0481 version[1] = tpm_config_in(TPM_INF_DATA);
0482 tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
0483 version[0] = tpm_config_in(TPM_INF_DATA);
0484
0485 switch ((productid[0] << 8) | productid[1]) {
0486 case 6:
0487 chipname = " (SLD 9630 TT 1.1)";
0488 break;
0489 case 11:
0490 chipname = " (SLB 9635 TT 1.2)";
0491 break;
0492 default:
0493 chipname = " (unknown chip)";
0494 break;
0495 }
0496
0497 if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
0498
0499
0500 tpm_config_out(IOLIMH, TPM_INF_ADDR);
0501 tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
0502 tpm_config_out(IOLIML, TPM_INF_ADDR);
0503 tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
0504
0505
0506 tpm_config_out(IOLIMH, TPM_INF_ADDR);
0507 ioh = tpm_config_in(TPM_INF_DATA);
0508 tpm_config_out(IOLIML, TPM_INF_ADDR);
0509 iol = tpm_config_in(TPM_INF_DATA);
0510
0511 if ((ioh << 8 | iol) != tpm_dev.data_regs) {
0512 dev_err(&dev->dev,
0513 "Could not set IO-data registers to 0x%x\n",
0514 tpm_dev.data_regs);
0515 rc = -EIO;
0516 goto err_release_region;
0517 }
0518
0519
0520 tpm_config_out(TPM_DAR, TPM_INF_ADDR);
0521 tpm_config_out(0x01, TPM_INF_DATA);
0522 tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
0523
0524
0525 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
0526
0527
0528 dev_info(&dev->dev, "TPM found: "
0529 "config base 0x%lx, "
0530 "data base 0x%lx, "
0531 "chip version 0x%02x%02x, "
0532 "vendor id 0x%x%x (Infineon), "
0533 "product id 0x%02x%02x"
0534 "%s\n",
0535 tpm_dev.iotype == TPM_INF_IO_PORT ?
0536 tpm_dev.config_port :
0537 tpm_dev.map_base + tpm_dev.index_off,
0538 tpm_dev.iotype == TPM_INF_IO_PORT ?
0539 tpm_dev.data_regs :
0540 tpm_dev.map_base + tpm_dev.data_regs,
0541 version[0], version[1],
0542 vendorid[0], vendorid[1],
0543 productid[0], productid[1], chipname);
0544
0545 chip = tpmm_chip_alloc(&dev->dev, &tpm_inf);
0546 if (IS_ERR(chip)) {
0547 rc = PTR_ERR(chip);
0548 goto err_release_region;
0549 }
0550
0551 rc = tpm_chip_register(chip);
0552 if (rc)
0553 goto err_release_region;
0554
0555 return 0;
0556 } else {
0557 rc = -ENODEV;
0558 goto err_release_region;
0559 }
0560
0561 err_release_region:
0562 if (tpm_dev.iotype == TPM_INF_IO_PORT) {
0563 release_region(tpm_dev.data_regs, tpm_dev.data_size);
0564 release_region(tpm_dev.config_port, tpm_dev.config_size);
0565 } else {
0566 iounmap(tpm_dev.mem_base);
0567 release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
0568 }
0569
0570 err_last:
0571 return rc;
0572 }
0573
0574 static void tpm_inf_pnp_remove(struct pnp_dev *dev)
0575 {
0576 struct tpm_chip *chip = pnp_get_drvdata(dev);
0577
0578 tpm_chip_unregister(chip);
0579
0580 if (tpm_dev.iotype == TPM_INF_IO_PORT) {
0581 release_region(tpm_dev.data_regs, tpm_dev.data_size);
0582 release_region(tpm_dev.config_port,
0583 tpm_dev.config_size);
0584 } else {
0585 iounmap(tpm_dev.mem_base);
0586 release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
0587 }
0588 }
0589
0590 #ifdef CONFIG_PM_SLEEP
0591 static int tpm_inf_resume(struct device *dev)
0592 {
0593
0594 tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
0595 tpm_config_out(IOLIMH, TPM_INF_ADDR);
0596 tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
0597 tpm_config_out(IOLIML, TPM_INF_ADDR);
0598 tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
0599
0600 tpm_config_out(TPM_DAR, TPM_INF_ADDR);
0601 tpm_config_out(0x01, TPM_INF_DATA);
0602 tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
0603
0604 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
0605 return tpm_pm_resume(dev);
0606 }
0607 #endif
0608 static SIMPLE_DEV_PM_OPS(tpm_inf_pm, tpm_pm_suspend, tpm_inf_resume);
0609
0610 static struct pnp_driver tpm_inf_pnp_driver = {
0611 .name = "tpm_inf_pnp",
0612 .id_table = tpm_inf_pnp_tbl,
0613 .probe = tpm_inf_pnp_probe,
0614 .remove = tpm_inf_pnp_remove,
0615 .driver = {
0616 .pm = &tpm_inf_pm,
0617 }
0618 };
0619
0620 module_pnp_driver(tpm_inf_pnp_driver);
0621
0622 MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
0623 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
0624 MODULE_VERSION("1.9.2");
0625 MODULE_LICENSE("GPL");