GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / crypto / cavium / cpt / cptvf_main.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2016 Cavium, Inc.
4  */
5
6 #include <linux/interrupt.h>
7 #include <linux/module.h>
8
9 #include "cptvf.h"
10
11 #define DRV_NAME        "thunder-cptvf"
12 #define DRV_VERSION     "1.0"
13
14 struct cptvf_wqe {
15         struct tasklet_struct twork;
16         void *cptvf;
17         u32 qno;
18 };
19
20 struct cptvf_wqe_info {
21         struct cptvf_wqe vq_wqe[CPT_NUM_QS_PER_VF];
22 };
23
24 static void vq_work_handler(unsigned long data)
25 {
26         struct cptvf_wqe_info *cwqe_info = (struct cptvf_wqe_info *)data;
27         struct cptvf_wqe *cwqe = &cwqe_info->vq_wqe[0];
28
29         vq_post_process(cwqe->cptvf, cwqe->qno);
30 }
31
32 static int init_worker_threads(struct cpt_vf *cptvf)
33 {
34         struct pci_dev *pdev = cptvf->pdev;
35         struct cptvf_wqe_info *cwqe_info;
36         int i;
37
38         cwqe_info = kzalloc(sizeof(*cwqe_info), GFP_KERNEL);
39         if (!cwqe_info)
40                 return -ENOMEM;
41
42         if (cptvf->nr_queues) {
43                 dev_info(&pdev->dev, "Creating VQ worker threads (%d)\n",
44                          cptvf->nr_queues);
45         }
46
47         for (i = 0; i < cptvf->nr_queues; i++) {
48                 tasklet_init(&cwqe_info->vq_wqe[i].twork, vq_work_handler,
49                              (u64)cwqe_info);
50                 cwqe_info->vq_wqe[i].qno = i;
51                 cwqe_info->vq_wqe[i].cptvf = cptvf;
52         }
53
54         cptvf->wqe_info = cwqe_info;
55
56         return 0;
57 }
58
59 static void cleanup_worker_threads(struct cpt_vf *cptvf)
60 {
61         struct cptvf_wqe_info *cwqe_info;
62         struct pci_dev *pdev = cptvf->pdev;
63         int i;
64
65         cwqe_info = (struct cptvf_wqe_info *)cptvf->wqe_info;
66         if (!cwqe_info)
67                 return;
68
69         if (cptvf->nr_queues) {
70                 dev_info(&pdev->dev, "Cleaning VQ worker threads (%u)\n",
71                          cptvf->nr_queues);
72         }
73
74         for (i = 0; i < cptvf->nr_queues; i++)
75                 tasklet_kill(&cwqe_info->vq_wqe[i].twork);
76
77         kfree_sensitive(cwqe_info);
78         cptvf->wqe_info = NULL;
79 }
80
81 static void free_pending_queues(struct pending_qinfo *pqinfo)
82 {
83         int i;
84         struct pending_queue *queue;
85
86         for_each_pending_queue(pqinfo, queue, i) {
87                 if (!queue->head)
88                         continue;
89
90                 /* free single queue */
91                 kfree_sensitive((queue->head));
92
93                 queue->front = 0;
94                 queue->rear = 0;
95
96                 return;
97         }
98
99         pqinfo->qlen = 0;
100         pqinfo->nr_queues = 0;
101 }
102
103 static int alloc_pending_queues(struct pending_qinfo *pqinfo, u32 qlen,
104                                 u32 nr_queues)
105 {
106         u32 i;
107         int ret;
108         struct pending_queue *queue = NULL;
109
110         pqinfo->nr_queues = nr_queues;
111         pqinfo->qlen = qlen;
112
113         for_each_pending_queue(pqinfo, queue, i) {
114                 queue->head = kcalloc(qlen, sizeof(*queue->head), GFP_KERNEL);
115                 if (!queue->head) {
116                         ret = -ENOMEM;
117                         goto pending_qfail;
118                 }
119
120                 queue->front = 0;
121                 queue->rear = 0;
122                 atomic64_set((&queue->pending_count), (0));
123
124                 /* init queue spin lock */
125                 spin_lock_init(&queue->lock);
126         }
127
128         return 0;
129
130 pending_qfail:
131         free_pending_queues(pqinfo);
132
133         return ret;
134 }
135
136 static int init_pending_queues(struct cpt_vf *cptvf, u32 qlen, u32 nr_queues)
137 {
138         struct pci_dev *pdev = cptvf->pdev;
139         int ret;
140
141         if (!nr_queues)
142                 return 0;
143
144         ret = alloc_pending_queues(&cptvf->pqinfo, qlen, nr_queues);
145         if (ret) {
146                 dev_err(&pdev->dev, "failed to setup pending queues (%u)\n",
147                         nr_queues);
148                 return ret;
149         }
150
151         return 0;
152 }
153
154 static void cleanup_pending_queues(struct cpt_vf *cptvf)
155 {
156         struct pci_dev *pdev = cptvf->pdev;
157
158         if (!cptvf->nr_queues)
159                 return;
160
161         dev_info(&pdev->dev, "Cleaning VQ pending queue (%u)\n",
162                  cptvf->nr_queues);
163         free_pending_queues(&cptvf->pqinfo);
164 }
165
166 static void free_command_queues(struct cpt_vf *cptvf,
167                                 struct command_qinfo *cqinfo)
168 {
169         int i;
170         struct command_queue *queue = NULL;
171         struct command_chunk *chunk = NULL;
172         struct pci_dev *pdev = cptvf->pdev;
173         struct hlist_node *node;
174
175         /* clean up for each queue */
176         for (i = 0; i < cptvf->nr_queues; i++) {
177                 queue = &cqinfo->queue[i];
178                 if (hlist_empty(&cqinfo->queue[i].chead))
179                         continue;
180
181                 hlist_for_each_entry_safe(chunk, node, &cqinfo->queue[i].chead,
182                                           nextchunk) {
183                         dma_free_coherent(&pdev->dev, chunk->size,
184                                           chunk->head,
185                                           chunk->dma_addr);
186                         chunk->head = NULL;
187                         chunk->dma_addr = 0;
188                         hlist_del(&chunk->nextchunk);
189                         kfree_sensitive(chunk);
190                 }
191
192                 queue->nchunks = 0;
193                 queue->idx = 0;
194         }
195
196         /* common cleanup */
197         cqinfo->cmd_size = 0;
198 }
199
200 static int alloc_command_queues(struct cpt_vf *cptvf,
201                                 struct command_qinfo *cqinfo, size_t cmd_size,
202                                 u32 qlen)
203 {
204         int i;
205         size_t q_size;
206         struct command_queue *queue = NULL;
207         struct pci_dev *pdev = cptvf->pdev;
208
209         /* common init */
210         cqinfo->cmd_size = cmd_size;
211         /* Qsize in dwords, needed for SADDR config, 1-next chunk pointer */
212         cptvf->qsize = min(qlen, cqinfo->qchunksize) *
213                         CPT_NEXT_CHUNK_PTR_SIZE + 1;
214         /* Qsize in bytes to create space for alignment */
215         q_size = qlen * cqinfo->cmd_size;
216
217         /* per queue initialization */
218         for (i = 0; i < cptvf->nr_queues; i++) {
219                 size_t c_size = 0;
220                 size_t rem_q_size = q_size;
221                 struct command_chunk *curr = NULL, *first = NULL, *last = NULL;
222                 u32 qcsize_bytes = cqinfo->qchunksize * cqinfo->cmd_size;
223
224                 queue = &cqinfo->queue[i];
225                 INIT_HLIST_HEAD(&cqinfo->queue[i].chead);
226                 do {
227                         curr = kzalloc(sizeof(*curr), GFP_KERNEL);
228                         if (!curr)
229                                 goto cmd_qfail;
230
231                         c_size = (rem_q_size > qcsize_bytes) ? qcsize_bytes :
232                                         rem_q_size;
233                         curr->head = dma_alloc_coherent(&pdev->dev,
234                                                         c_size + CPT_NEXT_CHUNK_PTR_SIZE,
235                                                         &curr->dma_addr,
236                                                         GFP_KERNEL);
237                         if (!curr->head) {
238                                 dev_err(&pdev->dev, "Command Q (%d) chunk (%d) allocation failed\n",
239                                         i, queue->nchunks);
240                                 kfree(curr);
241                                 goto cmd_qfail;
242                         }
243
244                         curr->size = c_size;
245                         if (queue->nchunks == 0) {
246                                 hlist_add_head(&curr->nextchunk,
247                                                &cqinfo->queue[i].chead);
248                                 first = curr;
249                         } else {
250                                 hlist_add_behind(&curr->nextchunk,
251                                                  &last->nextchunk);
252                         }
253
254                         queue->nchunks++;
255                         rem_q_size -= c_size;
256                         if (last)
257                                 *((u64 *)(&last->head[last->size])) = (u64)curr->dma_addr;
258
259                         last = curr;
260                 } while (rem_q_size);
261
262                 /* Make the queue circular */
263                 /* Tie back last chunk entry to head */
264                 curr = first;
265                 *((u64 *)(&last->head[last->size])) = (u64)curr->dma_addr;
266                 queue->qhead = curr;
267                 spin_lock_init(&queue->lock);
268         }
269         return 0;
270
271 cmd_qfail:
272         free_command_queues(cptvf, cqinfo);
273         return -ENOMEM;
274 }
275
276 static int init_command_queues(struct cpt_vf *cptvf, u32 qlen)
277 {
278         struct pci_dev *pdev = cptvf->pdev;
279         int ret;
280
281         /* setup AE command queues */
282         ret = alloc_command_queues(cptvf, &cptvf->cqinfo, CPT_INST_SIZE,
283                                    qlen);
284         if (ret) {
285                 dev_err(&pdev->dev, "failed to allocate AE command queues (%u)\n",
286                         cptvf->nr_queues);
287                 return ret;
288         }
289
290         return ret;
291 }
292
293 static void cleanup_command_queues(struct cpt_vf *cptvf)
294 {
295         struct pci_dev *pdev = cptvf->pdev;
296
297         if (!cptvf->nr_queues)
298                 return;
299
300         dev_info(&pdev->dev, "Cleaning VQ command queue (%u)\n",
301                  cptvf->nr_queues);
302         free_command_queues(cptvf, &cptvf->cqinfo);
303 }
304
305 static void cptvf_sw_cleanup(struct cpt_vf *cptvf)
306 {
307         cleanup_worker_threads(cptvf);
308         cleanup_pending_queues(cptvf);
309         cleanup_command_queues(cptvf);
310 }
311
312 static int cptvf_sw_init(struct cpt_vf *cptvf, u32 qlen, u32 nr_queues)
313 {
314         struct pci_dev *pdev = cptvf->pdev;
315         int ret = 0;
316         u32 max_dev_queues = 0;
317
318         max_dev_queues = CPT_NUM_QS_PER_VF;
319         /* possible cpus */
320         nr_queues = min_t(u32, nr_queues, max_dev_queues);
321         cptvf->nr_queues = nr_queues;
322
323         ret = init_command_queues(cptvf, qlen);
324         if (ret) {
325                 dev_err(&pdev->dev, "Failed to setup command queues (%u)\n",
326                         nr_queues);
327                 return ret;
328         }
329
330         ret = init_pending_queues(cptvf, qlen, nr_queues);
331         if (ret) {
332                 dev_err(&pdev->dev, "Failed to setup pending queues (%u)\n",
333                         nr_queues);
334                 goto setup_pqfail;
335         }
336
337         /* Create worker threads for BH processing */
338         ret = init_worker_threads(cptvf);
339         if (ret) {
340                 dev_err(&pdev->dev, "Failed to setup worker threads\n");
341                 goto init_work_fail;
342         }
343
344         return 0;
345
346 init_work_fail:
347         cleanup_worker_threads(cptvf);
348         cleanup_pending_queues(cptvf);
349
350 setup_pqfail:
351         cleanup_command_queues(cptvf);
352
353         return ret;
354 }
355
356 static void cptvf_free_irq_affinity(struct cpt_vf *cptvf, int vec)
357 {
358         irq_set_affinity_hint(pci_irq_vector(cptvf->pdev, vec), NULL);
359         free_cpumask_var(cptvf->affinity_mask[vec]);
360 }
361
362 static void cptvf_write_vq_ctl(struct cpt_vf *cptvf, bool val)
363 {
364         union cptx_vqx_ctl vqx_ctl;
365
366         vqx_ctl.u = cpt_read_csr64(cptvf->reg_base, CPTX_VQX_CTL(0, 0));
367         vqx_ctl.s.ena = val;
368         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_CTL(0, 0), vqx_ctl.u);
369 }
370
371 void cptvf_write_vq_doorbell(struct cpt_vf *cptvf, u32 val)
372 {
373         union cptx_vqx_doorbell vqx_dbell;
374
375         vqx_dbell.u = cpt_read_csr64(cptvf->reg_base,
376                                      CPTX_VQX_DOORBELL(0, 0));
377         vqx_dbell.s.dbell_cnt = val * 8; /* Num of Instructions * 8 words */
378         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_DOORBELL(0, 0),
379                         vqx_dbell.u);
380 }
381
382 static void cptvf_write_vq_inprog(struct cpt_vf *cptvf, u8 val)
383 {
384         union cptx_vqx_inprog vqx_inprg;
385
386         vqx_inprg.u = cpt_read_csr64(cptvf->reg_base, CPTX_VQX_INPROG(0, 0));
387         vqx_inprg.s.inflight = val;
388         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_INPROG(0, 0), vqx_inprg.u);
389 }
390
391 static void cptvf_write_vq_done_numwait(struct cpt_vf *cptvf, u32 val)
392 {
393         union cptx_vqx_done_wait vqx_dwait;
394
395         vqx_dwait.u = cpt_read_csr64(cptvf->reg_base,
396                                      CPTX_VQX_DONE_WAIT(0, 0));
397         vqx_dwait.s.num_wait = val;
398         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_DONE_WAIT(0, 0),
399                         vqx_dwait.u);
400 }
401
402 static void cptvf_write_vq_done_timewait(struct cpt_vf *cptvf, u16 time)
403 {
404         union cptx_vqx_done_wait vqx_dwait;
405
406         vqx_dwait.u = cpt_read_csr64(cptvf->reg_base,
407                                      CPTX_VQX_DONE_WAIT(0, 0));
408         vqx_dwait.s.time_wait = time;
409         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_DONE_WAIT(0, 0),
410                         vqx_dwait.u);
411 }
412
413 static void cptvf_enable_swerr_interrupts(struct cpt_vf *cptvf)
414 {
415         union cptx_vqx_misc_ena_w1s vqx_misc_ena;
416
417         vqx_misc_ena.u = cpt_read_csr64(cptvf->reg_base,
418                                         CPTX_VQX_MISC_ENA_W1S(0, 0));
419         /* Set mbox(0) interupts for the requested vf */
420         vqx_misc_ena.s.swerr = 1;
421         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0),
422                         vqx_misc_ena.u);
423 }
424
425 static void cptvf_enable_mbox_interrupts(struct cpt_vf *cptvf)
426 {
427         union cptx_vqx_misc_ena_w1s vqx_misc_ena;
428
429         vqx_misc_ena.u = cpt_read_csr64(cptvf->reg_base,
430                                         CPTX_VQX_MISC_ENA_W1S(0, 0));
431         /* Set mbox(0) interupts for the requested vf */
432         vqx_misc_ena.s.mbox = 1;
433         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0),
434                         vqx_misc_ena.u);
435 }
436
437 static void cptvf_enable_done_interrupts(struct cpt_vf *cptvf)
438 {
439         union cptx_vqx_done_ena_w1s vqx_done_ena;
440
441         vqx_done_ena.u = cpt_read_csr64(cptvf->reg_base,
442                                         CPTX_VQX_DONE_ENA_W1S(0, 0));
443         /* Set DONE interrupt for the requested vf */
444         vqx_done_ena.s.done = 1;
445         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_DONE_ENA_W1S(0, 0),
446                         vqx_done_ena.u);
447 }
448
449 static void cptvf_clear_dovf_intr(struct cpt_vf *cptvf)
450 {
451         union cptx_vqx_misc_int vqx_misc_int;
452
453         vqx_misc_int.u = cpt_read_csr64(cptvf->reg_base,
454                                         CPTX_VQX_MISC_INT(0, 0));
455         /* W1C for the VF */
456         vqx_misc_int.s.dovf = 1;
457         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_INT(0, 0),
458                         vqx_misc_int.u);
459 }
460
461 static void cptvf_clear_irde_intr(struct cpt_vf *cptvf)
462 {
463         union cptx_vqx_misc_int vqx_misc_int;
464
465         vqx_misc_int.u = cpt_read_csr64(cptvf->reg_base,
466                                         CPTX_VQX_MISC_INT(0, 0));
467         /* W1C for the VF */
468         vqx_misc_int.s.irde = 1;
469         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_INT(0, 0),
470                         vqx_misc_int.u);
471 }
472
473 static void cptvf_clear_nwrp_intr(struct cpt_vf *cptvf)
474 {
475         union cptx_vqx_misc_int vqx_misc_int;
476
477         vqx_misc_int.u = cpt_read_csr64(cptvf->reg_base,
478                                         CPTX_VQX_MISC_INT(0, 0));
479         /* W1C for the VF */
480         vqx_misc_int.s.nwrp = 1;
481         cpt_write_csr64(cptvf->reg_base,
482                         CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
483 }
484
485 static void cptvf_clear_mbox_intr(struct cpt_vf *cptvf)
486 {
487         union cptx_vqx_misc_int vqx_misc_int;
488
489         vqx_misc_int.u = cpt_read_csr64(cptvf->reg_base,
490                                         CPTX_VQX_MISC_INT(0, 0));
491         /* W1C for the VF */
492         vqx_misc_int.s.mbox = 1;
493         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_INT(0, 0),
494                         vqx_misc_int.u);
495 }
496
497 static void cptvf_clear_swerr_intr(struct cpt_vf *cptvf)
498 {
499         union cptx_vqx_misc_int vqx_misc_int;
500
501         vqx_misc_int.u = cpt_read_csr64(cptvf->reg_base,
502                                         CPTX_VQX_MISC_INT(0, 0));
503         /* W1C for the VF */
504         vqx_misc_int.s.swerr = 1;
505         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_INT(0, 0),
506                         vqx_misc_int.u);
507 }
508
509 static u64 cptvf_read_vf_misc_intr_status(struct cpt_vf *cptvf)
510 {
511         return cpt_read_csr64(cptvf->reg_base, CPTX_VQX_MISC_INT(0, 0));
512 }
513
514 static irqreturn_t cptvf_misc_intr_handler(int irq, void *cptvf_irq)
515 {
516         struct cpt_vf *cptvf = (struct cpt_vf *)cptvf_irq;
517         struct pci_dev *pdev = cptvf->pdev;
518         u64 intr;
519
520         intr = cptvf_read_vf_misc_intr_status(cptvf);
521         /*Check for MISC interrupt types*/
522         if (likely(intr & CPT_VF_INTR_MBOX_MASK)) {
523                 dev_dbg(&pdev->dev, "Mailbox interrupt 0x%llx on CPT VF %d\n",
524                         intr, cptvf->vfid);
525                 cptvf_handle_mbox_intr(cptvf);
526                 cptvf_clear_mbox_intr(cptvf);
527         } else if (unlikely(intr & CPT_VF_INTR_DOVF_MASK)) {
528                 cptvf_clear_dovf_intr(cptvf);
529                 /*Clear doorbell count*/
530                 cptvf_write_vq_doorbell(cptvf, 0);
531                 dev_err(&pdev->dev, "Doorbell overflow error interrupt 0x%llx on CPT VF %d\n",
532                         intr, cptvf->vfid);
533         } else if (unlikely(intr & CPT_VF_INTR_IRDE_MASK)) {
534                 cptvf_clear_irde_intr(cptvf);
535                 dev_err(&pdev->dev, "Instruction NCB read error interrupt 0x%llx on CPT VF %d\n",
536                         intr, cptvf->vfid);
537         } else if (unlikely(intr & CPT_VF_INTR_NWRP_MASK)) {
538                 cptvf_clear_nwrp_intr(cptvf);
539                 dev_err(&pdev->dev, "NCB response write error interrupt 0x%llx on CPT VF %d\n",
540                         intr, cptvf->vfid);
541         } else if (unlikely(intr & CPT_VF_INTR_SERR_MASK)) {
542                 cptvf_clear_swerr_intr(cptvf);
543                 dev_err(&pdev->dev, "Software error interrupt 0x%llx on CPT VF %d\n",
544                         intr, cptvf->vfid);
545         } else {
546                 dev_err(&pdev->dev, "Unhandled interrupt in CPT VF %d\n",
547                         cptvf->vfid);
548         }
549
550         return IRQ_HANDLED;
551 }
552
553 static inline struct cptvf_wqe *get_cptvf_vq_wqe(struct cpt_vf *cptvf,
554                                                  int qno)
555 {
556         struct cptvf_wqe_info *nwqe_info;
557
558         if (unlikely(qno >= cptvf->nr_queues))
559                 return NULL;
560         nwqe_info = (struct cptvf_wqe_info *)cptvf->wqe_info;
561
562         return &nwqe_info->vq_wqe[qno];
563 }
564
565 static inline u32 cptvf_read_vq_done_count(struct cpt_vf *cptvf)
566 {
567         union cptx_vqx_done vqx_done;
568
569         vqx_done.u = cpt_read_csr64(cptvf->reg_base, CPTX_VQX_DONE(0, 0));
570         return vqx_done.s.done;
571 }
572
573 static inline void cptvf_write_vq_done_ack(struct cpt_vf *cptvf,
574                                            u32 ackcnt)
575 {
576         union cptx_vqx_done_ack vqx_dack_cnt;
577
578         vqx_dack_cnt.u = cpt_read_csr64(cptvf->reg_base,
579                                         CPTX_VQX_DONE_ACK(0, 0));
580         vqx_dack_cnt.s.done_ack = ackcnt;
581         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_DONE_ACK(0, 0),
582                         vqx_dack_cnt.u);
583 }
584
585 static irqreturn_t cptvf_done_intr_handler(int irq, void *cptvf_irq)
586 {
587         struct cpt_vf *cptvf = (struct cpt_vf *)cptvf_irq;
588         struct pci_dev *pdev = cptvf->pdev;
589         /* Read the number of completions */
590         u32 intr = cptvf_read_vq_done_count(cptvf);
591
592         if (intr) {
593                 struct cptvf_wqe *wqe;
594
595                 /* Acknowledge the number of
596                  * scheduled completions for processing
597                  */
598                 cptvf_write_vq_done_ack(cptvf, intr);
599                 wqe = get_cptvf_vq_wqe(cptvf, 0);
600                 if (unlikely(!wqe)) {
601                         dev_err(&pdev->dev, "No work to schedule for VF (%d)",
602                                 cptvf->vfid);
603                         return IRQ_NONE;
604                 }
605                 tasklet_hi_schedule(&wqe->twork);
606         }
607
608         return IRQ_HANDLED;
609 }
610
611 static void cptvf_set_irq_affinity(struct cpt_vf *cptvf, int vec)
612 {
613         struct pci_dev *pdev = cptvf->pdev;
614         int cpu;
615
616         if (!zalloc_cpumask_var(&cptvf->affinity_mask[vec],
617                                 GFP_KERNEL)) {
618                 dev_err(&pdev->dev, "Allocation failed for affinity_mask for VF %d",
619                         cptvf->vfid);
620                 return;
621         }
622
623         cpu = cptvf->vfid % num_online_cpus();
624         cpumask_set_cpu(cpumask_local_spread(cpu, cptvf->node),
625                         cptvf->affinity_mask[vec]);
626         irq_set_affinity_hint(pci_irq_vector(pdev, vec),
627                         cptvf->affinity_mask[vec]);
628 }
629
630 static void cptvf_write_vq_saddr(struct cpt_vf *cptvf, u64 val)
631 {
632         union cptx_vqx_saddr vqx_saddr;
633
634         vqx_saddr.u = val;
635         cpt_write_csr64(cptvf->reg_base, CPTX_VQX_SADDR(0, 0), vqx_saddr.u);
636 }
637
638 static void cptvf_device_init(struct cpt_vf *cptvf)
639 {
640         u64 base_addr = 0;
641
642         /* Disable the VQ */
643         cptvf_write_vq_ctl(cptvf, 0);
644         /* Reset the doorbell */
645         cptvf_write_vq_doorbell(cptvf, 0);
646         /* Clear inflight */
647         cptvf_write_vq_inprog(cptvf, 0);
648         /* Write VQ SADDR */
649         /* TODO: for now only one queue, so hard coded */
650         base_addr = (u64)(cptvf->cqinfo.queue[0].qhead->dma_addr);
651         cptvf_write_vq_saddr(cptvf, base_addr);
652         /* Configure timerhold / coalescence */
653         cptvf_write_vq_done_timewait(cptvf, CPT_TIMER_THOLD);
654         cptvf_write_vq_done_numwait(cptvf, 1);
655         /* Enable the VQ */
656         cptvf_write_vq_ctl(cptvf, 1);
657         /* Flag the VF ready */
658         cptvf->flags |= CPT_FLAG_DEVICE_READY;
659 }
660
661 static int cptvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
662 {
663         struct device *dev = &pdev->dev;
664         struct cpt_vf *cptvf;
665         int    err;
666
667         cptvf = devm_kzalloc(dev, sizeof(*cptvf), GFP_KERNEL);
668         if (!cptvf)
669                 return -ENOMEM;
670
671         pci_set_drvdata(pdev, cptvf);
672         cptvf->pdev = pdev;
673         err = pci_enable_device(pdev);
674         if (err) {
675                 dev_err(dev, "Failed to enable PCI device\n");
676                 pci_set_drvdata(pdev, NULL);
677                 return err;
678         }
679
680         err = pci_request_regions(pdev, DRV_NAME);
681         if (err) {
682                 dev_err(dev, "PCI request regions failed 0x%x\n", err);
683                 goto cptvf_err_disable_device;
684         }
685         /* Mark as VF driver */
686         cptvf->flags |= CPT_FLAG_VF_DRIVER;
687         err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
688         if (err) {
689                 dev_err(dev, "Unable to get usable 48-bit DMA configuration\n");
690                 goto cptvf_err_release_regions;
691         }
692
693         /* MAP PF's configuration registers */
694         cptvf->reg_base = pcim_iomap(pdev, 0, 0);
695         if (!cptvf->reg_base) {
696                 dev_err(dev, "Cannot map config register space, aborting\n");
697                 err = -ENOMEM;
698                 goto cptvf_err_release_regions;
699         }
700
701         cptvf->node = dev_to_node(&pdev->dev);
702         err = pci_alloc_irq_vectors(pdev, CPT_VF_MSIX_VECTORS,
703                         CPT_VF_MSIX_VECTORS, PCI_IRQ_MSIX);
704         if (err < 0) {
705                 dev_err(dev, "Request for #%d msix vectors failed\n",
706                         CPT_VF_MSIX_VECTORS);
707                 goto cptvf_err_release_regions;
708         }
709
710         err = request_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_MISC),
711                           cptvf_misc_intr_handler, 0, "CPT VF misc intr",
712                           cptvf);
713         if (err) {
714                 dev_err(dev, "Request misc irq failed");
715                 goto cptvf_free_vectors;
716         }
717
718         /* Enable mailbox interrupt */
719         cptvf_enable_mbox_interrupts(cptvf);
720         cptvf_enable_swerr_interrupts(cptvf);
721
722         /* Check ready with PF */
723         /* Gets chip ID / device Id from PF if ready */
724         err = cptvf_check_pf_ready(cptvf);
725         if (err) {
726                 dev_err(dev, "PF not responding to READY msg");
727                 goto cptvf_free_misc_irq;
728         }
729
730         /* CPT VF software resources initialization */
731         cptvf->cqinfo.qchunksize = CPT_CMD_QCHUNK_SIZE;
732         err = cptvf_sw_init(cptvf, CPT_CMD_QLEN, CPT_NUM_QS_PER_VF);
733         if (err) {
734                 dev_err(dev, "cptvf_sw_init() failed");
735                 goto cptvf_free_misc_irq;
736         }
737         /* Convey VQ LEN to PF */
738         err = cptvf_send_vq_size_msg(cptvf);
739         if (err) {
740                 dev_err(dev, "PF not responding to QLEN msg");
741                 goto cptvf_free_misc_irq;
742         }
743
744         /* CPT VF device initialization */
745         cptvf_device_init(cptvf);
746         /* Send msg to PF to assign currnet Q to required group */
747         cptvf->vfgrp = 1;
748         err = cptvf_send_vf_to_grp_msg(cptvf);
749         if (err) {
750                 dev_err(dev, "PF not responding to VF_GRP msg");
751                 goto cptvf_free_misc_irq;
752         }
753
754         cptvf->priority = 1;
755         err = cptvf_send_vf_priority_msg(cptvf);
756         if (err) {
757                 dev_err(dev, "PF not responding to VF_PRIO msg");
758                 goto cptvf_free_misc_irq;
759         }
760
761         err = request_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_DONE),
762                           cptvf_done_intr_handler, 0, "CPT VF done intr",
763                           cptvf);
764         if (err) {
765                 dev_err(dev, "Request done irq failed\n");
766                 goto cptvf_free_misc_irq;
767         }
768
769         /* Enable mailbox interrupt */
770         cptvf_enable_done_interrupts(cptvf);
771
772         /* Set irq affinity masks */
773         cptvf_set_irq_affinity(cptvf, CPT_VF_INT_VEC_E_MISC);
774         cptvf_set_irq_affinity(cptvf, CPT_VF_INT_VEC_E_DONE);
775
776         err = cptvf_send_vf_up(cptvf);
777         if (err) {
778                 dev_err(dev, "PF not responding to UP msg");
779                 goto cptvf_free_irq_affinity;
780         }
781         err = cvm_crypto_init(cptvf);
782         if (err) {
783                 dev_err(dev, "Algorithm register failed\n");
784                 goto cptvf_free_irq_affinity;
785         }
786         return 0;
787
788 cptvf_free_irq_affinity:
789         cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_DONE);
790         cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_MISC);
791 cptvf_free_misc_irq:
792         free_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_MISC), cptvf);
793 cptvf_free_vectors:
794         pci_free_irq_vectors(cptvf->pdev);
795 cptvf_err_release_regions:
796         pci_release_regions(pdev);
797 cptvf_err_disable_device:
798         pci_disable_device(pdev);
799         pci_set_drvdata(pdev, NULL);
800
801         return err;
802 }
803
804 static void cptvf_remove(struct pci_dev *pdev)
805 {
806         struct cpt_vf *cptvf = pci_get_drvdata(pdev);
807
808         if (!cptvf) {
809                 dev_err(&pdev->dev, "Invalid CPT-VF device\n");
810                 return;
811         }
812
813         /* Convey DOWN to PF */
814         if (cptvf_send_vf_down(cptvf)) {
815                 dev_err(&pdev->dev, "PF not responding to DOWN msg");
816         } else {
817                 cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_DONE);
818                 cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_MISC);
819                 free_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_DONE), cptvf);
820                 free_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_MISC), cptvf);
821                 pci_free_irq_vectors(cptvf->pdev);
822                 cptvf_sw_cleanup(cptvf);
823                 pci_set_drvdata(pdev, NULL);
824                 pci_release_regions(pdev);
825                 pci_disable_device(pdev);
826                 cvm_crypto_exit();
827         }
828 }
829
830 static void cptvf_shutdown(struct pci_dev *pdev)
831 {
832         cptvf_remove(pdev);
833 }
834
835 /* Supported devices */
836 static const struct pci_device_id cptvf_id_table[] = {
837         {PCI_VDEVICE(CAVIUM, CPT_81XX_PCI_VF_DEVICE_ID), 0},
838         { 0, }  /* end of table */
839 };
840
841 static struct pci_driver cptvf_pci_driver = {
842         .name = DRV_NAME,
843         .id_table = cptvf_id_table,
844         .probe = cptvf_probe,
845         .remove = cptvf_remove,
846         .shutdown = cptvf_shutdown,
847 };
848
849 module_pci_driver(cptvf_pci_driver);
850
851 MODULE_AUTHOR("George Cherian <george.cherian@cavium.com>");
852 MODULE_DESCRIPTION("Cavium Thunder CPT Virtual Function Driver");
853 MODULE_LICENSE("GPL v2");
854 MODULE_VERSION(DRV_VERSION);
855 MODULE_DEVICE_TABLE(pci, cptvf_id_table);