numam-dpdk/drivers/common/cnxk/roc_dpi.c
Radha Mohan Chintakuntla b6e395692b common/cnxk: add DPI DMA support
Add base support as ROC(Rest of Chip) API which will be used by PMD
dmadev driver.

This patch adds routines to init, fini, configure the DPI DMA device
found in Marvell's CN9k or CN10k SoC families.

Signed-off-by: Radha Mohan Chintakuntla <radhac@marvell.com>
2021-11-07 23:29:58 +01:00

194 lines
4.4 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(C) 2021 Marvell.
*/
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "roc_api.h"
#include "roc_priv.h"
#define DPI_PF_MBOX_SYSFS_ENTRY "dpi_device_config"
static inline int
send_msg_to_pf(struct plt_pci_addr *pci_addr, const char *value, int size)
{
char buf[255] = {0};
int res, fd;
res = snprintf(
buf, sizeof(buf), "/sys/bus/pci/devices/" PCI_PRI_FMT "/%s",
pci_addr->domain, pci_addr->bus, DPI_PF_DBDF_DEVICE & 0x7,
DPI_PF_DBDF_FUNCTION & 0x7, DPI_PF_MBOX_SYSFS_ENTRY);
if ((res < 0) || ((size_t)res > sizeof(buf)))
return -ERANGE;
fd = open(buf, O_WRONLY);
if (fd < 0)
return -EACCES;
res = write(fd, value, size);
close(fd);
if (res < 0)
return -EACCES;
return 0;
}
int
roc_dpi_enable(struct roc_dpi *dpi)
{
plt_write64(0x1, dpi->rbase + DPI_VDMA_EN);
return 0;
}
int
roc_dpi_disable(struct roc_dpi *dpi)
{
plt_write64(0x0, dpi->rbase + DPI_VDMA_EN);
return 0;
}
int
roc_dpi_configure(struct roc_dpi *roc_dpi)
{
struct plt_pci_device *pci_dev;
const struct plt_memzone *dpi_mz;
dpi_mbox_msg_t mbox_msg;
struct npa_pool_s pool;
struct npa_aura_s aura;
int rc, count, buflen;
uint64_t aura_handle;
plt_iova_t iova;
char name[32];
if (!roc_dpi) {
plt_err("roc_dpi is NULL");
return -EINVAL;
}
pci_dev = roc_dpi->pci_dev;
memset(&pool, 0, sizeof(struct npa_pool_s));
pool.nat_align = 1;
memset(&aura, 0, sizeof(aura));
rc = roc_npa_pool_create(&aura_handle, DPI_CMD_QUEUE_SIZE,
DPI_CMD_QUEUE_BUFS, &aura, &pool);
if (rc) {
plt_err("Failed to create NPA pool, err %d\n", rc);
return rc;
}
snprintf(name, sizeof(name), "dpimem%d", roc_dpi->vfid);
buflen = DPI_CMD_QUEUE_SIZE * DPI_CMD_QUEUE_BUFS;
dpi_mz = plt_memzone_reserve_aligned(name, buflen, 0,
DPI_CMD_QUEUE_SIZE);
if (dpi_mz == NULL) {
plt_err("dpi memzone reserve failed");
rc = -ENOMEM;
goto err1;
}
roc_dpi->mz = dpi_mz;
iova = dpi_mz->iova;
for (count = 0; count < DPI_CMD_QUEUE_BUFS; count++) {
roc_npa_aura_op_free(aura_handle, 0, iova);
iova += DPI_CMD_QUEUE_SIZE;
}
roc_dpi->chunk_base = (void *)roc_npa_aura_op_alloc(aura_handle, 0);
if (!roc_dpi->chunk_base) {
plt_err("Failed to alloc buffer from NPA aura");
rc = -ENOMEM;
goto err2;
}
roc_dpi->chunk_next = (void *)roc_npa_aura_op_alloc(aura_handle, 0);
if (!roc_dpi->chunk_next) {
plt_err("Failed to alloc buffer from NPA aura");
rc = -ENOMEM;
goto err2;
}
roc_dpi->aura_handle = aura_handle;
/* subtract 2 as they have already been alloc'ed above */
roc_dpi->pool_size_m1 = (DPI_CMD_QUEUE_SIZE >> 3) - 2;
plt_write64(0x0, roc_dpi->rbase + DPI_VDMA_REQQ_CTL);
plt_write64(((uint64_t)(roc_dpi->chunk_base) >> 7) << 7,
roc_dpi->rbase + DPI_VDMA_SADDR);
mbox_msg.u[0] = 0;
mbox_msg.u[1] = 0;
/* DPI PF driver expects vfid starts from index 0 */
mbox_msg.s.vfid = roc_dpi->vfid;
mbox_msg.s.cmd = DPI_QUEUE_OPEN;
mbox_msg.s.csize = DPI_CMD_QUEUE_SIZE;
mbox_msg.s.aura = roc_npa_aura_handle_to_aura(aura_handle);
mbox_msg.s.sso_pf_func = idev_sso_pffunc_get();
mbox_msg.s.npa_pf_func = idev_npa_pffunc_get();
rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg,
sizeof(dpi_mbox_msg_t));
if (rc < 0) {
plt_err("Failed to send mbox message %d to DPI PF, err %d",
mbox_msg.s.cmd, rc);
goto err2;
}
return rc;
err2:
plt_memzone_free(dpi_mz);
err1:
roc_npa_pool_destroy(aura_handle);
return rc;
}
int
roc_dpi_dev_init(struct roc_dpi *roc_dpi)
{
struct plt_pci_device *pci_dev = roc_dpi->pci_dev;
uint16_t vfid;
roc_dpi->rbase = pci_dev->mem_resource[0].addr;
vfid = ((pci_dev->addr.devid & 0x1F) << 3) |
(pci_dev->addr.function & 0x7);
vfid -= 1;
roc_dpi->vfid = vfid;
plt_spinlock_init(&roc_dpi->chunk_lock);
return 0;
}
int
roc_dpi_dev_fini(struct roc_dpi *roc_dpi)
{
struct plt_pci_device *pci_dev = roc_dpi->pci_dev;
dpi_mbox_msg_t mbox_msg;
uint64_t reg;
int rc;
/* Wait for SADDR to become idle */
reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR);
while (!(reg & BIT_ULL(63)))
reg = plt_read64(roc_dpi->rbase + DPI_VDMA_SADDR);
mbox_msg.u[0] = 0;
mbox_msg.u[1] = 0;
mbox_msg.s.vfid = roc_dpi->vfid;
mbox_msg.s.cmd = DPI_QUEUE_CLOSE;
rc = send_msg_to_pf(&pci_dev->addr, (const char *)&mbox_msg,
sizeof(dpi_mbox_msg_t));
if (rc < 0)
plt_err("Failed to send mbox message %d to DPI PF, err %d",
mbox_msg.s.cmd, rc);
roc_npa_pool_destroy(roc_dpi->aura_handle);
plt_memzone_free(roc_dpi->mz);
return rc;
}