/* * TPM command can be up to 2048 byte, A TPM response can be up to * 1024 byte. * Between command and response, there are latency byte (up to 15 * usually on st33zp24 2 are enough). * * Overall when sending a command and expecting an answer we need if * worst case: * 2048 (for the TPM command) + 1024 (for the TPM answer). We need * some latency byte before the answer is available (max 15). * We have 2048 + 1024 + 15.
*/ #define ST33ZP24_SPI_BUFFER_SIZE (ST33ZP24_BUFSIZE + (ST33ZP24_BUFSIZE / 2) +\
MAX_SPI_LATENCY)
staticint st33zp24_status_to_errno(u8 code)
{ switch (code) { case ST33ZP24_OK: return 0; case ST33ZP24_UNDEFINED_ERR: case ST33ZP24_BADLOCALITY: case ST33ZP24_TISREGISTER_UNKNOWN: case ST33ZP24_LOCALITY_NOT_ACTIVATED: case ST33ZP24_HASH_END_BEFORE_HASH_START: case ST33ZP24_BAD_COMMAND_ORDER: case ST33ZP24_UNEXPECTED_READ_FIFO: case ST33ZP24_UNEXPECTED_WRITE_FIFO: case ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END: return -EPROTO; case ST33ZP24_INCORECT_RECEIVED_LENGTH: case ST33ZP24_TPM_FIFO_OVERFLOW: return -EMSGSIZE; case ST33ZP24_DUMMY_BYTES: return -ENOSYS;
} return code;
}
/* * st33zp24_spi_send * Send byte to the TIS register according to the ST33ZP24 SPI protocol. * @param: phy_id, the phy description * @param: tpm_register, the tpm tis register where the data should be written * @param: tpm_data, the tpm_data to write inside the tpm_register * @param: tpm_size, The length of the data * @return: should be zero if success else a negative error code.
*/ staticint st33zp24_spi_send(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size)
{ int total_length = 0, ret = 0; struct st33zp24_spi_phy *phy = phy_id; struct spi_device *dev = phy->spi_device; struct spi_transfer spi_xfer = {
.tx_buf = phy->tx_buf,
.rx_buf = phy->rx_buf,
};
/* * st33zp24_spi_read8_recv * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. * @param: phy_id, the phy description * @param: tpm_register, the tpm tis register where the data should be read * @param: tpm_data, the TPM response * @param: tpm_size, tpm TPM response size to read. * @return: should be zero if success else a negative error code.
*/ staticint st33zp24_spi_read8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size)
{ int total_length = 0, ret; struct st33zp24_spi_phy *phy = phy_id; struct spi_device *dev = phy->spi_device; struct spi_transfer spi_xfer = {
.tx_buf = phy->tx_buf,
.rx_buf = phy->rx_buf,
};
/* header + status byte + size of the data + status byte */
ret = spi_sync_transfer(dev, &spi_xfer, 1); if (tpm_size > 0 && ret == 0) {
ret = phy->rx_buf[total_length + phy->latency - 1];
/* * st33zp24_spi_recv * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. * @param: phy_id, the phy description * @param: tpm_register, the tpm tis register where the data should be read * @param: tpm_data, the TPM response * @param: tpm_size, tpm TPM response size to read. * @return: number of byte read successfully: should be one if success.
*/ staticint st33zp24_spi_recv(void *phy_id, u8 tpm_register, u8 *tpm_data, int tpm_size)
{ int ret;
ret = st33zp24_spi_read8_reg(phy_id, tpm_register, tpm_data, tpm_size); if (!st33zp24_status_to_errno(ret)) return tpm_size; return ret;
} /* st33zp24_spi_recv() */
staticint st33zp24_spi_evaluate_latency(void *phy_id)
{ struct st33zp24_spi_phy *phy = phy_id; int latency = 1, status = 0;
u8 data = 0;
while (!status && latency < MAX_SPI_LATENCY) {
phy->latency = latency;
status = st33zp24_spi_read8_reg(phy_id, TPM_INTF_CAPABILITY,
&data, 1);
latency++;
} if (status < 0) return status; if (latency == MAX_SPI_LATENCY) return -ENODEV;
/* * st33zp24_spi_probe initialize the TPM device * @param: dev, the spi_device description (TPM SPI description). * @return: 0 in case of success. * or a negative value describing the error.
*/ staticint st33zp24_spi_probe(struct spi_device *dev)
{ struct st33zp24_spi_phy *phy;
phy = devm_kzalloc(&dev->dev, sizeof(struct st33zp24_spi_phy),
GFP_KERNEL); if (!phy) return -ENOMEM;
phy->spi_device = dev;
phy->latency = st33zp24_spi_evaluate_latency(phy); if (phy->latency <= 0) return -ENODEV;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.