octeontx2-af: cn10k: Support configurable LMTST regions
This patch extends the lmtst_tbl_setup_req mbox to support run time LMTST configuration. RVU PF/VF and DPDK/ODP allocates a LMT region, creates a translation entry for a device via VFIO IOCTLs. This IOVA is shared with AF through above mbox. AF then uses RVU_SMMU transulation Widget and gets PA for the IOVA and updates the LMTtable entry for that device. Signed-off-by: Geetha sowjanya <gakula@marvell.com> Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
873a1e3d20
commit
893ae97214
@ -1283,6 +1283,9 @@ struct set_vf_perm {
|
|||||||
struct lmtst_tbl_setup_req {
|
struct lmtst_tbl_setup_req {
|
||||||
struct mbox_msghdr hdr;
|
struct mbox_msghdr hdr;
|
||||||
u16 base_pcifunc;
|
u16 base_pcifunc;
|
||||||
|
u8 use_local_lmt_region;
|
||||||
|
u64 lmt_iova;
|
||||||
|
u64 rsvd[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CPT mailbox error codes
|
/* CPT mailbox error codes
|
||||||
|
@ -55,14 +55,101 @@ static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
|
|||||||
(pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
|
(pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
|
||||||
|
u64 iova, u64 *lmt_addr)
|
||||||
|
{
|
||||||
|
u64 pa, val, pf;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!iova) {
|
||||||
|
dev_err(rvu->dev, "%s Requested Null address for transulation\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
|
||||||
|
pf = rvu_get_pf(pcifunc) & 0x1F;
|
||||||
|
val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
|
||||||
|
((pcifunc & RVU_PFVF_FUNC_MASK) & 0xFF);
|
||||||
|
rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TXN_REQ, val);
|
||||||
|
|
||||||
|
err = rvu_poll_reg(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS, BIT_ULL(0), false);
|
||||||
|
if (err) {
|
||||||
|
dev_err(rvu->dev, "%s LMTLINE iova transulation failed\n", __func__);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
val = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS);
|
||||||
|
if (val & ~0x1ULL) {
|
||||||
|
dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
/* PA[51:12] = RVU_AF_SMMU_TLN_FLIT1[60:21]
|
||||||
|
* PA[11:0] = IOVA[11:0]
|
||||||
|
*/
|
||||||
|
pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT1) >> 21;
|
||||||
|
pa &= GENMASK_ULL(39, 0);
|
||||||
|
*lmt_addr = (pa << 12) | (iova & 0xFFF);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rvu_update_lmtaddr(struct rvu *rvu, u16 pcifunc, u64 lmt_addr)
|
||||||
|
{
|
||||||
|
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
|
||||||
|
u32 tbl_idx;
|
||||||
|
int err = 0;
|
||||||
|
u64 val;
|
||||||
|
|
||||||
|
/* Read the current lmt addr of pcifunc */
|
||||||
|
tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
|
||||||
|
err = lmtst_map_table_ops(rvu, tbl_idx, &val, LMT_TBL_OP_READ);
|
||||||
|
if (err) {
|
||||||
|
dev_err(rvu->dev,
|
||||||
|
"Failed to read LMT map table: index 0x%x err %d\n",
|
||||||
|
tbl_idx, err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Storing the seondary's lmt base address as this needs to be
|
||||||
|
* reverted in FLR. Also making sure this default value doesn't
|
||||||
|
* get overwritten on multiple calls to this mailbox.
|
||||||
|
*/
|
||||||
|
if (!pfvf->lmt_base_addr)
|
||||||
|
pfvf->lmt_base_addr = val;
|
||||||
|
|
||||||
|
/* Update the LMT table with new addr */
|
||||||
|
err = lmtst_map_table_ops(rvu, tbl_idx, &lmt_addr, LMT_TBL_OP_WRITE);
|
||||||
|
if (err) {
|
||||||
|
dev_err(rvu->dev,
|
||||||
|
"Failed to update LMT map table: index 0x%x err %d\n",
|
||||||
|
tbl_idx, err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
|
int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
|
||||||
struct lmtst_tbl_setup_req *req,
|
struct lmtst_tbl_setup_req *req,
|
||||||
struct msg_rsp *rsp)
|
struct msg_rsp *rsp)
|
||||||
{
|
{
|
||||||
struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
|
u64 lmt_addr, val;
|
||||||
u32 pri_tbl_idx, sec_tbl_idx;
|
u32 pri_tbl_idx;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
u64 val;
|
|
||||||
|
/* Check if PF_FUNC wants to use it's own local memory as LMTLINE
|
||||||
|
* region, if so, convert that IOVA to physical address and
|
||||||
|
* populate LMT table with that address
|
||||||
|
*/
|
||||||
|
if (req->use_local_lmt_region) {
|
||||||
|
err = rvu_get_lmtaddr(rvu, req->hdr.pcifunc,
|
||||||
|
req->lmt_iova, &lmt_addr);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* Update the lmt addr for this PFFUNC in the LMT table */
|
||||||
|
err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, lmt_addr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reconfiguring lmtst map table in lmt region shared mode i.e. make
|
/* Reconfiguring lmtst map table in lmt region shared mode i.e. make
|
||||||
* multiple PF_FUNCs to share an LMTLINE region, so primary/base
|
* multiple PF_FUNCs to share an LMTLINE region, so primary/base
|
||||||
@ -76,27 +163,6 @@ int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
|
|||||||
*/
|
*/
|
||||||
pri_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->base_pcifunc);
|
pri_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->base_pcifunc);
|
||||||
|
|
||||||
/* Truncating secondary pcifunc to calculate the LMT table index
|
|
||||||
* equivalent to secondary pcifunc.
|
|
||||||
*/
|
|
||||||
sec_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->hdr.pcifunc);
|
|
||||||
/* Read the base lmt addr of the secondary pcifunc */
|
|
||||||
err = lmtst_map_table_ops(rvu, sec_tbl_idx, &val,
|
|
||||||
LMT_TBL_OP_READ);
|
|
||||||
if (err) {
|
|
||||||
dev_err(rvu->dev,
|
|
||||||
"Failed to read LMT map table: index 0x%x err %d\n",
|
|
||||||
sec_tbl_idx, err);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Storing the seondary's lmt base address as this needs to be
|
|
||||||
* reverted in FLR. Also making sure this default value doesn't
|
|
||||||
* get overwritten on multiple calls to this mailbox.
|
|
||||||
*/
|
|
||||||
if (!pfvf->lmt_base_addr)
|
|
||||||
pfvf->lmt_base_addr = val;
|
|
||||||
|
|
||||||
/* Read the base lmt addr of the primary pcifunc */
|
/* Read the base lmt addr of the primary pcifunc */
|
||||||
err = lmtst_map_table_ops(rvu, pri_tbl_idx, &val,
|
err = lmtst_map_table_ops(rvu, pri_tbl_idx, &val,
|
||||||
LMT_TBL_OP_READ);
|
LMT_TBL_OP_READ);
|
||||||
@ -104,24 +170,18 @@ int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
|
|||||||
dev_err(rvu->dev,
|
dev_err(rvu->dev,
|
||||||
"Failed to read LMT map table: index 0x%x err %d\n",
|
"Failed to read LMT map table: index 0x%x err %d\n",
|
||||||
pri_tbl_idx, err);
|
pri_tbl_idx, err);
|
||||||
goto error;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the base lmt addr of secondary with primary's base
|
/* Update the base lmt addr of secondary with primary's base
|
||||||
* lmt addr.
|
* lmt addr.
|
||||||
*/
|
*/
|
||||||
err = lmtst_map_table_ops(rvu, sec_tbl_idx, &val,
|
err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, val);
|
||||||
LMT_TBL_OP_WRITE);
|
if (err)
|
||||||
if (err) {
|
return err;
|
||||||
dev_err(rvu->dev,
|
|
||||||
"Failed to update LMT map table: index 0x%x err %d\n",
|
|
||||||
sec_tbl_idx, err);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
return 0;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resetting the lmtst map table to original base addresses */
|
/* Resetting the lmtst map table to original base addresses */
|
||||||
|
@ -49,6 +49,11 @@
|
|||||||
#define RVU_AF_PFX_VF_BAR4_ADDR (0x5400 | (a) << 4)
|
#define RVU_AF_PFX_VF_BAR4_ADDR (0x5400 | (a) << 4)
|
||||||
#define RVU_AF_PFX_VF_BAR4_CFG (0x5600 | (a) << 4)
|
#define RVU_AF_PFX_VF_BAR4_CFG (0x5600 | (a) << 4)
|
||||||
#define RVU_AF_PFX_LMTLINE_ADDR (0x5800 | (a) << 4)
|
#define RVU_AF_PFX_LMTLINE_ADDR (0x5800 | (a) << 4)
|
||||||
|
#define RVU_AF_SMMU_ADDR_REQ (0x6000)
|
||||||
|
#define RVU_AF_SMMU_TXN_REQ (0x6008)
|
||||||
|
#define RVU_AF_SMMU_ADDR_RSP_STS (0x6010)
|
||||||
|
#define RVU_AF_SMMU_ADDR_TLN (0x6018)
|
||||||
|
#define RVU_AF_SMMU_TLN_FLIT1 (0x6030)
|
||||||
|
|
||||||
/* Admin function's privileged PF/VF registers */
|
/* Admin function's privileged PF/VF registers */
|
||||||
#define RVU_PRIV_CONST (0x8000000)
|
#define RVU_PRIV_CONST (0x8000000)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user