cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

otx_cptvf_main.c (24866B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Marvell OcteonTX CPT driver
      3 *
      4 * Copyright (C) 2019 Marvell International Ltd.
      5 *
      6 * This program is free software; you can redistribute it and/or modify
      7 * it under the terms of the GNU General Public License version 2 as
      8 * published by the Free Software Foundation.
      9 */
     10
     11#include <linux/interrupt.h>
     12#include <linux/module.h>
     13#include "otx_cptvf.h"
     14#include "otx_cptvf_algs.h"
     15#include "otx_cptvf_reqmgr.h"
     16
     17#define DRV_NAME	"octeontx-cptvf"
     18#define DRV_VERSION	"1.0"
     19
     20static void vq_work_handler(unsigned long data)
     21{
     22	struct otx_cptvf_wqe_info *cwqe_info =
     23					(struct otx_cptvf_wqe_info *) data;
     24
     25	otx_cpt_post_process(&cwqe_info->vq_wqe[0]);
     26}
     27
     28static int init_worker_threads(struct otx_cptvf *cptvf)
     29{
     30	struct pci_dev *pdev = cptvf->pdev;
     31	struct otx_cptvf_wqe_info *cwqe_info;
     32	int i;
     33
     34	cwqe_info = kzalloc(sizeof(*cwqe_info), GFP_KERNEL);
     35	if (!cwqe_info)
     36		return -ENOMEM;
     37
     38	if (cptvf->num_queues) {
     39		dev_dbg(&pdev->dev, "Creating VQ worker threads (%d)\n",
     40			cptvf->num_queues);
     41	}
     42
     43	for (i = 0; i < cptvf->num_queues; i++) {
     44		tasklet_init(&cwqe_info->vq_wqe[i].twork, vq_work_handler,
     45			     (u64)cwqe_info);
     46		cwqe_info->vq_wqe[i].cptvf = cptvf;
     47	}
     48	cptvf->wqe_info = cwqe_info;
     49
     50	return 0;
     51}
     52
     53static void cleanup_worker_threads(struct otx_cptvf *cptvf)
     54{
     55	struct pci_dev *pdev = cptvf->pdev;
     56	struct otx_cptvf_wqe_info *cwqe_info;
     57	int i;
     58
     59	cwqe_info = (struct otx_cptvf_wqe_info *)cptvf->wqe_info;
     60	if (!cwqe_info)
     61		return;
     62
     63	if (cptvf->num_queues) {
     64		dev_dbg(&pdev->dev, "Cleaning VQ worker threads (%u)\n",
     65			cptvf->num_queues);
     66	}
     67
     68	for (i = 0; i < cptvf->num_queues; i++)
     69		tasklet_kill(&cwqe_info->vq_wqe[i].twork);
     70
     71	kfree_sensitive(cwqe_info);
     72	cptvf->wqe_info = NULL;
     73}
     74
     75static void free_pending_queues(struct otx_cpt_pending_qinfo *pqinfo)
     76{
     77	struct otx_cpt_pending_queue *queue;
     78	int i;
     79
     80	for_each_pending_queue(pqinfo, queue, i) {
     81		if (!queue->head)
     82			continue;
     83
     84		/* free single queue */
     85		kfree_sensitive((queue->head));
     86		queue->front = 0;
     87		queue->rear = 0;
     88		queue->qlen = 0;
     89	}
     90	pqinfo->num_queues = 0;
     91}
     92
     93static int alloc_pending_queues(struct otx_cpt_pending_qinfo *pqinfo, u32 qlen,
     94				u32 num_queues)
     95{
     96	struct otx_cpt_pending_queue *queue = NULL;
     97	int ret;
     98	u32 i;
     99
    100	pqinfo->num_queues = num_queues;
    101
    102	for_each_pending_queue(pqinfo, queue, i) {
    103		queue->head = kcalloc(qlen, sizeof(*queue->head), GFP_KERNEL);
    104		if (!queue->head) {
    105			ret = -ENOMEM;
    106			goto pending_qfail;
    107		}
    108
    109		queue->pending_count = 0;
    110		queue->front = 0;
    111		queue->rear = 0;
    112		queue->qlen = qlen;
    113
    114		/* init queue spin lock */
    115		spin_lock_init(&queue->lock);
    116	}
    117	return 0;
    118
    119pending_qfail:
    120	free_pending_queues(pqinfo);
    121
    122	return ret;
    123}
    124
    125static int init_pending_queues(struct otx_cptvf *cptvf, u32 qlen,
    126			       u32 num_queues)
    127{
    128	struct pci_dev *pdev = cptvf->pdev;
    129	int ret;
    130
    131	if (!num_queues)
    132		return 0;
    133
    134	ret = alloc_pending_queues(&cptvf->pqinfo, qlen, num_queues);
    135	if (ret) {
    136		dev_err(&pdev->dev, "Failed to setup pending queues (%u)\n",
    137			num_queues);
    138		return ret;
    139	}
    140	return 0;
    141}
    142
    143static void cleanup_pending_queues(struct otx_cptvf *cptvf)
    144{
    145	struct pci_dev *pdev = cptvf->pdev;
    146
    147	if (!cptvf->num_queues)
    148		return;
    149
    150	dev_dbg(&pdev->dev, "Cleaning VQ pending queue (%u)\n",
    151		cptvf->num_queues);
    152	free_pending_queues(&cptvf->pqinfo);
    153}
    154
    155static void free_command_queues(struct otx_cptvf *cptvf,
    156				struct otx_cpt_cmd_qinfo *cqinfo)
    157{
    158	struct otx_cpt_cmd_queue *queue = NULL;
    159	struct otx_cpt_cmd_chunk *chunk = NULL;
    160	struct pci_dev *pdev = cptvf->pdev;
    161	int i;
    162
    163	/* clean up for each queue */
    164	for (i = 0; i < cptvf->num_queues; i++) {
    165		queue = &cqinfo->queue[i];
    166
    167		while (!list_empty(&cqinfo->queue[i].chead)) {
    168			chunk = list_first_entry(&cqinfo->queue[i].chead,
    169					struct otx_cpt_cmd_chunk, nextchunk);
    170
    171			dma_free_coherent(&pdev->dev, chunk->size,
    172					  chunk->head,
    173					  chunk->dma_addr);
    174			chunk->head = NULL;
    175			chunk->dma_addr = 0;
    176			list_del(&chunk->nextchunk);
    177			kfree_sensitive(chunk);
    178		}
    179		queue->num_chunks = 0;
    180		queue->idx = 0;
    181
    182	}
    183}
    184
    185static int alloc_command_queues(struct otx_cptvf *cptvf,
    186				struct otx_cpt_cmd_qinfo *cqinfo,
    187				u32 qlen)
    188{
    189	struct otx_cpt_cmd_chunk *curr, *first, *last;
    190	struct otx_cpt_cmd_queue *queue = NULL;
    191	struct pci_dev *pdev = cptvf->pdev;
    192	size_t q_size, c_size, rem_q_size;
    193	u32 qcsize_bytes;
    194	int i;
    195
    196
    197	/* Qsize in dwords, needed for SADDR config, 1-next chunk pointer */
    198	cptvf->qsize = min(qlen, cqinfo->qchunksize) *
    199		       OTX_CPT_NEXT_CHUNK_PTR_SIZE + 1;
    200	/* Qsize in bytes to create space for alignment */
    201	q_size = qlen * OTX_CPT_INST_SIZE;
    202
    203	qcsize_bytes = cqinfo->qchunksize * OTX_CPT_INST_SIZE;
    204
    205	/* per queue initialization */
    206	for (i = 0; i < cptvf->num_queues; i++) {
    207		rem_q_size = q_size;
    208		first = NULL;
    209		last = NULL;
    210
    211		queue = &cqinfo->queue[i];
    212		INIT_LIST_HEAD(&queue->chead);
    213		do {
    214			curr = kzalloc(sizeof(*curr), GFP_KERNEL);
    215			if (!curr)
    216				goto cmd_qfail;
    217
    218			c_size = (rem_q_size > qcsize_bytes) ? qcsize_bytes :
    219					rem_q_size;
    220			curr->head = dma_alloc_coherent(&pdev->dev,
    221					   c_size + OTX_CPT_NEXT_CHUNK_PTR_SIZE,
    222					   &curr->dma_addr, GFP_KERNEL);
    223			if (!curr->head) {
    224				dev_err(&pdev->dev,
    225				"Command Q (%d) chunk (%d) allocation failed\n",
    226					i, queue->num_chunks);
    227				goto free_curr;
    228			}
    229			curr->size = c_size;
    230
    231			if (queue->num_chunks == 0) {
    232				first = curr;
    233				queue->base  = first;
    234			}
    235			list_add_tail(&curr->nextchunk,
    236				      &cqinfo->queue[i].chead);
    237
    238			queue->num_chunks++;
    239			rem_q_size -= c_size;
    240			if (last)
    241				*((u64 *)(&last->head[last->size])) =
    242					(u64)curr->dma_addr;
    243
    244			last = curr;
    245		} while (rem_q_size);
    246
    247		/*
    248		 * Make the queue circular, tie back last chunk entry to head
    249		 */
    250		curr = first;
    251		*((u64 *)(&last->head[last->size])) = (u64)curr->dma_addr;
    252		queue->qhead = curr;
    253	}
    254	return 0;
    255free_curr:
    256	kfree(curr);
    257cmd_qfail:
    258	free_command_queues(cptvf, cqinfo);
    259	return -ENOMEM;
    260}
    261
    262static int init_command_queues(struct otx_cptvf *cptvf, u32 qlen)
    263{
    264	struct pci_dev *pdev = cptvf->pdev;
    265	int ret;
    266
    267	/* setup command queues */
    268	ret = alloc_command_queues(cptvf, &cptvf->cqinfo, qlen);
    269	if (ret) {
    270		dev_err(&pdev->dev, "Failed to allocate command queues (%u)\n",
    271			cptvf->num_queues);
    272		return ret;
    273	}
    274	return ret;
    275}
    276
    277static void cleanup_command_queues(struct otx_cptvf *cptvf)
    278{
    279	struct pci_dev *pdev = cptvf->pdev;
    280
    281	if (!cptvf->num_queues)
    282		return;
    283
    284	dev_dbg(&pdev->dev, "Cleaning VQ command queue (%u)\n",
    285		cptvf->num_queues);
    286	free_command_queues(cptvf, &cptvf->cqinfo);
    287}
    288
    289static void cptvf_sw_cleanup(struct otx_cptvf *cptvf)
    290{
    291	cleanup_worker_threads(cptvf);
    292	cleanup_pending_queues(cptvf);
    293	cleanup_command_queues(cptvf);
    294}
    295
    296static int cptvf_sw_init(struct otx_cptvf *cptvf, u32 qlen, u32 num_queues)
    297{
    298	struct pci_dev *pdev = cptvf->pdev;
    299	u32 max_dev_queues = 0;
    300	int ret;
    301
    302	max_dev_queues = OTX_CPT_NUM_QS_PER_VF;
    303	/* possible cpus */
    304	num_queues = min_t(u32, num_queues, max_dev_queues);
    305	cptvf->num_queues = num_queues;
    306
    307	ret = init_command_queues(cptvf, qlen);
    308	if (ret) {
    309		dev_err(&pdev->dev, "Failed to setup command queues (%u)\n",
    310			num_queues);
    311		return ret;
    312	}
    313
    314	ret = init_pending_queues(cptvf, qlen, num_queues);
    315	if (ret) {
    316		dev_err(&pdev->dev, "Failed to setup pending queues (%u)\n",
    317			num_queues);
    318		goto setup_pqfail;
    319	}
    320
    321	/* Create worker threads for BH processing */
    322	ret = init_worker_threads(cptvf);
    323	if (ret) {
    324		dev_err(&pdev->dev, "Failed to setup worker threads\n");
    325		goto init_work_fail;
    326	}
    327	return 0;
    328
    329init_work_fail:
    330	cleanup_worker_threads(cptvf);
    331	cleanup_pending_queues(cptvf);
    332
    333setup_pqfail:
    334	cleanup_command_queues(cptvf);
    335
    336	return ret;
    337}
    338
    339static void cptvf_free_irq_affinity(struct otx_cptvf *cptvf, int vec)
    340{
    341	irq_set_affinity_hint(pci_irq_vector(cptvf->pdev, vec), NULL);
    342	free_cpumask_var(cptvf->affinity_mask[vec]);
    343}
    344
    345static void cptvf_write_vq_ctl(struct otx_cptvf *cptvf, bool val)
    346{
    347	union otx_cptx_vqx_ctl vqx_ctl;
    348
    349	vqx_ctl.u = readq(cptvf->reg_base + OTX_CPT_VQX_CTL(0));
    350	vqx_ctl.s.ena = val;
    351	writeq(vqx_ctl.u, cptvf->reg_base + OTX_CPT_VQX_CTL(0));
    352}
    353
    354void otx_cptvf_write_vq_doorbell(struct otx_cptvf *cptvf, u32 val)
    355{
    356	union otx_cptx_vqx_doorbell vqx_dbell;
    357
    358	vqx_dbell.u = readq(cptvf->reg_base + OTX_CPT_VQX_DOORBELL(0));
    359	vqx_dbell.s.dbell_cnt = val * 8; /* Num of Instructions * 8 words */
    360	writeq(vqx_dbell.u, cptvf->reg_base + OTX_CPT_VQX_DOORBELL(0));
    361}
    362
    363static void cptvf_write_vq_inprog(struct otx_cptvf *cptvf, u8 val)
    364{
    365	union otx_cptx_vqx_inprog vqx_inprg;
    366
    367	vqx_inprg.u = readq(cptvf->reg_base + OTX_CPT_VQX_INPROG(0));
    368	vqx_inprg.s.inflight = val;
    369	writeq(vqx_inprg.u, cptvf->reg_base + OTX_CPT_VQX_INPROG(0));
    370}
    371
    372static void cptvf_write_vq_done_numwait(struct otx_cptvf *cptvf, u32 val)
    373{
    374	union otx_cptx_vqx_done_wait vqx_dwait;
    375
    376	vqx_dwait.u = readq(cptvf->reg_base + OTX_CPT_VQX_DONE_WAIT(0));
    377	vqx_dwait.s.num_wait = val;
    378	writeq(vqx_dwait.u, cptvf->reg_base + OTX_CPT_VQX_DONE_WAIT(0));
    379}
    380
    381static u32 cptvf_read_vq_done_numwait(struct otx_cptvf *cptvf)
    382{
    383	union otx_cptx_vqx_done_wait vqx_dwait;
    384
    385	vqx_dwait.u = readq(cptvf->reg_base + OTX_CPT_VQX_DONE_WAIT(0));
    386	return vqx_dwait.s.num_wait;
    387}
    388
    389static void cptvf_write_vq_done_timewait(struct otx_cptvf *cptvf, u16 time)
    390{
    391	union otx_cptx_vqx_done_wait vqx_dwait;
    392
    393	vqx_dwait.u = readq(cptvf->reg_base + OTX_CPT_VQX_DONE_WAIT(0));
    394	vqx_dwait.s.time_wait = time;
    395	writeq(vqx_dwait.u, cptvf->reg_base + OTX_CPT_VQX_DONE_WAIT(0));
    396}
    397
    398
    399static u16 cptvf_read_vq_done_timewait(struct otx_cptvf *cptvf)
    400{
    401	union otx_cptx_vqx_done_wait vqx_dwait;
    402
    403	vqx_dwait.u = readq(cptvf->reg_base + OTX_CPT_VQX_DONE_WAIT(0));
    404	return vqx_dwait.s.time_wait;
    405}
    406
    407static void cptvf_enable_swerr_interrupts(struct otx_cptvf *cptvf)
    408{
    409	union otx_cptx_vqx_misc_ena_w1s vqx_misc_ena;
    410
    411	vqx_misc_ena.u = readq(cptvf->reg_base + OTX_CPT_VQX_MISC_ENA_W1S(0));
    412	/* Enable SWERR interrupts for the requested VF */
    413	vqx_misc_ena.s.swerr = 1;
    414	writeq(vqx_misc_ena.u, cptvf->reg_base + OTX_CPT_VQX_MISC_ENA_W1S(0));
    415}
    416
    417static void cptvf_enable_mbox_interrupts(struct otx_cptvf *cptvf)
    418{
    419	union otx_cptx_vqx_misc_ena_w1s vqx_misc_ena;
    420
    421	vqx_misc_ena.u = readq(cptvf->reg_base + OTX_CPT_VQX_MISC_ENA_W1S(0));
    422	/* Enable MBOX interrupt for the requested VF */
    423	vqx_misc_ena.s.mbox = 1;
    424	writeq(vqx_misc_ena.u, cptvf->reg_base + OTX_CPT_VQX_MISC_ENA_W1S(0));
    425}
    426
    427static void cptvf_enable_done_interrupts(struct otx_cptvf *cptvf)
    428{
    429	union otx_cptx_vqx_done_ena_w1s vqx_done_ena;
    430
    431	vqx_done_ena.u = readq(cptvf->reg_base + OTX_CPT_VQX_DONE_ENA_W1S(0));
    432	/* Enable DONE interrupt for the requested VF */
    433	vqx_done_ena.s.done = 1;
    434	writeq(vqx_done_ena.u, cptvf->reg_base + OTX_CPT_VQX_DONE_ENA_W1S(0));
    435}
    436
    437static void cptvf_clear_dovf_intr(struct otx_cptvf *cptvf)
    438{
    439	union otx_cptx_vqx_misc_int vqx_misc_int;
    440
    441	vqx_misc_int.u = readq(cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    442	/* W1C for the VF */
    443	vqx_misc_int.s.dovf = 1;
    444	writeq(vqx_misc_int.u, cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    445}
    446
    447static void cptvf_clear_irde_intr(struct otx_cptvf *cptvf)
    448{
    449	union otx_cptx_vqx_misc_int vqx_misc_int;
    450
    451	vqx_misc_int.u = readq(cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    452	/* W1C for the VF */
    453	vqx_misc_int.s.irde = 1;
    454	writeq(vqx_misc_int.u, cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    455}
    456
    457static void cptvf_clear_nwrp_intr(struct otx_cptvf *cptvf)
    458{
    459	union otx_cptx_vqx_misc_int vqx_misc_int;
    460
    461	vqx_misc_int.u = readq(cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    462	/* W1C for the VF */
    463	vqx_misc_int.s.nwrp = 1;
    464	writeq(vqx_misc_int.u, cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    465}
    466
    467static void cptvf_clear_mbox_intr(struct otx_cptvf *cptvf)
    468{
    469	union otx_cptx_vqx_misc_int vqx_misc_int;
    470
    471	vqx_misc_int.u = readq(cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    472	/* W1C for the VF */
    473	vqx_misc_int.s.mbox = 1;
    474	writeq(vqx_misc_int.u, cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    475}
    476
    477static void cptvf_clear_swerr_intr(struct otx_cptvf *cptvf)
    478{
    479	union otx_cptx_vqx_misc_int vqx_misc_int;
    480
    481	vqx_misc_int.u = readq(cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    482	/* W1C for the VF */
    483	vqx_misc_int.s.swerr = 1;
    484	writeq(vqx_misc_int.u, cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    485}
    486
    487static u64 cptvf_read_vf_misc_intr_status(struct otx_cptvf *cptvf)
    488{
    489	return readq(cptvf->reg_base + OTX_CPT_VQX_MISC_INT(0));
    490}
    491
    492static irqreturn_t cptvf_misc_intr_handler(int __always_unused irq,
    493					   void *arg)
    494{
    495	struct otx_cptvf *cptvf = arg;
    496	struct pci_dev *pdev = cptvf->pdev;
    497	u64 intr;
    498
    499	intr = cptvf_read_vf_misc_intr_status(cptvf);
    500	/* Check for MISC interrupt types */
    501	if (likely(intr & OTX_CPT_VF_INTR_MBOX_MASK)) {
    502		dev_dbg(&pdev->dev, "Mailbox interrupt 0x%llx on CPT VF %d\n",
    503			intr, cptvf->vfid);
    504		otx_cptvf_handle_mbox_intr(cptvf);
    505		cptvf_clear_mbox_intr(cptvf);
    506	} else if (unlikely(intr & OTX_CPT_VF_INTR_DOVF_MASK)) {
    507		cptvf_clear_dovf_intr(cptvf);
    508		/* Clear doorbell count */
    509		otx_cptvf_write_vq_doorbell(cptvf, 0);
    510		dev_err(&pdev->dev,
    511		"Doorbell overflow error interrupt 0x%llx on CPT VF %d\n",
    512			intr, cptvf->vfid);
    513	} else if (unlikely(intr & OTX_CPT_VF_INTR_IRDE_MASK)) {
    514		cptvf_clear_irde_intr(cptvf);
    515		dev_err(&pdev->dev,
    516		"Instruction NCB read error interrupt 0x%llx on CPT VF %d\n",
    517			intr, cptvf->vfid);
    518	} else if (unlikely(intr & OTX_CPT_VF_INTR_NWRP_MASK)) {
    519		cptvf_clear_nwrp_intr(cptvf);
    520		dev_err(&pdev->dev,
    521		"NCB response write error interrupt 0x%llx on CPT VF %d\n",
    522			intr, cptvf->vfid);
    523	} else if (unlikely(intr & OTX_CPT_VF_INTR_SERR_MASK)) {
    524		cptvf_clear_swerr_intr(cptvf);
    525		dev_err(&pdev->dev,
    526			"Software error interrupt 0x%llx on CPT VF %d\n",
    527			intr, cptvf->vfid);
    528	} else {
    529		dev_err(&pdev->dev, "Unhandled interrupt in OTX_CPT VF %d\n",
    530			cptvf->vfid);
    531	}
    532
    533	return IRQ_HANDLED;
    534}
    535
    536static inline struct otx_cptvf_wqe *get_cptvf_vq_wqe(struct otx_cptvf *cptvf,
    537						     int qno)
    538{
    539	struct otx_cptvf_wqe_info *nwqe_info;
    540
    541	if (unlikely(qno >= cptvf->num_queues))
    542		return NULL;
    543	nwqe_info = (struct otx_cptvf_wqe_info *)cptvf->wqe_info;
    544
    545	return &nwqe_info->vq_wqe[qno];
    546}
    547
    548static inline u32 cptvf_read_vq_done_count(struct otx_cptvf *cptvf)
    549{
    550	union otx_cptx_vqx_done vqx_done;
    551
    552	vqx_done.u = readq(cptvf->reg_base + OTX_CPT_VQX_DONE(0));
    553	return vqx_done.s.done;
    554}
    555
    556static inline void cptvf_write_vq_done_ack(struct otx_cptvf *cptvf,
    557					   u32 ackcnt)
    558{
    559	union otx_cptx_vqx_done_ack vqx_dack_cnt;
    560
    561	vqx_dack_cnt.u = readq(cptvf->reg_base + OTX_CPT_VQX_DONE_ACK(0));
    562	vqx_dack_cnt.s.done_ack = ackcnt;
    563	writeq(vqx_dack_cnt.u, cptvf->reg_base + OTX_CPT_VQX_DONE_ACK(0));
    564}
    565
    566static irqreturn_t cptvf_done_intr_handler(int __always_unused irq,
    567					   void *cptvf_dev)
    568{
    569	struct otx_cptvf *cptvf = (struct otx_cptvf *)cptvf_dev;
    570	struct pci_dev *pdev = cptvf->pdev;
    571	/* Read the number of completions */
    572	u32 intr = cptvf_read_vq_done_count(cptvf);
    573
    574	if (intr) {
    575		struct otx_cptvf_wqe *wqe;
    576
    577		/*
    578		 * Acknowledge the number of scheduled completions for
    579		 * processing
    580		 */
    581		cptvf_write_vq_done_ack(cptvf, intr);
    582		wqe = get_cptvf_vq_wqe(cptvf, 0);
    583		if (unlikely(!wqe)) {
    584			dev_err(&pdev->dev, "No work to schedule for VF (%d)\n",
    585				cptvf->vfid);
    586			return IRQ_NONE;
    587		}
    588		tasklet_hi_schedule(&wqe->twork);
    589	}
    590
    591	return IRQ_HANDLED;
    592}
    593
    594static void cptvf_set_irq_affinity(struct otx_cptvf *cptvf, int vec)
    595{
    596	struct pci_dev *pdev = cptvf->pdev;
    597	int cpu;
    598
    599	if (!zalloc_cpumask_var(&cptvf->affinity_mask[vec],
    600				GFP_KERNEL)) {
    601		dev_err(&pdev->dev,
    602			"Allocation failed for affinity_mask for VF %d\n",
    603			cptvf->vfid);
    604		return;
    605	}
    606
    607	cpu = cptvf->vfid % num_online_cpus();
    608	cpumask_set_cpu(cpumask_local_spread(cpu, cptvf->node),
    609			cptvf->affinity_mask[vec]);
    610	irq_set_affinity_hint(pci_irq_vector(pdev, vec),
    611			      cptvf->affinity_mask[vec]);
    612}
    613
    614static void cptvf_write_vq_saddr(struct otx_cptvf *cptvf, u64 val)
    615{
    616	union otx_cptx_vqx_saddr vqx_saddr;
    617
    618	vqx_saddr.u = val;
    619	writeq(vqx_saddr.u, cptvf->reg_base + OTX_CPT_VQX_SADDR(0));
    620}
    621
    622static void cptvf_device_init(struct otx_cptvf *cptvf)
    623{
    624	u64 base_addr = 0;
    625
    626	/* Disable the VQ */
    627	cptvf_write_vq_ctl(cptvf, 0);
    628	/* Reset the doorbell */
    629	otx_cptvf_write_vq_doorbell(cptvf, 0);
    630	/* Clear inflight */
    631	cptvf_write_vq_inprog(cptvf, 0);
    632	/* Write VQ SADDR */
    633	base_addr = (u64)(cptvf->cqinfo.queue[0].qhead->dma_addr);
    634	cptvf_write_vq_saddr(cptvf, base_addr);
    635	/* Configure timerhold / coalescence */
    636	cptvf_write_vq_done_timewait(cptvf, OTX_CPT_TIMER_HOLD);
    637	cptvf_write_vq_done_numwait(cptvf, OTX_CPT_COUNT_HOLD);
    638	/* Enable the VQ */
    639	cptvf_write_vq_ctl(cptvf, 1);
    640	/* Flag the VF ready */
    641	cptvf->flags |= OTX_CPT_FLAG_DEVICE_READY;
    642}
    643
    644static ssize_t vf_type_show(struct device *dev,
    645			    struct device_attribute *attr,
    646			    char *buf)
    647{
    648	struct otx_cptvf *cptvf = dev_get_drvdata(dev);
    649	char *msg;
    650
    651	switch (cptvf->vftype) {
    652	case OTX_CPT_AE_TYPES:
    653		msg = "AE";
    654		break;
    655
    656	case OTX_CPT_SE_TYPES:
    657		msg = "SE";
    658		break;
    659
    660	default:
    661		msg = "Invalid";
    662	}
    663
    664	return scnprintf(buf, PAGE_SIZE, "%s\n", msg);
    665}
    666
    667static ssize_t vf_engine_group_show(struct device *dev,
    668				    struct device_attribute *attr,
    669				    char *buf)
    670{
    671	struct otx_cptvf *cptvf = dev_get_drvdata(dev);
    672
    673	return scnprintf(buf, PAGE_SIZE, "%d\n", cptvf->vfgrp);
    674}
    675
    676static ssize_t vf_engine_group_store(struct device *dev,
    677				     struct device_attribute *attr,
    678				     const char *buf, size_t count)
    679{
    680	struct otx_cptvf *cptvf = dev_get_drvdata(dev);
    681	int val, ret;
    682
    683	ret = kstrtoint(buf, 10, &val);
    684	if (ret)
    685		return ret;
    686
    687	if (val < 0)
    688		return -EINVAL;
    689
    690	if (val >= OTX_CPT_MAX_ENGINE_GROUPS) {
    691		dev_err(dev, "Engine group >= than max available groups %d\n",
    692			OTX_CPT_MAX_ENGINE_GROUPS);
    693		return -EINVAL;
    694	}
    695
    696	ret = otx_cptvf_send_vf_to_grp_msg(cptvf, val);
    697	if (ret)
    698		return ret;
    699
    700	return count;
    701}
    702
    703static ssize_t vf_coalesc_time_wait_show(struct device *dev,
    704					 struct device_attribute *attr,
    705					 char *buf)
    706{
    707	struct otx_cptvf *cptvf = dev_get_drvdata(dev);
    708
    709	return scnprintf(buf, PAGE_SIZE, "%d\n",
    710			 cptvf_read_vq_done_timewait(cptvf));
    711}
    712
    713static ssize_t vf_coalesc_num_wait_show(struct device *dev,
    714					struct device_attribute *attr,
    715					char *buf)
    716{
    717	struct otx_cptvf *cptvf = dev_get_drvdata(dev);
    718
    719	return scnprintf(buf, PAGE_SIZE, "%d\n",
    720			 cptvf_read_vq_done_numwait(cptvf));
    721}
    722
    723static ssize_t vf_coalesc_time_wait_store(struct device *dev,
    724					  struct device_attribute *attr,
    725					  const char *buf, size_t count)
    726{
    727	struct otx_cptvf *cptvf = dev_get_drvdata(dev);
    728	long val;
    729	int ret;
    730
    731	ret = kstrtol(buf, 10, &val);
    732	if (ret != 0)
    733		return ret;
    734
    735	if (val < OTX_CPT_COALESC_MIN_TIME_WAIT ||
    736	    val > OTX_CPT_COALESC_MAX_TIME_WAIT)
    737		return -EINVAL;
    738
    739	cptvf_write_vq_done_timewait(cptvf, val);
    740	return count;
    741}
    742
    743static ssize_t vf_coalesc_num_wait_store(struct device *dev,
    744					 struct device_attribute *attr,
    745					 const char *buf, size_t count)
    746{
    747	struct otx_cptvf *cptvf = dev_get_drvdata(dev);
    748	long val;
    749	int ret;
    750
    751	ret = kstrtol(buf, 10, &val);
    752	if (ret != 0)
    753		return ret;
    754
    755	if (val < OTX_CPT_COALESC_MIN_NUM_WAIT ||
    756	    val > OTX_CPT_COALESC_MAX_NUM_WAIT)
    757		return -EINVAL;
    758
    759	cptvf_write_vq_done_numwait(cptvf, val);
    760	return count;
    761}
    762
    763static DEVICE_ATTR_RO(vf_type);
    764static DEVICE_ATTR_RW(vf_engine_group);
    765static DEVICE_ATTR_RW(vf_coalesc_time_wait);
    766static DEVICE_ATTR_RW(vf_coalesc_num_wait);
    767
    768static struct attribute *otx_cptvf_attrs[] = {
    769	&dev_attr_vf_type.attr,
    770	&dev_attr_vf_engine_group.attr,
    771	&dev_attr_vf_coalesc_time_wait.attr,
    772	&dev_attr_vf_coalesc_num_wait.attr,
    773	NULL
    774};
    775
    776static const struct attribute_group otx_cptvf_sysfs_group = {
    777	.attrs = otx_cptvf_attrs,
    778};
    779
    780static int otx_cptvf_probe(struct pci_dev *pdev,
    781			   const struct pci_device_id *ent)
    782{
    783	struct device *dev = &pdev->dev;
    784	struct otx_cptvf *cptvf;
    785	int err;
    786
    787	cptvf = devm_kzalloc(dev, sizeof(*cptvf), GFP_KERNEL);
    788	if (!cptvf)
    789		return -ENOMEM;
    790
    791	pci_set_drvdata(pdev, cptvf);
    792	cptvf->pdev = pdev;
    793
    794	err = pci_enable_device(pdev);
    795	if (err) {
    796		dev_err(dev, "Failed to enable PCI device\n");
    797		goto clear_drvdata;
    798	}
    799	err = pci_request_regions(pdev, DRV_NAME);
    800	if (err) {
    801		dev_err(dev, "PCI request regions failed 0x%x\n", err);
    802		goto disable_device;
    803	}
    804	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(48));
    805	if (err) {
    806		dev_err(dev, "Unable to get usable 48-bit DMA configuration\n");
    807		goto release_regions;
    808	}
    809
    810	/* MAP PF's configuration registers */
    811	cptvf->reg_base = pci_iomap(pdev, OTX_CPT_VF_PCI_CFG_BAR, 0);
    812	if (!cptvf->reg_base) {
    813		dev_err(dev, "Cannot map config register space, aborting\n");
    814		err = -ENOMEM;
    815		goto release_regions;
    816	}
    817
    818	cptvf->node = dev_to_node(&pdev->dev);
    819	err = pci_alloc_irq_vectors(pdev, OTX_CPT_VF_MSIX_VECTORS,
    820				    OTX_CPT_VF_MSIX_VECTORS, PCI_IRQ_MSIX);
    821	if (err < 0) {
    822		dev_err(dev, "Request for #%d msix vectors failed\n",
    823			OTX_CPT_VF_MSIX_VECTORS);
    824		goto unmap_region;
    825	}
    826
    827	err = request_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_MISC),
    828			  cptvf_misc_intr_handler, 0, "CPT VF misc intr",
    829			  cptvf);
    830	if (err) {
    831		dev_err(dev, "Failed to request misc irq\n");
    832		goto free_vectors;
    833	}
    834
    835	/* Enable mailbox interrupt */
    836	cptvf_enable_mbox_interrupts(cptvf);
    837	cptvf_enable_swerr_interrupts(cptvf);
    838
    839	/* Check cpt pf status, gets chip ID / device Id from PF if ready */
    840	err = otx_cptvf_check_pf_ready(cptvf);
    841	if (err)
    842		goto free_misc_irq;
    843
    844	/* CPT VF software resources initialization */
    845	cptvf->cqinfo.qchunksize = OTX_CPT_CMD_QCHUNK_SIZE;
    846	err = cptvf_sw_init(cptvf, OTX_CPT_CMD_QLEN, OTX_CPT_NUM_QS_PER_VF);
    847	if (err) {
    848		dev_err(dev, "cptvf_sw_init() failed\n");
    849		goto free_misc_irq;
    850	}
    851	/* Convey VQ LEN to PF */
    852	err = otx_cptvf_send_vq_size_msg(cptvf);
    853	if (err)
    854		goto sw_cleanup;
    855
    856	/* CPT VF device initialization */
    857	cptvf_device_init(cptvf);
    858	/* Send msg to PF to assign currnet Q to required group */
    859	err = otx_cptvf_send_vf_to_grp_msg(cptvf, cptvf->vfgrp);
    860	if (err)
    861		goto sw_cleanup;
    862
    863	cptvf->priority = 1;
    864	err = otx_cptvf_send_vf_priority_msg(cptvf);
    865	if (err)
    866		goto sw_cleanup;
    867
    868	err = request_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_DONE),
    869			  cptvf_done_intr_handler, 0, "CPT VF done intr",
    870			  cptvf);
    871	if (err) {
    872		dev_err(dev, "Failed to request done irq\n");
    873		goto free_done_irq;
    874	}
    875
    876	/* Enable done interrupt */
    877	cptvf_enable_done_interrupts(cptvf);
    878
    879	/* Set irq affinity masks */
    880	cptvf_set_irq_affinity(cptvf, CPT_VF_INT_VEC_E_MISC);
    881	cptvf_set_irq_affinity(cptvf, CPT_VF_INT_VEC_E_DONE);
    882
    883	err = otx_cptvf_send_vf_up(cptvf);
    884	if (err)
    885		goto free_irq_affinity;
    886
    887	/* Initialize algorithms and set ops */
    888	err = otx_cpt_crypto_init(pdev, THIS_MODULE,
    889		    cptvf->vftype == OTX_CPT_SE_TYPES ? OTX_CPT_SE : OTX_CPT_AE,
    890		    cptvf->vftype, 1, cptvf->num_vfs);
    891	if (err) {
    892		dev_err(dev, "Failed to register crypto algs\n");
    893		goto free_irq_affinity;
    894	}
    895
    896	err = sysfs_create_group(&dev->kobj, &otx_cptvf_sysfs_group);
    897	if (err) {
    898		dev_err(dev, "Creating sysfs entries failed\n");
    899		goto crypto_exit;
    900	}
    901
    902	return 0;
    903
    904crypto_exit:
    905	otx_cpt_crypto_exit(pdev, THIS_MODULE, cptvf->vftype);
    906free_irq_affinity:
    907	cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_DONE);
    908	cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_MISC);
    909free_done_irq:
    910	free_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_DONE), cptvf);
    911sw_cleanup:
    912	cptvf_sw_cleanup(cptvf);
    913free_misc_irq:
    914	free_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_MISC), cptvf);
    915free_vectors:
    916	pci_free_irq_vectors(cptvf->pdev);
    917unmap_region:
    918	pci_iounmap(pdev, cptvf->reg_base);
    919release_regions:
    920	pci_release_regions(pdev);
    921disable_device:
    922	pci_disable_device(pdev);
    923clear_drvdata:
    924	pci_set_drvdata(pdev, NULL);
    925
    926	return err;
    927}
    928
    929static void otx_cptvf_remove(struct pci_dev *pdev)
    930{
    931	struct otx_cptvf *cptvf = pci_get_drvdata(pdev);
    932
    933	if (!cptvf) {
    934		dev_err(&pdev->dev, "Invalid CPT-VF device\n");
    935		return;
    936	}
    937
    938	/* Convey DOWN to PF */
    939	if (otx_cptvf_send_vf_down(cptvf)) {
    940		dev_err(&pdev->dev, "PF not responding to DOWN msg\n");
    941	} else {
    942		sysfs_remove_group(&pdev->dev.kobj, &otx_cptvf_sysfs_group);
    943		otx_cpt_crypto_exit(pdev, THIS_MODULE, cptvf->vftype);
    944		cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_DONE);
    945		cptvf_free_irq_affinity(cptvf, CPT_VF_INT_VEC_E_MISC);
    946		free_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_DONE), cptvf);
    947		free_irq(pci_irq_vector(pdev, CPT_VF_INT_VEC_E_MISC), cptvf);
    948		cptvf_sw_cleanup(cptvf);
    949		pci_free_irq_vectors(cptvf->pdev);
    950		pci_iounmap(pdev, cptvf->reg_base);
    951		pci_release_regions(pdev);
    952		pci_disable_device(pdev);
    953		pci_set_drvdata(pdev, NULL);
    954	}
    955}
    956
    957/* Supported devices */
    958static const struct pci_device_id otx_cptvf_id_table[] = {
    959	{PCI_VDEVICE(CAVIUM, OTX_CPT_PCI_VF_DEVICE_ID), 0},
    960	{ 0, }  /* end of table */
    961};
    962
    963static struct pci_driver otx_cptvf_pci_driver = {
    964	.name = DRV_NAME,
    965	.id_table = otx_cptvf_id_table,
    966	.probe = otx_cptvf_probe,
    967	.remove = otx_cptvf_remove,
    968};
    969
    970module_pci_driver(otx_cptvf_pci_driver);
    971
    972MODULE_AUTHOR("Marvell International Ltd.");
    973MODULE_DESCRIPTION("Marvell OcteonTX CPT Virtual Function Driver");
    974MODULE_LICENSE("GPL v2");
    975MODULE_VERSION(DRV_VERSION);
    976MODULE_DEVICE_TABLE(pci, otx_cptvf_id_table);