420 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Microchip / Atmel ECC (I2C) driver.4 *5 * Copyright (c) 2017, Microchip Technology Inc.6 * Author: Tudor Ambarus7 */8 9#include <linux/bitrev.h>10#include <linux/crc16.h>11#include <linux/delay.h>12#include <linux/device.h>13#include <linux/err.h>14#include <linux/errno.h>15#include <linux/i2c.h>16#include <linux/init.h>17#include <linux/kernel.h>18#include <linux/module.h>19#include <linux/scatterlist.h>20#include <linux/slab.h>21#include <linux/workqueue.h>22#include "atmel-i2c.h"23 24static const struct {25 u8 value;26 const char *error_text;27} error_list[] = {28 { 0x01, "CheckMac or Verify miscompare" },29 { 0x03, "Parse Error" },30 { 0x05, "ECC Fault" },31 { 0x0F, "Execution Error" },32 { 0xEE, "Watchdog about to expire" },33 { 0xFF, "CRC or other communication error" },34};35 36/**37 * atmel_i2c_checksum() - Generate 16-bit CRC as required by ATMEL ECC.38 * CRC16 verification of the count, opcode, param1, param2 and data bytes.39 * The checksum is saved in little-endian format in the least significant40 * two bytes of the command. CRC polynomial is 0x8005 and the initial register41 * value should be zero.42 *43 * @cmd : structure used for communicating with the device.44 */45static void atmel_i2c_checksum(struct atmel_i2c_cmd *cmd)46{47 u8 *data = &cmd->count;48 size_t len = cmd->count - CRC_SIZE;49 __le16 *__crc16 = (__le16 *)(data + len);50 51 *__crc16 = cpu_to_le16(bitrev16(crc16(0, data, len)));52}53 54void atmel_i2c_init_read_config_cmd(struct atmel_i2c_cmd *cmd)55{56 cmd->word_addr = COMMAND;57 cmd->opcode = OPCODE_READ;58 /*59 * Read the word from Configuration zone that contains the lock bytes60 * (UserExtra, Selector, LockValue, LockConfig).61 */62 cmd->param1 = CONFIGURATION_ZONE;63 cmd->param2 = cpu_to_le16(DEVICE_LOCK_ADDR);64 cmd->count = READ_COUNT;65 66 atmel_i2c_checksum(cmd);67 68 cmd->msecs = MAX_EXEC_TIME_READ;69 cmd->rxsize = READ_RSP_SIZE;70}71EXPORT_SYMBOL(atmel_i2c_init_read_config_cmd);72 73int atmel_i2c_init_read_otp_cmd(struct atmel_i2c_cmd *cmd, u16 addr)74{75 if (addr < 0 || addr > OTP_ZONE_SIZE)76 return -1;77 78 cmd->word_addr = COMMAND;79 cmd->opcode = OPCODE_READ;80 /*81 * Read the word from OTP zone that may contain e.g. serial82 * numbers or similar if persistently pre-initialized and locked83 */84 cmd->param1 = OTP_ZONE;85 cmd->param2 = cpu_to_le16(addr);86 cmd->count = READ_COUNT;87 88 atmel_i2c_checksum(cmd);89 90 cmd->msecs = MAX_EXEC_TIME_READ;91 cmd->rxsize = READ_RSP_SIZE;92 93 return 0;94}95EXPORT_SYMBOL(atmel_i2c_init_read_otp_cmd);96 97void atmel_i2c_init_random_cmd(struct atmel_i2c_cmd *cmd)98{99 cmd->word_addr = COMMAND;100 cmd->opcode = OPCODE_RANDOM;101 cmd->param1 = 0;102 cmd->param2 = 0;103 cmd->count = RANDOM_COUNT;104 105 atmel_i2c_checksum(cmd);106 107 cmd->msecs = MAX_EXEC_TIME_RANDOM;108 cmd->rxsize = RANDOM_RSP_SIZE;109}110EXPORT_SYMBOL(atmel_i2c_init_random_cmd);111 112void atmel_i2c_init_genkey_cmd(struct atmel_i2c_cmd *cmd, u16 keyid)113{114 cmd->word_addr = COMMAND;115 cmd->count = GENKEY_COUNT;116 cmd->opcode = OPCODE_GENKEY;117 cmd->param1 = GENKEY_MODE_PRIVATE;118 /* a random private key will be generated and stored in slot keyID */119 cmd->param2 = cpu_to_le16(keyid);120 121 atmel_i2c_checksum(cmd);122 123 cmd->msecs = MAX_EXEC_TIME_GENKEY;124 cmd->rxsize = GENKEY_RSP_SIZE;125}126EXPORT_SYMBOL(atmel_i2c_init_genkey_cmd);127 128int atmel_i2c_init_ecdh_cmd(struct atmel_i2c_cmd *cmd,129 struct scatterlist *pubkey)130{131 size_t copied;132 133 cmd->word_addr = COMMAND;134 cmd->count = ECDH_COUNT;135 cmd->opcode = OPCODE_ECDH;136 cmd->param1 = ECDH_PREFIX_MODE;137 /* private key slot */138 cmd->param2 = cpu_to_le16(DATA_SLOT_2);139 140 /*141 * The device only supports NIST P256 ECC keys. The public key size will142 * always be the same. Use a macro for the key size to avoid unnecessary143 * computations.144 */145 copied = sg_copy_to_buffer(pubkey,146 sg_nents_for_len(pubkey,147 ATMEL_ECC_PUBKEY_SIZE),148 cmd->data, ATMEL_ECC_PUBKEY_SIZE);149 if (copied != ATMEL_ECC_PUBKEY_SIZE)150 return -EINVAL;151 152 atmel_i2c_checksum(cmd);153 154 cmd->msecs = MAX_EXEC_TIME_ECDH;155 cmd->rxsize = ECDH_RSP_SIZE;156 157 return 0;158}159EXPORT_SYMBOL(atmel_i2c_init_ecdh_cmd);160 161/*162 * After wake and after execution of a command, there will be error, status, or163 * result bytes in the device's output register that can be retrieved by the164 * system. When the length of that group is four bytes, the codes returned are165 * detailed in error_list.166 */167static int atmel_i2c_status(struct device *dev, u8 *status)168{169 size_t err_list_len = ARRAY_SIZE(error_list);170 int i;171 u8 err_id = status[1];172 173 if (*status != STATUS_SIZE)174 return 0;175 176 if (err_id == STATUS_WAKE_SUCCESSFUL || err_id == STATUS_NOERR)177 return 0;178 179 for (i = 0; i < err_list_len; i++)180 if (error_list[i].value == err_id)181 break;182 183 /* if err_id is not in the error_list then ignore it */184 if (i != err_list_len) {185 dev_err(dev, "%02x: %s:\n", err_id, error_list[i].error_text);186 return err_id;187 }188 189 return 0;190}191 192static int atmel_i2c_wakeup(struct i2c_client *client)193{194 struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);195 u8 status[STATUS_RSP_SIZE];196 int ret;197 198 /*199 * The device ignores any levels or transitions on the SCL pin when the200 * device is idle, asleep or during waking up. Don't check for error201 * when waking up the device.202 */203 i2c_transfer_buffer_flags(client, i2c_priv->wake_token,204 i2c_priv->wake_token_sz, I2C_M_IGNORE_NAK);205 206 /*207 * Wait to wake the device. Typical execution times for ecdh and genkey208 * are around tens of milliseconds. Delta is chosen to 50 microseconds.209 */210 usleep_range(TWHI_MIN, TWHI_MAX);211 212 ret = i2c_master_recv(client, status, STATUS_SIZE);213 if (ret < 0)214 return ret;215 216 return atmel_i2c_status(&client->dev, status);217}218 219static int atmel_i2c_sleep(struct i2c_client *client)220{221 u8 sleep = SLEEP_TOKEN;222 223 return i2c_master_send(client, &sleep, 1);224}225 226/*227 * atmel_i2c_send_receive() - send a command to the device and receive its228 * response.229 * @client: i2c client device230 * @cmd : structure used to communicate with the device231 *232 * After the device receives a Wake token, a watchdog counter starts within the233 * device. After the watchdog timer expires, the device enters sleep mode234 * regardless of whether some I/O transmission or command execution is in235 * progress. If a command is attempted when insufficient time remains prior to236 * watchdog timer execution, the device will return the watchdog timeout error237 * code without attempting to execute the command. There is no way to reset the238 * counter other than to put the device into sleep or idle mode and then239 * wake it up again.240 */241int atmel_i2c_send_receive(struct i2c_client *client, struct atmel_i2c_cmd *cmd)242{243 struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);244 int ret;245 246 mutex_lock(&i2c_priv->lock);247 248 ret = atmel_i2c_wakeup(client);249 if (ret)250 goto err;251 252 /* send the command */253 ret = i2c_master_send(client, (u8 *)cmd, cmd->count + WORD_ADDR_SIZE);254 if (ret < 0)255 goto err;256 257 /* delay the appropriate amount of time for command to execute */258 msleep(cmd->msecs);259 260 /* receive the response */261 ret = i2c_master_recv(client, cmd->data, cmd->rxsize);262 if (ret < 0)263 goto err;264 265 /* put the device into low-power mode */266 ret = atmel_i2c_sleep(client);267 if (ret < 0)268 goto err;269 270 mutex_unlock(&i2c_priv->lock);271 return atmel_i2c_status(&client->dev, cmd->data);272err:273 mutex_unlock(&i2c_priv->lock);274 return ret;275}276EXPORT_SYMBOL(atmel_i2c_send_receive);277 278static void atmel_i2c_work_handler(struct work_struct *work)279{280 struct atmel_i2c_work_data *work_data =281 container_of(work, struct atmel_i2c_work_data, work);282 struct atmel_i2c_cmd *cmd = &work_data->cmd;283 struct i2c_client *client = work_data->client;284 int status;285 286 status = atmel_i2c_send_receive(client, cmd);287 work_data->cbk(work_data, work_data->areq, status);288}289 290static struct workqueue_struct *atmel_wq;291 292void atmel_i2c_enqueue(struct atmel_i2c_work_data *work_data,293 void (*cbk)(struct atmel_i2c_work_data *work_data,294 void *areq, int status),295 void *areq)296{297 work_data->cbk = (void *)cbk;298 work_data->areq = areq;299 300 INIT_WORK(&work_data->work, atmel_i2c_work_handler);301 queue_work(atmel_wq, &work_data->work);302}303EXPORT_SYMBOL(atmel_i2c_enqueue);304 305void atmel_i2c_flush_queue(void)306{307 flush_workqueue(atmel_wq);308}309EXPORT_SYMBOL(atmel_i2c_flush_queue);310 311static inline size_t atmel_i2c_wake_token_sz(u32 bus_clk_rate)312{313 u32 no_of_bits = DIV_ROUND_UP(TWLO_USEC * bus_clk_rate, USEC_PER_SEC);314 315 /* return the size of the wake_token in bytes */316 return DIV_ROUND_UP(no_of_bits, 8);317}318 319static int device_sanity_check(struct i2c_client *client)320{321 struct atmel_i2c_cmd *cmd;322 int ret;323 324 cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);325 if (!cmd)326 return -ENOMEM;327 328 atmel_i2c_init_read_config_cmd(cmd);329 330 ret = atmel_i2c_send_receive(client, cmd);331 if (ret)332 goto free_cmd;333 334 /*335 * It is vital that the Configuration, Data and OTP zones be locked336 * prior to release into the field of the system containing the device.337 * Failure to lock these zones may permit modification of any secret338 * keys and may lead to other security problems.339 */340 if (cmd->data[LOCK_CONFIG_IDX] || cmd->data[LOCK_VALUE_IDX]) {341 dev_err(&client->dev, "Configuration or Data and OTP zones are unlocked!\n");342 ret = -ENOTSUPP;343 }344 345 /* fall through */346free_cmd:347 kfree(cmd);348 return ret;349}350 351int atmel_i2c_probe(struct i2c_client *client)352{353 struct atmel_i2c_client_priv *i2c_priv;354 struct device *dev = &client->dev;355 int ret;356 u32 bus_clk_rate;357 358 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {359 dev_err(dev, "I2C_FUNC_I2C not supported\n");360 return -ENODEV;361 }362 363 bus_clk_rate = i2c_acpi_find_bus_speed(&client->adapter->dev);364 if (!bus_clk_rate) {365 ret = device_property_read_u32(&client->adapter->dev,366 "clock-frequency", &bus_clk_rate);367 if (ret) {368 dev_err(dev, "failed to read clock-frequency property\n");369 return ret;370 }371 }372 373 if (bus_clk_rate > 1000000L) {374 dev_err(dev, "%u exceeds maximum supported clock frequency (1MHz)\n",375 bus_clk_rate);376 return -EINVAL;377 }378 379 i2c_priv = devm_kmalloc(dev, sizeof(*i2c_priv), GFP_KERNEL);380 if (!i2c_priv)381 return -ENOMEM;382 383 i2c_priv->client = client;384 mutex_init(&i2c_priv->lock);385 386 /*387 * WAKE_TOKEN_MAX_SIZE was calculated for the maximum bus_clk_rate -388 * 1MHz. The previous bus_clk_rate check ensures us that wake_token_sz389 * will always be smaller than or equal to WAKE_TOKEN_MAX_SIZE.390 */391 i2c_priv->wake_token_sz = atmel_i2c_wake_token_sz(bus_clk_rate);392 393 memset(i2c_priv->wake_token, 0, sizeof(i2c_priv->wake_token));394 395 atomic_set(&i2c_priv->tfm_count, 0);396 397 i2c_set_clientdata(client, i2c_priv);398 399 return device_sanity_check(client);400}401EXPORT_SYMBOL(atmel_i2c_probe);402 403static int __init atmel_i2c_init(void)404{405 atmel_wq = alloc_workqueue("atmel_wq", 0, 0);406 return atmel_wq ? 0 : -ENOMEM;407}408 409static void __exit atmel_i2c_exit(void)410{411 destroy_workqueue(atmel_wq);412}413 414module_init(atmel_i2c_init);415module_exit(atmel_i2c_exit);416 417MODULE_AUTHOR("Tudor Ambarus");418MODULE_DESCRIPTION("Microchip / Atmel ECC (I2C) driver");419MODULE_LICENSE("GPL v2");420