diff options
Diffstat (limited to 'drivers/net/ethernet/marvell')
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 34 | ||||
-rw-r--r-- | drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 1 |
2 files changed, 32 insertions, 3 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index 469c96bfc026..7bcc1fd3da83 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -441,9 +441,10 @@ static int rvu_setup_msix_resources(struct rvu *rvu) { struct rvu_hwinfo *hw = rvu->hw; int pf, vf, numvfs, hwvf, err; + int nvecs, offset, max_msix; struct rvu_pfvf *pfvf; - int nvecs, offset; - u64 cfg; + u64 cfg, phy_addr; + dma_addr_t iova; for (pf = 0; pf < hw->total_pfs; pf++) { cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf)); @@ -522,6 +523,23 @@ setup_vfmsix: } } + /* HW interprets RVU_AF_MSIXTR_BASE address as an IOVA, hence + * create a IOMMU mapping for the physcial address configured by + * firmware and reconfig RVU_AF_MSIXTR_BASE with IOVA. + */ + cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_CONST); + max_msix = cfg & 0xFFFFF; + phy_addr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_MSIXTR_BASE); + iova = dma_map_resource(rvu->dev, phy_addr, + max_msix * PCI_MSIX_ENTRY_SIZE, + DMA_BIDIRECTIONAL, 0); + + if (dma_mapping_error(rvu->dev, iova)) + return -ENOMEM; + + rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_MSIXTR_BASE, (u64)iova); + rvu->msix_base_iova = iova; + return 0; } @@ -530,7 +548,8 @@ static void rvu_free_hw_resources(struct rvu *rvu) struct rvu_hwinfo *hw = rvu->hw; struct rvu_block *block; struct rvu_pfvf *pfvf; - int id; + int id, max_msix; + u64 cfg; /* Free block LF bitmaps */ for (id = 0; id < BLK_COUNT; id++) { @@ -548,6 +567,15 @@ static void rvu_free_hw_resources(struct rvu *rvu) pfvf = &rvu->hwvf[id]; kfree(pfvf->msix.bmap); } + + /* Unmap MSIX vector base IOVA mapping */ + if (!rvu->msix_base_iova) + return; + cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_CONST); + max_msix = cfg & 0xFFFFF; + dma_unmap_resource(rvu->dev, rvu->msix_base_iova, + max_msix * PCI_MSIX_ENTRY_SIZE, + DMA_BIDIRECTIONAL, 0); } static int rvu_setup_hw_resources(struct rvu *rvu) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index 7435e8384cb4..92c202295206 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -99,6 +99,7 @@ struct rvu { u16 num_vec; char *irq_name; bool *irq_allocated; + dma_addr_t msix_base_iova; }; static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) |