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