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