17a37245eSSunil Goutham // SPDX-License-Identifier: GPL-2.0
27a37245eSSunil Goutham /* Marvell OcteonTx2 RVU Admin Function driver
37a37245eSSunil Goutham  *
47a37245eSSunil Goutham  * Copyright (C) 2018 Marvell International Ltd.
57a37245eSSunil Goutham  *
67a37245eSSunil Goutham  * This program is free software; you can redistribute it and/or modify
77a37245eSSunil Goutham  * it under the terms of the GNU General Public License version 2 as
87a37245eSSunil Goutham  * published by the Free Software Foundation.
97a37245eSSunil Goutham  */
107a37245eSSunil Goutham 
117a37245eSSunil Goutham #include <linux/module.h>
127a37245eSSunil Goutham #include <linux/pci.h>
137a37245eSSunil Goutham 
147a37245eSSunil Goutham #include "rvu_struct.h"
157a37245eSSunil Goutham #include "rvu_reg.h"
167a37245eSSunil Goutham #include "rvu.h"
177a37245eSSunil Goutham 
184a3581cdSSunil Goutham static int npa_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,
194a3581cdSSunil Goutham 			       struct npa_aq_inst_s *inst)
204a3581cdSSunil Goutham {
214a3581cdSSunil Goutham 	struct admin_queue *aq = block->aq;
224a3581cdSSunil Goutham 	struct npa_aq_res_s *result;
234a3581cdSSunil Goutham 	int timeout = 1000;
244a3581cdSSunil Goutham 	u64 reg, head;
254a3581cdSSunil Goutham 
264a3581cdSSunil Goutham 	result = (struct npa_aq_res_s *)aq->res->base;
274a3581cdSSunil Goutham 
284a3581cdSSunil Goutham 	/* Get current head pointer where to append this instruction */
294a3581cdSSunil Goutham 	reg = rvu_read64(rvu, block->addr, NPA_AF_AQ_STATUS);
304a3581cdSSunil Goutham 	head = (reg >> 4) & AQ_PTR_MASK;
314a3581cdSSunil Goutham 
324a3581cdSSunil Goutham 	memcpy((void *)(aq->inst->base + (head * aq->inst->entry_sz)),
334a3581cdSSunil Goutham 	       (void *)inst, aq->inst->entry_sz);
344a3581cdSSunil Goutham 	memset(result, 0, sizeof(*result));
354a3581cdSSunil Goutham 	/* sync into memory */
364a3581cdSSunil Goutham 	wmb();
374a3581cdSSunil Goutham 
384a3581cdSSunil Goutham 	/* Ring the doorbell and wait for result */
394a3581cdSSunil Goutham 	rvu_write64(rvu, block->addr, NPA_AF_AQ_DOOR, 1);
404a3581cdSSunil Goutham 	while (result->compcode == NPA_AQ_COMP_NOTDONE) {
414a3581cdSSunil Goutham 		cpu_relax();
424a3581cdSSunil Goutham 		udelay(1);
434a3581cdSSunil Goutham 		timeout--;
444a3581cdSSunil Goutham 		if (!timeout)
454a3581cdSSunil Goutham 			return -EBUSY;
464a3581cdSSunil Goutham 	}
474a3581cdSSunil Goutham 
484a3581cdSSunil Goutham 	if (result->compcode != NPA_AQ_COMP_GOOD)
494a3581cdSSunil Goutham 		/* TODO: Replace this with some error code */
504a3581cdSSunil Goutham 		return -EBUSY;
514a3581cdSSunil Goutham 
524a3581cdSSunil Goutham 	return 0;
534a3581cdSSunil Goutham }
544a3581cdSSunil Goutham 
558756828aSChristina Jacob int rvu_npa_aq_enq_inst(struct rvu *rvu, struct npa_aq_enq_req *req,
564a3581cdSSunil Goutham 			struct npa_aq_enq_rsp *rsp)
574a3581cdSSunil Goutham {
584a3581cdSSunil Goutham 	struct rvu_hwinfo *hw = rvu->hw;
594a3581cdSSunil Goutham 	u16 pcifunc = req->hdr.pcifunc;
604a3581cdSSunil Goutham 	int blkaddr, npalf, rc = 0;
614a3581cdSSunil Goutham 	struct npa_aq_inst_s inst;
624a3581cdSSunil Goutham 	struct rvu_block *block;
634a3581cdSSunil Goutham 	struct admin_queue *aq;
644a3581cdSSunil Goutham 	struct rvu_pfvf *pfvf;
654a3581cdSSunil Goutham 	void *ctx, *mask;
6657856ddeSGeetha sowjanya 	bool ena;
674a3581cdSSunil Goutham 
684a3581cdSSunil Goutham 	pfvf = rvu_get_pfvf(rvu, pcifunc);
694a3581cdSSunil Goutham 	if (!pfvf->aura_ctx || req->aura_id >= pfvf->aura_ctx->qsize)
704a3581cdSSunil Goutham 		return NPA_AF_ERR_AQ_ENQUEUE;
714a3581cdSSunil Goutham 
724a3581cdSSunil Goutham 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, pcifunc);
734a3581cdSSunil Goutham 	if (!pfvf->npalf || blkaddr < 0)
744a3581cdSSunil Goutham 		return NPA_AF_ERR_AF_LF_INVALID;
754a3581cdSSunil Goutham 
764a3581cdSSunil Goutham 	block = &hw->block[blkaddr];
774a3581cdSSunil Goutham 	aq = block->aq;
784a3581cdSSunil Goutham 	if (!aq) {
794a3581cdSSunil Goutham 		dev_warn(rvu->dev, "%s: NPA AQ not initialized\n", __func__);
804a3581cdSSunil Goutham 		return NPA_AF_ERR_AQ_ENQUEUE;
814a3581cdSSunil Goutham 	}
824a3581cdSSunil Goutham 
834a3581cdSSunil Goutham 	npalf = rvu_get_lf(rvu, block, pcifunc, 0);
844a3581cdSSunil Goutham 	if (npalf < 0)
854a3581cdSSunil Goutham 		return NPA_AF_ERR_AF_LF_INVALID;
864a3581cdSSunil Goutham 
874a3581cdSSunil Goutham 	memset(&inst, 0, sizeof(struct npa_aq_inst_s));
884a3581cdSSunil Goutham 	inst.cindex = req->aura_id;
894a3581cdSSunil Goutham 	inst.lf = npalf;
904a3581cdSSunil Goutham 	inst.ctype = req->ctype;
914a3581cdSSunil Goutham 	inst.op = req->op;
924a3581cdSSunil Goutham 	/* Currently we are not supporting enqueuing multiple instructions,
934a3581cdSSunil Goutham 	 * so always choose first entry in result memory.
944a3581cdSSunil Goutham 	 */
954a3581cdSSunil Goutham 	inst.res_addr = (u64)aq->res->iova;
964a3581cdSSunil Goutham 
9727150bc4SGeetha sowjanya 	/* Hardware uses same aq->res->base for updating result of
9827150bc4SGeetha sowjanya 	 * previous instruction hence wait here till it is done.
9927150bc4SGeetha sowjanya 	 */
10027150bc4SGeetha sowjanya 	spin_lock(&aq->lock);
10127150bc4SGeetha sowjanya 
1024a3581cdSSunil Goutham 	/* Clean result + context memory */
1034a3581cdSSunil Goutham 	memset(aq->res->base, 0, aq->res->entry_sz);
1044a3581cdSSunil Goutham 	/* Context needs to be written at RES_ADDR + 128 */
1054a3581cdSSunil Goutham 	ctx = aq->res->base + 128;
1064a3581cdSSunil Goutham 	/* Mask needs to be written at RES_ADDR + 256 */
1074a3581cdSSunil Goutham 	mask = aq->res->base + 256;
1084a3581cdSSunil Goutham 
1094a3581cdSSunil Goutham 	switch (req->op) {
1104a3581cdSSunil Goutham 	case NPA_AQ_INSTOP_WRITE:
1114a3581cdSSunil Goutham 		/* Copy context and write mask */
1124a3581cdSSunil Goutham 		if (req->ctype == NPA_AQ_CTYPE_AURA) {
1134a3581cdSSunil Goutham 			memcpy(mask, &req->aura_mask,
1144a3581cdSSunil Goutham 			       sizeof(struct npa_aura_s));
1154a3581cdSSunil Goutham 			memcpy(ctx, &req->aura, sizeof(struct npa_aura_s));
1164a3581cdSSunil Goutham 		} else {
1174a3581cdSSunil Goutham 			memcpy(mask, &req->pool_mask,
1184a3581cdSSunil Goutham 			       sizeof(struct npa_pool_s));
1194a3581cdSSunil Goutham 			memcpy(ctx, &req->pool, sizeof(struct npa_pool_s));
1204a3581cdSSunil Goutham 		}
1214a3581cdSSunil Goutham 		break;
1224a3581cdSSunil Goutham 	case NPA_AQ_INSTOP_INIT:
1234a3581cdSSunil Goutham 		if (req->ctype == NPA_AQ_CTYPE_AURA) {
1244a3581cdSSunil Goutham 			if (req->aura.pool_addr >= pfvf->pool_ctx->qsize) {
1254a3581cdSSunil Goutham 				rc = NPA_AF_ERR_AQ_FULL;
1264a3581cdSSunil Goutham 				break;
1274a3581cdSSunil Goutham 			}
1284a3581cdSSunil Goutham 			/* Set pool's context address */
1294a3581cdSSunil Goutham 			req->aura.pool_addr = pfvf->pool_ctx->iova +
1304a3581cdSSunil Goutham 			(req->aura.pool_addr * pfvf->pool_ctx->entry_sz);
1314a3581cdSSunil Goutham 			memcpy(ctx, &req->aura, sizeof(struct npa_aura_s));
1324a3581cdSSunil Goutham 		} else { /* POOL's context */
1334a3581cdSSunil Goutham 			memcpy(ctx, &req->pool, sizeof(struct npa_pool_s));
1344a3581cdSSunil Goutham 		}
1354a3581cdSSunil Goutham 		break;
1364a3581cdSSunil Goutham 	case NPA_AQ_INSTOP_NOP:
1374a3581cdSSunil Goutham 	case NPA_AQ_INSTOP_READ:
1384a3581cdSSunil Goutham 	case NPA_AQ_INSTOP_LOCK:
1394a3581cdSSunil Goutham 	case NPA_AQ_INSTOP_UNLOCK:
1404a3581cdSSunil Goutham 		break;
1414a3581cdSSunil Goutham 	default:
1424a3581cdSSunil Goutham 		rc = NPA_AF_ERR_AQ_FULL;
1434a3581cdSSunil Goutham 		break;
1444a3581cdSSunil Goutham 	}
1454a3581cdSSunil Goutham 
14627150bc4SGeetha sowjanya 	if (rc) {
14727150bc4SGeetha sowjanya 		spin_unlock(&aq->lock);
1484a3581cdSSunil Goutham 		return rc;
14927150bc4SGeetha sowjanya 	}
1504a3581cdSSunil Goutham 
1514a3581cdSSunil Goutham 	/* Submit the instruction to AQ */
1524a3581cdSSunil Goutham 	rc = npa_aq_enqueue_wait(rvu, block, &inst);
1534a3581cdSSunil Goutham 	if (rc) {
1544a3581cdSSunil Goutham 		spin_unlock(&aq->lock);
1554a3581cdSSunil Goutham 		return rc;
1564a3581cdSSunil Goutham 	}
1574a3581cdSSunil Goutham 
15857856ddeSGeetha sowjanya 	/* Set aura bitmap if aura hw context is enabled */
15957856ddeSGeetha sowjanya 	if (req->ctype == NPA_AQ_CTYPE_AURA) {
16057856ddeSGeetha sowjanya 		if (req->op == NPA_AQ_INSTOP_INIT && req->aura.ena)
16157856ddeSGeetha sowjanya 			__set_bit(req->aura_id, pfvf->aura_bmap);
16257856ddeSGeetha sowjanya 		if (req->op == NPA_AQ_INSTOP_WRITE) {
16357856ddeSGeetha sowjanya 			ena = (req->aura.ena & req->aura_mask.ena) |
16457856ddeSGeetha sowjanya 				(test_bit(req->aura_id, pfvf->aura_bmap) &
16557856ddeSGeetha sowjanya 				~req->aura_mask.ena);
16657856ddeSGeetha sowjanya 			if (ena)
16757856ddeSGeetha sowjanya 				__set_bit(req->aura_id, pfvf->aura_bmap);
16857856ddeSGeetha sowjanya 			else
16957856ddeSGeetha sowjanya 				__clear_bit(req->aura_id, pfvf->aura_bmap);
17057856ddeSGeetha sowjanya 		}
17157856ddeSGeetha sowjanya 	}
17257856ddeSGeetha sowjanya 
17357856ddeSGeetha sowjanya 	/* Set pool bitmap if pool hw context is enabled */
17457856ddeSGeetha sowjanya 	if (req->ctype == NPA_AQ_CTYPE_POOL) {
17557856ddeSGeetha sowjanya 		if (req->op == NPA_AQ_INSTOP_INIT && req->pool.ena)
17657856ddeSGeetha sowjanya 			__set_bit(req->aura_id, pfvf->pool_bmap);
17757856ddeSGeetha sowjanya 		if (req->op == NPA_AQ_INSTOP_WRITE) {
17857856ddeSGeetha sowjanya 			ena = (req->pool.ena & req->pool_mask.ena) |
17957856ddeSGeetha sowjanya 				(test_bit(req->aura_id, pfvf->pool_bmap) &
18057856ddeSGeetha sowjanya 				~req->pool_mask.ena);
18157856ddeSGeetha sowjanya 			if (ena)
18257856ddeSGeetha sowjanya 				__set_bit(req->aura_id, pfvf->pool_bmap);
18357856ddeSGeetha sowjanya 			else
18457856ddeSGeetha sowjanya 				__clear_bit(req->aura_id, pfvf->pool_bmap);
18557856ddeSGeetha sowjanya 		}
18657856ddeSGeetha sowjanya 	}
1874a3581cdSSunil Goutham 	spin_unlock(&aq->lock);
1884a3581cdSSunil Goutham 
1894a3581cdSSunil Goutham 	if (rsp) {
1904a3581cdSSunil Goutham 		/* Copy read context into mailbox */
1914a3581cdSSunil Goutham 		if (req->op == NPA_AQ_INSTOP_READ) {
1924a3581cdSSunil Goutham 			if (req->ctype == NPA_AQ_CTYPE_AURA)
1934a3581cdSSunil Goutham 				memcpy(&rsp->aura, ctx,
1944a3581cdSSunil Goutham 				       sizeof(struct npa_aura_s));
1954a3581cdSSunil Goutham 			else
1964a3581cdSSunil Goutham 				memcpy(&rsp->pool, ctx,
1974a3581cdSSunil Goutham 				       sizeof(struct npa_pool_s));
1984a3581cdSSunil Goutham 		}
1994a3581cdSSunil Goutham 	}
2004a3581cdSSunil Goutham 
2014a3581cdSSunil Goutham 	return 0;
2024a3581cdSSunil Goutham }
2034a3581cdSSunil Goutham 
20457856ddeSGeetha sowjanya static int npa_lf_hwctx_disable(struct rvu *rvu, struct hwctx_disable_req *req)
20557856ddeSGeetha sowjanya {
20657856ddeSGeetha sowjanya 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
20757856ddeSGeetha sowjanya 	struct npa_aq_enq_req aq_req;
20857856ddeSGeetha sowjanya 	unsigned long *bmap;
20957856ddeSGeetha sowjanya 	int id, cnt = 0;
21057856ddeSGeetha sowjanya 	int err = 0, rc;
21157856ddeSGeetha sowjanya 
21257856ddeSGeetha sowjanya 	if (!pfvf->pool_ctx || !pfvf->aura_ctx)
21357856ddeSGeetha sowjanya 		return NPA_AF_ERR_AQ_ENQUEUE;
21457856ddeSGeetha sowjanya 
21557856ddeSGeetha sowjanya 	memset(&aq_req, 0, sizeof(struct npa_aq_enq_req));
21657856ddeSGeetha sowjanya 	aq_req.hdr.pcifunc = req->hdr.pcifunc;
21757856ddeSGeetha sowjanya 
21857856ddeSGeetha sowjanya 	if (req->ctype == NPA_AQ_CTYPE_POOL) {
21957856ddeSGeetha sowjanya 		aq_req.pool.ena = 0;
22057856ddeSGeetha sowjanya 		aq_req.pool_mask.ena = 1;
22157856ddeSGeetha sowjanya 		cnt = pfvf->pool_ctx->qsize;
22257856ddeSGeetha sowjanya 		bmap = pfvf->pool_bmap;
22357856ddeSGeetha sowjanya 	} else if (req->ctype == NPA_AQ_CTYPE_AURA) {
22457856ddeSGeetha sowjanya 		aq_req.aura.ena = 0;
22557856ddeSGeetha sowjanya 		aq_req.aura_mask.ena = 1;
22627150bc4SGeetha sowjanya 		aq_req.aura.bp_ena = 0;
22727150bc4SGeetha sowjanya 		aq_req.aura_mask.bp_ena = 1;
22857856ddeSGeetha sowjanya 		cnt = pfvf->aura_ctx->qsize;
22957856ddeSGeetha sowjanya 		bmap = pfvf->aura_bmap;
23057856ddeSGeetha sowjanya 	}
23157856ddeSGeetha sowjanya 
23257856ddeSGeetha sowjanya 	aq_req.ctype = req->ctype;
23357856ddeSGeetha sowjanya 	aq_req.op = NPA_AQ_INSTOP_WRITE;
23457856ddeSGeetha sowjanya 
23557856ddeSGeetha sowjanya 	for (id = 0; id < cnt; id++) {
23657856ddeSGeetha sowjanya 		if (!test_bit(id, bmap))
23757856ddeSGeetha sowjanya 			continue;
23857856ddeSGeetha sowjanya 		aq_req.aura_id = id;
23957856ddeSGeetha sowjanya 		rc = rvu_npa_aq_enq_inst(rvu, &aq_req, NULL);
24057856ddeSGeetha sowjanya 		if (rc) {
24157856ddeSGeetha sowjanya 			err = rc;
24257856ddeSGeetha sowjanya 			dev_err(rvu->dev, "Failed to disable %s:%d context\n",
24357856ddeSGeetha sowjanya 				(req->ctype == NPA_AQ_CTYPE_AURA) ?
24457856ddeSGeetha sowjanya 				"Aura" : "Pool", id);
24557856ddeSGeetha sowjanya 		}
24657856ddeSGeetha sowjanya 	}
24757856ddeSGeetha sowjanya 
24857856ddeSGeetha sowjanya 	return err;
24957856ddeSGeetha sowjanya }
25057856ddeSGeetha sowjanya 
251a0291766SSunil Goutham #ifdef CONFIG_NDC_DIS_DYNAMIC_CACHING
252a0291766SSunil Goutham static int npa_lf_hwctx_lockdown(struct rvu *rvu, struct npa_aq_enq_req *req)
253a0291766SSunil Goutham {
254a0291766SSunil Goutham 	struct npa_aq_enq_req lock_ctx_req;
255a0291766SSunil Goutham 	int err;
256a0291766SSunil Goutham 
257a0291766SSunil Goutham 	if (req->op != NPA_AQ_INSTOP_INIT)
258a0291766SSunil Goutham 		return 0;
259a0291766SSunil Goutham 
260a0291766SSunil Goutham 	memset(&lock_ctx_req, 0, sizeof(struct npa_aq_enq_req));
261a0291766SSunil Goutham 	lock_ctx_req.hdr.pcifunc = req->hdr.pcifunc;
262a0291766SSunil Goutham 	lock_ctx_req.ctype = req->ctype;
263a0291766SSunil Goutham 	lock_ctx_req.op = NPA_AQ_INSTOP_LOCK;
264a0291766SSunil Goutham 	lock_ctx_req.aura_id = req->aura_id;
265a0291766SSunil Goutham 	err = rvu_npa_aq_enq_inst(rvu, &lock_ctx_req, NULL);
266a0291766SSunil Goutham 	if (err)
267a0291766SSunil Goutham 		dev_err(rvu->dev,
268a0291766SSunil Goutham 			"PFUNC 0x%x: Failed to lock NPA context %s:%d\n",
269a0291766SSunil Goutham 			req->hdr.pcifunc,
270a0291766SSunil Goutham 			(req->ctype == NPA_AQ_CTYPE_AURA) ?
271a0291766SSunil Goutham 			"Aura" : "Pool", req->aura_id);
272a0291766SSunil Goutham 	return err;
273a0291766SSunil Goutham }
274a0291766SSunil Goutham 
275a0291766SSunil Goutham int rvu_mbox_handler_npa_aq_enq(struct rvu *rvu,
276a0291766SSunil Goutham 				struct npa_aq_enq_req *req,
277a0291766SSunil Goutham 				struct npa_aq_enq_rsp *rsp)
278a0291766SSunil Goutham {
279a0291766SSunil Goutham 	int err;
280a0291766SSunil Goutham 
281a0291766SSunil Goutham 	err = rvu_npa_aq_enq_inst(rvu, req, rsp);
282a0291766SSunil Goutham 	if (!err)
283a0291766SSunil Goutham 		err = npa_lf_hwctx_lockdown(rvu, req);
284a0291766SSunil Goutham 	return err;
285a0291766SSunil Goutham }
286a0291766SSunil Goutham #else
287a0291766SSunil Goutham 
288eac66686SSunil Goutham int rvu_mbox_handler_npa_aq_enq(struct rvu *rvu,
2894a3581cdSSunil Goutham 				struct npa_aq_enq_req *req,
2904a3581cdSSunil Goutham 				struct npa_aq_enq_rsp *rsp)
2914a3581cdSSunil Goutham {
2924a3581cdSSunil Goutham 	return rvu_npa_aq_enq_inst(rvu, req, rsp);
2934a3581cdSSunil Goutham }
294a0291766SSunil Goutham #endif
2954a3581cdSSunil Goutham 
296eac66686SSunil Goutham int rvu_mbox_handler_npa_hwctx_disable(struct rvu *rvu,
29757856ddeSGeetha sowjanya 				       struct hwctx_disable_req *req,
29857856ddeSGeetha sowjanya 				       struct msg_rsp *rsp)
29957856ddeSGeetha sowjanya {
30057856ddeSGeetha sowjanya 	return npa_lf_hwctx_disable(rvu, req);
30157856ddeSGeetha sowjanya }
30257856ddeSGeetha sowjanya 
3033fa4c323SSunil Goutham static void npa_ctx_free(struct rvu *rvu, struct rvu_pfvf *pfvf)
3043fa4c323SSunil Goutham {
30557856ddeSGeetha sowjanya 	kfree(pfvf->aura_bmap);
30657856ddeSGeetha sowjanya 	pfvf->aura_bmap = NULL;
30757856ddeSGeetha sowjanya 
3083fa4c323SSunil Goutham 	qmem_free(rvu->dev, pfvf->aura_ctx);
3093fa4c323SSunil Goutham 	pfvf->aura_ctx = NULL;
3103fa4c323SSunil Goutham 
31157856ddeSGeetha sowjanya 	kfree(pfvf->pool_bmap);
31257856ddeSGeetha sowjanya 	pfvf->pool_bmap = NULL;
31357856ddeSGeetha sowjanya 
3143fa4c323SSunil Goutham 	qmem_free(rvu->dev, pfvf->pool_ctx);
3153fa4c323SSunil Goutham 	pfvf->pool_ctx = NULL;
3163fa4c323SSunil Goutham 
3173fa4c323SSunil Goutham 	qmem_free(rvu->dev, pfvf->npa_qints_ctx);
3183fa4c323SSunil Goutham 	pfvf->npa_qints_ctx = NULL;
3193fa4c323SSunil Goutham }
3203fa4c323SSunil Goutham 
321eac66686SSunil Goutham int rvu_mbox_handler_npa_lf_alloc(struct rvu *rvu,
3223fa4c323SSunil Goutham 				  struct npa_lf_alloc_req *req,
3233fa4c323SSunil Goutham 				  struct npa_lf_alloc_rsp *rsp)
3243fa4c323SSunil Goutham {
3253fa4c323SSunil Goutham 	int npalf, qints, hwctx_size, err, rc = 0;
3263fa4c323SSunil Goutham 	struct rvu_hwinfo *hw = rvu->hw;
3273fa4c323SSunil Goutham 	u16 pcifunc = req->hdr.pcifunc;
3283fa4c323SSunil Goutham 	struct rvu_block *block;
3293fa4c323SSunil Goutham 	struct rvu_pfvf *pfvf;
3303fa4c323SSunil Goutham 	u64 cfg, ctx_cfg;
3313fa4c323SSunil Goutham 	int blkaddr;
3323fa4c323SSunil Goutham 
3333fa4c323SSunil Goutham 	if (req->aura_sz > NPA_AURA_SZ_MAX ||
3343fa4c323SSunil Goutham 	    req->aura_sz == NPA_AURA_SZ_0 || !req->nr_pools)
3353fa4c323SSunil Goutham 		return NPA_AF_ERR_PARAM;
3363fa4c323SSunil Goutham 
337ee1e7591SGeetha sowjanya 	if (req->way_mask)
338ee1e7591SGeetha sowjanya 		req->way_mask &= 0xFFFF;
339ee1e7591SGeetha sowjanya 
3403fa4c323SSunil Goutham 	pfvf = rvu_get_pfvf(rvu, pcifunc);
3413fa4c323SSunil Goutham 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, pcifunc);
3423fa4c323SSunil Goutham 	if (!pfvf->npalf || blkaddr < 0)
3433fa4c323SSunil Goutham 		return NPA_AF_ERR_AF_LF_INVALID;
3443fa4c323SSunil Goutham 
3453fa4c323SSunil Goutham 	block = &hw->block[blkaddr];
3463fa4c323SSunil Goutham 	npalf = rvu_get_lf(rvu, block, pcifunc, 0);
3473fa4c323SSunil Goutham 	if (npalf < 0)
3483fa4c323SSunil Goutham 		return NPA_AF_ERR_AF_LF_INVALID;
3493fa4c323SSunil Goutham 
3503fa4c323SSunil Goutham 	/* Reset this NPA LF */
3513fa4c323SSunil Goutham 	err = rvu_lf_reset(rvu, block, npalf);
3523fa4c323SSunil Goutham 	if (err) {
3533fa4c323SSunil Goutham 		dev_err(rvu->dev, "Failed to reset NPALF%d\n", npalf);
3543fa4c323SSunil Goutham 		return NPA_AF_ERR_LF_RESET;
3553fa4c323SSunil Goutham 	}
3563fa4c323SSunil Goutham 
3573fa4c323SSunil Goutham 	ctx_cfg = rvu_read64(rvu, blkaddr, NPA_AF_CONST1);
3583fa4c323SSunil Goutham 
3593fa4c323SSunil Goutham 	/* Alloc memory for aura HW contexts */
3603fa4c323SSunil Goutham 	hwctx_size = 1UL << (ctx_cfg & 0xF);
3613fa4c323SSunil Goutham 	err = qmem_alloc(rvu->dev, &pfvf->aura_ctx,
3623fa4c323SSunil Goutham 			 NPA_AURA_COUNT(req->aura_sz), hwctx_size);
3633fa4c323SSunil Goutham 	if (err)
3643fa4c323SSunil Goutham 		goto free_mem;
3653fa4c323SSunil Goutham 
36657856ddeSGeetha sowjanya 	pfvf->aura_bmap = kcalloc(NPA_AURA_COUNT(req->aura_sz), sizeof(long),
36757856ddeSGeetha sowjanya 				  GFP_KERNEL);
36857856ddeSGeetha sowjanya 	if (!pfvf->aura_bmap)
36957856ddeSGeetha sowjanya 		goto free_mem;
37057856ddeSGeetha sowjanya 
3713fa4c323SSunil Goutham 	/* Alloc memory for pool HW contexts */
3723fa4c323SSunil Goutham 	hwctx_size = 1UL << ((ctx_cfg >> 4) & 0xF);
3733fa4c323SSunil Goutham 	err = qmem_alloc(rvu->dev, &pfvf->pool_ctx, req->nr_pools, hwctx_size);
3743fa4c323SSunil Goutham 	if (err)
3753fa4c323SSunil Goutham 		goto free_mem;
3763fa4c323SSunil Goutham 
37757856ddeSGeetha sowjanya 	pfvf->pool_bmap = kcalloc(NPA_AURA_COUNT(req->aura_sz), sizeof(long),
37857856ddeSGeetha sowjanya 				  GFP_KERNEL);
37957856ddeSGeetha sowjanya 	if (!pfvf->pool_bmap)
38057856ddeSGeetha sowjanya 		goto free_mem;
38157856ddeSGeetha sowjanya 
3823fa4c323SSunil Goutham 	/* Get no of queue interrupts supported */
3833fa4c323SSunil Goutham 	cfg = rvu_read64(rvu, blkaddr, NPA_AF_CONST);
3843fa4c323SSunil Goutham 	qints = (cfg >> 28) & 0xFFF;
3853fa4c323SSunil Goutham 
3863fa4c323SSunil Goutham 	/* Alloc memory for Qints HW contexts */
3873fa4c323SSunil Goutham 	hwctx_size = 1UL << ((ctx_cfg >> 8) & 0xF);
3883fa4c323SSunil Goutham 	err = qmem_alloc(rvu->dev, &pfvf->npa_qints_ctx, qints, hwctx_size);
3893fa4c323SSunil Goutham 	if (err)
3903fa4c323SSunil Goutham 		goto free_mem;
3913fa4c323SSunil Goutham 
3923fa4c323SSunil Goutham 	cfg = rvu_read64(rvu, blkaddr, NPA_AF_LFX_AURAS_CFG(npalf));
3933fa4c323SSunil Goutham 	/* Clear way partition mask and set aura offset to '0' */
3943fa4c323SSunil Goutham 	cfg &= ~(BIT_ULL(34) - 1);
3953fa4c323SSunil Goutham 	/* Set aura size & enable caching of contexts */
396ee1e7591SGeetha sowjanya 	cfg |= (req->aura_sz << 16) | BIT_ULL(34) | req->way_mask;
397ee1e7591SGeetha sowjanya 
3983fa4c323SSunil Goutham 	rvu_write64(rvu, blkaddr, NPA_AF_LFX_AURAS_CFG(npalf), cfg);
3993fa4c323SSunil Goutham 
4003fa4c323SSunil Goutham 	/* Configure aura HW context's base */
4013fa4c323SSunil Goutham 	rvu_write64(rvu, blkaddr, NPA_AF_LFX_LOC_AURAS_BASE(npalf),
4023fa4c323SSunil Goutham 		    (u64)pfvf->aura_ctx->iova);
4033fa4c323SSunil Goutham 
4043fa4c323SSunil Goutham 	/* Enable caching of qints hw context */
405ee1e7591SGeetha sowjanya 	rvu_write64(rvu, blkaddr, NPA_AF_LFX_QINTS_CFG(npalf),
406ee1e7591SGeetha sowjanya 		    BIT_ULL(36) | req->way_mask << 20);
4073fa4c323SSunil Goutham 	rvu_write64(rvu, blkaddr, NPA_AF_LFX_QINTS_BASE(npalf),
4083fa4c323SSunil Goutham 		    (u64)pfvf->npa_qints_ctx->iova);
4093fa4c323SSunil Goutham 
4103fa4c323SSunil Goutham 	goto exit;
4113fa4c323SSunil Goutham 
4123fa4c323SSunil Goutham free_mem:
4133fa4c323SSunil Goutham 	npa_ctx_free(rvu, pfvf);
4143fa4c323SSunil Goutham 	rc = -ENOMEM;
4153fa4c323SSunil Goutham 
4163fa4c323SSunil Goutham exit:
4173fa4c323SSunil Goutham 	/* set stack page info */
4183fa4c323SSunil Goutham 	cfg = rvu_read64(rvu, blkaddr, NPA_AF_CONST);
4193fa4c323SSunil Goutham 	rsp->stack_pg_ptrs = (cfg >> 8) & 0xFF;
4203fa4c323SSunil Goutham 	rsp->stack_pg_bytes = cfg & 0xFF;
4213fa4c323SSunil Goutham 	rsp->qints = (cfg >> 28) & 0xFFF;
422*ae2c341eSGeetha sowjanya 	if (!is_rvu_otx2(rvu)) {
423*ae2c341eSGeetha sowjanya 		cfg = rvu_read64(rvu, block->addr, NPA_AF_BATCH_CTL);
424*ae2c341eSGeetha sowjanya 		rsp->cache_lines = (cfg >> 1) & 0x3F;
425*ae2c341eSGeetha sowjanya 	}
4263fa4c323SSunil Goutham 	return rc;
4273fa4c323SSunil Goutham }
4283fa4c323SSunil Goutham 
429eac66686SSunil Goutham int rvu_mbox_handler_npa_lf_free(struct rvu *rvu, struct msg_req *req,
4303fa4c323SSunil Goutham 				 struct msg_rsp *rsp)
4313fa4c323SSunil Goutham {
4323fa4c323SSunil Goutham 	struct rvu_hwinfo *hw = rvu->hw;
4333fa4c323SSunil Goutham 	u16 pcifunc = req->hdr.pcifunc;
4343fa4c323SSunil Goutham 	struct rvu_block *block;
4353fa4c323SSunil Goutham 	struct rvu_pfvf *pfvf;
4363fa4c323SSunil Goutham 	int npalf, err;
4373fa4c323SSunil Goutham 	int blkaddr;
4383fa4c323SSunil Goutham 
4393fa4c323SSunil Goutham 	pfvf = rvu_get_pfvf(rvu, pcifunc);
4403fa4c323SSunil Goutham 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, pcifunc);
4413fa4c323SSunil Goutham 	if (!pfvf->npalf || blkaddr < 0)
4423fa4c323SSunil Goutham 		return NPA_AF_ERR_AF_LF_INVALID;
4433fa4c323SSunil Goutham 
4443fa4c323SSunil Goutham 	block = &hw->block[blkaddr];
4453fa4c323SSunil Goutham 	npalf = rvu_get_lf(rvu, block, pcifunc, 0);
4463fa4c323SSunil Goutham 	if (npalf < 0)
4473fa4c323SSunil Goutham 		return NPA_AF_ERR_AF_LF_INVALID;
4483fa4c323SSunil Goutham 
4493fa4c323SSunil Goutham 	/* Reset this NPA LF */
4503fa4c323SSunil Goutham 	err = rvu_lf_reset(rvu, block, npalf);
4513fa4c323SSunil Goutham 	if (err) {
4523fa4c323SSunil Goutham 		dev_err(rvu->dev, "Failed to reset NPALF%d\n", npalf);
4533fa4c323SSunil Goutham 		return NPA_AF_ERR_LF_RESET;
4543fa4c323SSunil Goutham 	}
4553fa4c323SSunil Goutham 
4563fa4c323SSunil Goutham 	npa_ctx_free(rvu, pfvf);
4573fa4c323SSunil Goutham 
4583fa4c323SSunil Goutham 	return 0;
4593fa4c323SSunil Goutham }
4603fa4c323SSunil Goutham 
4617a37245eSSunil Goutham static int npa_aq_init(struct rvu *rvu, struct rvu_block *block)
4627a37245eSSunil Goutham {
4637a37245eSSunil Goutham 	u64 cfg;
4647a37245eSSunil Goutham 	int err;
4657a37245eSSunil Goutham 
4667a37245eSSunil Goutham 	/* Set admin queue endianness */
4677a37245eSSunil Goutham 	cfg = rvu_read64(rvu, block->addr, NPA_AF_GEN_CFG);
4687a37245eSSunil Goutham #ifdef __BIG_ENDIAN
4697a37245eSSunil Goutham 	cfg |= BIT_ULL(1);
4707a37245eSSunil Goutham 	rvu_write64(rvu, block->addr, NPA_AF_GEN_CFG, cfg);
4717a37245eSSunil Goutham #else
4727a37245eSSunil Goutham 	cfg &= ~BIT_ULL(1);
4737a37245eSSunil Goutham 	rvu_write64(rvu, block->addr, NPA_AF_GEN_CFG, cfg);
4747a37245eSSunil Goutham #endif
4757a37245eSSunil Goutham 
4767a37245eSSunil Goutham 	/* Do not bypass NDC cache */
4777a37245eSSunil Goutham 	cfg = rvu_read64(rvu, block->addr, NPA_AF_NDC_CFG);
4787a37245eSSunil Goutham 	cfg &= ~0x03DULL;
479a0291766SSunil Goutham #ifdef CONFIG_NDC_DIS_DYNAMIC_CACHING
480a0291766SSunil Goutham 	/* Disable caching of stack pages */
481a0291766SSunil Goutham 	cfg |= 0x10ULL;
482a0291766SSunil Goutham #endif
4837a37245eSSunil Goutham 	rvu_write64(rvu, block->addr, NPA_AF_NDC_CFG, cfg);
4847a37245eSSunil Goutham 
485*ae2c341eSGeetha sowjanya 	/* For CN10K NPA BATCH DMA set 35 cache lines */
486*ae2c341eSGeetha sowjanya 	if (!is_rvu_otx2(rvu)) {
487*ae2c341eSGeetha sowjanya 		cfg = rvu_read64(rvu, block->addr, NPA_AF_BATCH_CTL);
488*ae2c341eSGeetha sowjanya 		cfg &= ~0x7EULL;
489*ae2c341eSGeetha sowjanya 		cfg |= BIT_ULL(6) | BIT_ULL(2) | BIT_ULL(1);
490*ae2c341eSGeetha sowjanya 		rvu_write64(rvu, block->addr, NPA_AF_BATCH_CTL, cfg);
491*ae2c341eSGeetha sowjanya 	}
4927a37245eSSunil Goutham 	/* Result structure can be followed by Aura/Pool context at
4937a37245eSSunil Goutham 	 * RES + 128bytes and a write mask at RES + 256 bytes, depending on
4947a37245eSSunil Goutham 	 * operation type. Alloc sufficient result memory for all operations.
4957a37245eSSunil Goutham 	 */
4967a37245eSSunil Goutham 	err = rvu_aq_alloc(rvu, &block->aq,
4977a37245eSSunil Goutham 			   Q_COUNT(AQ_SIZE), sizeof(struct npa_aq_inst_s),
4987a37245eSSunil Goutham 			   ALIGN(sizeof(struct npa_aq_res_s), 128) + 256);
4997a37245eSSunil Goutham 	if (err)
5007a37245eSSunil Goutham 		return err;
5017a37245eSSunil Goutham 
5027a37245eSSunil Goutham 	rvu_write64(rvu, block->addr, NPA_AF_AQ_CFG, AQ_SIZE);
5037a37245eSSunil Goutham 	rvu_write64(rvu, block->addr,
5047a37245eSSunil Goutham 		    NPA_AF_AQ_BASE, (u64)block->aq->inst->iova);
5057a37245eSSunil Goutham 	return 0;
5067a37245eSSunil Goutham }
5077a37245eSSunil Goutham 
5087a37245eSSunil Goutham int rvu_npa_init(struct rvu *rvu)
5097a37245eSSunil Goutham {
5107a37245eSSunil Goutham 	struct rvu_hwinfo *hw = rvu->hw;
5118e3bf53cSZheng Yongjun 	int blkaddr;
5127a37245eSSunil Goutham 
5137a37245eSSunil Goutham 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
5147a37245eSSunil Goutham 	if (blkaddr < 0)
5157a37245eSSunil Goutham 		return 0;
5167a37245eSSunil Goutham 
5177a37245eSSunil Goutham 	/* Initialize admin queue */
5188e3bf53cSZheng Yongjun 	return npa_aq_init(rvu, &hw->block[blkaddr]);
5197a37245eSSunil Goutham }
5207a37245eSSunil Goutham 
5217a37245eSSunil Goutham void rvu_npa_freemem(struct rvu *rvu)
5227a37245eSSunil Goutham {
5237a37245eSSunil Goutham 	struct rvu_hwinfo *hw = rvu->hw;
5247a37245eSSunil Goutham 	struct rvu_block *block;
5253fa4c323SSunil Goutham 	int blkaddr;
5267a37245eSSunil Goutham 
5277a37245eSSunil Goutham 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
5287a37245eSSunil Goutham 	if (blkaddr < 0)
5297a37245eSSunil Goutham 		return;
5307a37245eSSunil Goutham 
5317a37245eSSunil Goutham 	block = &hw->block[blkaddr];
5323fa4c323SSunil Goutham 	rvu_aq_free(rvu, block->aq);
5337a37245eSSunil Goutham }
534c554f9c1SGeetha sowjanya 
535c554f9c1SGeetha sowjanya void rvu_npa_lf_teardown(struct rvu *rvu, u16 pcifunc, int npalf)
536c554f9c1SGeetha sowjanya {
537c554f9c1SGeetha sowjanya 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
538c554f9c1SGeetha sowjanya 	struct hwctx_disable_req ctx_req;
539c554f9c1SGeetha sowjanya 
540c554f9c1SGeetha sowjanya 	/* Disable all pools */
541c554f9c1SGeetha sowjanya 	ctx_req.hdr.pcifunc = pcifunc;
542c554f9c1SGeetha sowjanya 	ctx_req.ctype = NPA_AQ_CTYPE_POOL;
543c554f9c1SGeetha sowjanya 	npa_lf_hwctx_disable(rvu, &ctx_req);
544c554f9c1SGeetha sowjanya 
545c554f9c1SGeetha sowjanya 	/* Disable all auras */
546c554f9c1SGeetha sowjanya 	ctx_req.ctype = NPA_AQ_CTYPE_AURA;
547c554f9c1SGeetha sowjanya 	npa_lf_hwctx_disable(rvu, &ctx_req);
548c554f9c1SGeetha sowjanya 
549c554f9c1SGeetha sowjanya 	npa_ctx_free(rvu, pfvf);
550c554f9c1SGeetha sowjanya }
551