The timer triggers when 500ms have gone by after triggering the engine and no completion interrupt was received. The callback then tries to sanitise things as well as possible.
Unified · Split
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | #define MV_CESA "MV-CESA:" | 25 | #define MV_CESA "MV-CESA:" |
| 26 | #define MAX_HW_HASH_SIZE 0xFFFF | 26 | #define MAX_HW_HASH_SIZE 0xFFFF |
| 27 | #define MV_CESA_EXPIRE 500 /* msec */ | ||
| 27 | 28 | ||
| 28 | /* | 29 | /* |
| 29 | * STM: | 30 | * STM: |
| @@ -87,6 +88,7 @@ struct crypto_priv { · 57 unmodified lines | |||
| 87 | spinlock_t lock; | 88 | spinlock_t lock; |
| 88 | struct crypto_queue queue; | 89 | struct crypto_queue queue; |
| 89 | enum engine_status eng_st; | 90 | enum engine_status eng_st; |
| 91 | struct timer_list completion_timer; | ||
| 90 | struct crypto_async_request *cur_req; | 92 | struct crypto_async_request *cur_req; |
| 91 | struct req_progress p; | 93 | struct req_progress p; |
| 92 | int max_req_size; | 94 | int max_req_size; |
| @@ -138,6 +140,29 @@ struct mv_req_hash_ctx { · 45 unmodified lines | |||
| 138 | int count_add; | 140 | int count_add; |
| 139 | }; | 141 | }; |
| 140 | 142 | ||
| 143 | static void mv_completion_timer_callback(unsigned long unused) | ||
| 144 | { | ||
| 145 | int active = readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_EN_SEC_ACCL0; | ||
| 146 | |||
| 147 | printk(KERN_ERR MV_CESA | ||
| 148 | "completion timer expired (CESA %sactive), cleaning up.\n", | ||
| 149 | active ? "" : "in"); | ||
| 150 | |||
| 151 | del_timer(&cpg->completion_timer); | ||
| 152 | writel(SEC_CMD_DISABLE_SEC, cpg->reg + SEC_ACCEL_CMD); | ||
| 153 | while(readl(cpg->reg + SEC_ACCEL_CMD) & SEC_CMD_DISABLE_SEC) | ||
| 154 | printk(KERN_INFO MV_CESA "%s: waiting for engine finishing\n", __func__); | ||
| 155 | cpg->eng_st = ENGINE_W_DEQUEUE; | ||
| 156 | wake_up_process(cpg->queue_th); | ||
| 157 | } | ||
| 158 | |||
| 159 | static void mv_setup_timer(void) | ||
| 160 | { | ||
| 161 | setup_timer(&cpg->completion_timer, &mv_completion_timer_callback, 0); | ||
| 162 | mod_timer(&cpg->completion_timer, | ||
| 163 | jiffies + msecs_to_jiffies(MV_CESA_EXPIRE)); | ||
| 164 | } | ||
| 165 | |||
| 141 | static void compute_aes_dec_key(struct mv_ctx *ctx) | 166 | static void compute_aes_dec_key(struct mv_ctx *ctx) |
| 142 | { | 167 | { |
| 143 | struct crypto_aes_ctx gen_aes_key; | 168 | struct crypto_aes_ctx gen_aes_key; |
| @@ -273,12 +298,8 @@ static void mv_process_current_q(int first_block) · 129 unmodified lines | |||
| 273 | sizeof(struct sec_accel_config)); | 298 | sizeof(struct sec_accel_config)); |
| 274 | 299 | ||
| 275 | /* GO */ | 300 | /* GO */ |
| 301 | mv_setup_timer(); | ||
| 276 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); | 302 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); |
| 277 | |||
| 278 | /* | ||
| 279 | * XXX: add timer if the interrupt does not occur for some mystery | ||
| 280 | * reason | ||
| 281 | */ | ||
| 282 | } | 303 | } |
| 283 | 304 | ||
| 284 | static void mv_crypto_algo_completion(void) | 305 | static void mv_crypto_algo_completion(void) |
| @@ -357,12 +378,8 @@ static void mv_process_hash_current(int first_block) · 72 unmodified lines | |||
| 357 | memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); | 378 | memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config)); |
| 358 | 379 | ||
| 359 | /* GO */ | 380 | /* GO */ |
| 381 | mv_setup_timer(); | ||
| 360 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); | 382 | writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD); |
| 361 | |||
| 362 | /* | ||
| 363 | * XXX: add timer if the interrupt does not occur for some mystery | ||
| 364 | * reason | ||
| 365 | */ | ||
| 366 | } | 383 | } |
| 367 | 384 | ||
| 368 | static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx, | 385 | static inline int mv_hash_import_sha1_ctx(const struct mv_req_hash_ctx *ctx, |
| @@ -888,6 +905,10 @@ irqreturn_t crypto_int(int irq, void *priv) · 519 unmodified lines | |||
| 888 | if (!(val & SEC_INT_ACCEL0_DONE)) | 905 | if (!(val & SEC_INT_ACCEL0_DONE)) |
| 889 | return IRQ_NONE; | 906 | return IRQ_NONE; |
| 890 | 907 | ||
| 908 | if (!del_timer(&cpg->completion_timer)) { | ||
| 909 | printk(KERN_WARNING MV_CESA | ||
| 910 | "got an interrupt but no pending timer?\n"); | ||
| 911 | } | ||
| 891 | val &= ~SEC_INT_ACCEL0_DONE; | 912 | val &= ~SEC_INT_ACCEL0_DONE; |
| 892 | writel(val, cpg->reg + FPGA_INT_STATUS); | 913 | writel(val, cpg->reg + FPGA_INT_STATUS); |
| 893 | writel(val, cpg->reg + SEC_ACCEL_INT_STATUS); | 914 | writel(val, cpg->reg + SEC_ACCEL_INT_STATUS); |