-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
octeontx2-af: NPA block admin queue init
Initialize NPA admin queue (AQ) i.e alloc memory for AQ instructions and for the results. All NPA LFs will submit instructions to AQ to init/write/read Aura/Pool contexts and in case of read, get context from result memory. Added some common APIs for allocating memory for a queue and get IOVA in return, these APIs will be used by NIX AQ and for other purposes. Signed-off-by: Sunil Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Sunil Goutham
authored and
David S. Miller
committed
Oct 18, 2018
1 parent
23999b3
commit 7a37245
Showing
6 changed files
with
309 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 | ||
* Marvell OcteonTx2 RVU Admin Function driver | ||
* | ||
* Copyright (C) 2018 Marvell International Ltd. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#ifndef COMMON_H | ||
#define COMMON_H | ||
|
||
#include "rvu_struct.h" | ||
|
||
#define OTX2_ALIGN 128 /* Align to cacheline */ | ||
|
||
#define Q_SIZE_16 0ULL /* 16 entries */ | ||
#define Q_SIZE_64 1ULL /* 64 entries */ | ||
#define Q_SIZE_256 2ULL | ||
#define Q_SIZE_1K 3ULL | ||
#define Q_SIZE_4K 4ULL | ||
#define Q_SIZE_16K 5ULL | ||
#define Q_SIZE_64K 6ULL | ||
#define Q_SIZE_256K 7ULL | ||
#define Q_SIZE_1M 8ULL /* Million entries */ | ||
#define Q_SIZE_MIN Q_SIZE_16 | ||
#define Q_SIZE_MAX Q_SIZE_1M | ||
|
||
#define Q_COUNT(x) (16ULL << (2 * x)) | ||
#define Q_SIZE(x, n) ((ilog2(x) - (n)) / 2) | ||
|
||
/* Admin queue info */ | ||
|
||
/* Since we intend to add only one instruction at a time, | ||
* keep queue size to it's minimum. | ||
*/ | ||
#define AQ_SIZE Q_SIZE_16 | ||
/* HW head & tail pointer mask */ | ||
#define AQ_PTR_MASK 0xFFFFF | ||
|
||
struct qmem { | ||
void *base; | ||
dma_addr_t iova; | ||
int alloc_sz; | ||
u8 entry_sz; | ||
u8 align; | ||
u32 qsize; | ||
}; | ||
|
||
static inline int qmem_alloc(struct device *dev, struct qmem **q, | ||
int qsize, int entry_sz) | ||
{ | ||
struct qmem *qmem; | ||
int aligned_addr; | ||
|
||
if (!qsize) | ||
return -EINVAL; | ||
|
||
*q = devm_kzalloc(dev, sizeof(*qmem), GFP_KERNEL); | ||
if (!*q) | ||
return -ENOMEM; | ||
qmem = *q; | ||
|
||
qmem->entry_sz = entry_sz; | ||
qmem->alloc_sz = (qsize * entry_sz) + OTX2_ALIGN; | ||
qmem->base = dma_zalloc_coherent(dev, qmem->alloc_sz, | ||
&qmem->iova, GFP_KERNEL); | ||
if (!qmem->base) | ||
return -ENOMEM; | ||
|
||
qmem->qsize = qsize; | ||
|
||
aligned_addr = ALIGN((u64)qmem->iova, OTX2_ALIGN); | ||
qmem->align = (aligned_addr - qmem->iova); | ||
qmem->base += qmem->align; | ||
qmem->iova += qmem->align; | ||
return 0; | ||
} | ||
|
||
static inline void qmem_free(struct device *dev, struct qmem *qmem) | ||
{ | ||
if (!qmem) | ||
return; | ||
|
||
if (qmem->base) | ||
dma_free_coherent(dev, qmem->alloc_sz, | ||
qmem->base - qmem->align, | ||
qmem->iova - qmem->align); | ||
devm_kfree(dev, qmem); | ||
} | ||
|
||
struct admin_queue { | ||
struct qmem *inst; | ||
struct qmem *res; | ||
spinlock_t lock; /* Serialize inst enqueue from PFs */ | ||
}; | ||
|
||
#endif /* COMMON_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Marvell OcteonTx2 RVU Admin Function driver | ||
* | ||
* Copyright (C) 2018 Marvell International Ltd. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/pci.h> | ||
|
||
#include "rvu_struct.h" | ||
#include "rvu_reg.h" | ||
#include "rvu.h" | ||
|
||
static int npa_aq_init(struct rvu *rvu, struct rvu_block *block) | ||
{ | ||
u64 cfg; | ||
int err; | ||
|
||
/* Set admin queue endianness */ | ||
cfg = rvu_read64(rvu, block->addr, NPA_AF_GEN_CFG); | ||
#ifdef __BIG_ENDIAN | ||
cfg |= BIT_ULL(1); | ||
rvu_write64(rvu, block->addr, NPA_AF_GEN_CFG, cfg); | ||
#else | ||
cfg &= ~BIT_ULL(1); | ||
rvu_write64(rvu, block->addr, NPA_AF_GEN_CFG, cfg); | ||
#endif | ||
|
||
/* Do not bypass NDC cache */ | ||
cfg = rvu_read64(rvu, block->addr, NPA_AF_NDC_CFG); | ||
cfg &= ~0x03DULL; | ||
rvu_write64(rvu, block->addr, NPA_AF_NDC_CFG, cfg); | ||
|
||
/* Result structure can be followed by Aura/Pool context at | ||
* RES + 128bytes and a write mask at RES + 256 bytes, depending on | ||
* operation type. Alloc sufficient result memory for all operations. | ||
*/ | ||
err = rvu_aq_alloc(rvu, &block->aq, | ||
Q_COUNT(AQ_SIZE), sizeof(struct npa_aq_inst_s), | ||
ALIGN(sizeof(struct npa_aq_res_s), 128) + 256); | ||
if (err) | ||
return err; | ||
|
||
rvu_write64(rvu, block->addr, NPA_AF_AQ_CFG, AQ_SIZE); | ||
rvu_write64(rvu, block->addr, | ||
NPA_AF_AQ_BASE, (u64)block->aq->inst->iova); | ||
return 0; | ||
} | ||
|
||
int rvu_npa_init(struct rvu *rvu) | ||
{ | ||
struct rvu_hwinfo *hw = rvu->hw; | ||
struct rvu_block *block; | ||
int blkaddr, err; | ||
|
||
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); | ||
if (blkaddr < 0) | ||
return 0; | ||
|
||
block = &hw->block[blkaddr]; | ||
|
||
/* Initialize admin queue */ | ||
err = npa_aq_init(rvu, &hw->block[blkaddr]); | ||
if (err) | ||
return err; | ||
|
||
return 0; | ||
} | ||
|
||
void rvu_npa_freemem(struct rvu *rvu) | ||
{ | ||
struct rvu_hwinfo *hw = rvu->hw; | ||
struct rvu_block *block; | ||
int blkaddr, err; | ||
|
||
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); | ||
if (blkaddr < 0) | ||
return; | ||
|
||
block = &hw->block[blkaddr]; | ||
rvu_aq_free(rvu, &block->aq); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters