From 0e9734fe41d43cc9889c834b2fa82734a5c95c2d Mon Sep 17 00:00:00 2001 From: Jerin Jacob Date: Sat, 22 Jun 2019 18:53:59 +0530 Subject: [PATCH] common/octeontx2: handle intra device operations The mempool device(NPA) may be provisioned as a standalone device or it can be part of ethdev/eventdev device. In order to address mempool as standalone or integrated with ethdev/eventdev device, An intra device structure being introduced. When the _first_ ethdev/eventdev PCIe device or standalone mempool(NPA) devices get probed by the eal PCI subsystem, The NPA object(struct otx2_npa_lf) stored in otx2_dev base class. Once it is accomplished, the other consumer drivers like ethdev driver or eventdev driver use otx2_npa_* API to operate on shared NPA object. The similar concept followed for SSO object, Which needs to share between PCIe devices. Signed-off-by: Jerin Jacob Signed-off-by: Nithin Dabilpuram Signed-off-by: Pavan Nikhilesh --- drivers/common/octeontx2/otx2_common.c | 163 ++++++++++++++++++ drivers/common/octeontx2/otx2_common.h | 32 +++- drivers/common/octeontx2/otx2_dev.c | 6 + drivers/common/octeontx2/otx2_dev.h | 1 + .../rte_common_octeontx2_version.map | 9 + 5 files changed, 210 insertions(+), 1 deletion(-) diff --git a/drivers/common/octeontx2/otx2_common.c b/drivers/common/octeontx2/otx2_common.c index a4b91b4f1a..7e45366390 100644 --- a/drivers/common/octeontx2/otx2_common.c +++ b/drivers/common/octeontx2/otx2_common.c @@ -2,9 +2,172 @@ * Copyright(C) 2019 Marvell International Ltd. */ +#include +#include #include #include "otx2_common.h" +#include "otx2_dev.h" +#include "otx2_mbox.h" + +/** + * @internal + * Set default NPA configuration. + */ +void +otx2_npa_set_defaults(struct otx2_idev_cfg *idev) +{ + idev->npa_pf_func = 0; + rte_atomic16_set(&idev->npa_refcnt, 0); +} + +/** + * @internal + * Get intra device config structure. + */ +struct otx2_idev_cfg * +otx2_intra_dev_get_cfg(void) +{ + const char name[] = "octeontx2_intra_device_conf"; + const struct rte_memzone *mz; + struct otx2_idev_cfg *idev; + + mz = rte_memzone_lookup(name); + if (mz != NULL) + return mz->addr; + + /* Request for the first time */ + mz = rte_memzone_reserve_aligned(name, sizeof(struct otx2_idev_cfg), + SOCKET_ID_ANY, 0, OTX2_ALIGN); + if (mz != NULL) { + idev = mz->addr; + idev->sso_pf_func = 0; + idev->npa_lf = NULL; + otx2_npa_set_defaults(idev); + return idev; + } + return NULL; +} + +/** + * @internal + * Get SSO PF_FUNC. + */ +uint16_t +otx2_sso_pf_func_get(void) +{ + struct otx2_idev_cfg *idev; + uint16_t sso_pf_func; + + sso_pf_func = 0; + idev = otx2_intra_dev_get_cfg(); + + if (idev != NULL) + sso_pf_func = idev->sso_pf_func; + + return sso_pf_func; +} + +/** + * @internal + * Set SSO PF_FUNC. + */ +void +otx2_sso_pf_func_set(uint16_t sso_pf_func) +{ + struct otx2_idev_cfg *idev; + + idev = otx2_intra_dev_get_cfg(); + + if (idev != NULL) { + idev->sso_pf_func = sso_pf_func; + rte_smp_wmb(); + } +} + +/** + * @internal + * Get NPA PF_FUNC. + */ +uint16_t +otx2_npa_pf_func_get(void) +{ + struct otx2_idev_cfg *idev; + uint16_t npa_pf_func; + + npa_pf_func = 0; + idev = otx2_intra_dev_get_cfg(); + + if (idev != NULL) + npa_pf_func = idev->npa_pf_func; + + return npa_pf_func; +} + +/** + * @internal + * Get NPA lf object. + */ +struct otx2_npa_lf * +otx2_npa_lf_obj_get(void) +{ + struct otx2_idev_cfg *idev; + + idev = otx2_intra_dev_get_cfg(); + + if (idev != NULL && rte_atomic16_read(&idev->npa_refcnt)) + return idev->npa_lf; + + return NULL; +} + +/** + * @internal + * Is NPA lf active for the given device?. + */ +int +otx2_npa_lf_active(void *otx2_dev) +{ + struct otx2_dev *dev = otx2_dev; + struct otx2_idev_cfg *idev; + + /* Check if npalf is actively used on this dev */ + idev = otx2_intra_dev_get_cfg(); + if (!idev || !idev->npa_lf || idev->npa_lf->mbox != dev->mbox) + return 0; + + return rte_atomic16_read(&idev->npa_refcnt); +} + +/* + * @internal + * Gets reference only to existing NPA LF object. + */ +int otx2_npa_lf_obj_ref(void) +{ + struct otx2_idev_cfg *idev; + uint16_t cnt; + int rc; + + idev = otx2_intra_dev_get_cfg(); + + /* Check if ref not possible */ + if (idev == NULL) + return -EINVAL; + + + /* Get ref only if > 0 */ + cnt = rte_atomic16_read(&idev->npa_refcnt); + while (cnt != 0) { + rc = rte_atomic16_cmpset(&idev->npa_refcnt_u16, cnt, cnt + 1); + if (rc) + break; + + cnt = rte_atomic16_read(&idev->npa_refcnt); + } + + return cnt ? 0 : -EINVAL; +} /** * @internal diff --git a/drivers/common/octeontx2/otx2_common.h b/drivers/common/octeontx2/otx2_common.h index b9e7a7f8d6..cbc5c65a78 100644 --- a/drivers/common/octeontx2/otx2_common.h +++ b/drivers/common/octeontx2/otx2_common.h @@ -5,9 +5,12 @@ #ifndef _OTX2_COMMON_H_ #define _OTX2_COMMON_H_ +#include #include -#include +#include #include +#include +#include #include "hw/otx2_rvu.h" #include "hw/otx2_nix.h" @@ -33,6 +36,33 @@ #define __hot __attribute__((hot)) #endif +/* Intra device related functions */ +struct otx2_npa_lf { + struct otx2_mbox *mbox; + struct rte_pci_device *pci_dev; + struct rte_intr_handle *intr_handle; +}; + +struct otx2_idev_cfg { + uint16_t sso_pf_func; + uint16_t npa_pf_func; + struct otx2_npa_lf *npa_lf; + RTE_STD_C11 + union { + rte_atomic16_t npa_refcnt; + uint16_t npa_refcnt_u16; + }; +}; + +struct otx2_idev_cfg *otx2_intra_dev_get_cfg(void); +void otx2_sso_pf_func_set(uint16_t sso_pf_func); +uint16_t otx2_sso_pf_func_get(void); +uint16_t otx2_npa_pf_func_get(void); +struct otx2_npa_lf *otx2_npa_lf_obj_get(void); +void otx2_npa_set_defaults(struct otx2_idev_cfg *idev); +int otx2_npa_lf_active(void *dev); +int otx2_npa_lf_obj_ref(void); + /* Log */ extern int otx2_logtype_base; extern int otx2_logtype_mbox; diff --git a/drivers/common/octeontx2/otx2_dev.c b/drivers/common/octeontx2/otx2_dev.c index 486b1b7c8b..c3b3f9be51 100644 --- a/drivers/common/octeontx2/otx2_dev.c +++ b/drivers/common/octeontx2/otx2_dev.c @@ -177,8 +177,14 @@ void otx2_dev_fini(struct rte_pci_device *pci_dev, void *otx2_dev) { struct otx2_dev *dev = otx2_dev; + struct otx2_idev_cfg *idev; struct otx2_mbox *mbox; + /* Clear references to this pci dev */ + idev = otx2_intra_dev_get_cfg(); + if (idev->npa_lf && idev->npa_lf->pci_dev == pci_dev) + idev->npa_lf = NULL; + /* Release PF - VF */ mbox = &dev->mbox_vfpf; if (mbox->hwbase && mbox->dev) diff --git a/drivers/common/octeontx2/otx2_dev.h b/drivers/common/octeontx2/otx2_dev.h index a89570b622..70104dfa22 100644 --- a/drivers/common/octeontx2/otx2_dev.h +++ b/drivers/common/octeontx2/otx2_dev.h @@ -40,6 +40,7 @@ struct otx2_dev; otx2_intr_t intr; \ int timer_set; /* ~0 : no alarm handling */ \ uint64_t hwcap; \ + struct otx2_npa_lf npalf; \ struct otx2_mbox *mbox; \ uint16_t maxvf; \ const struct otx2_dev_ops *ops diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map index 007649a484..efcf0cb55f 100644 --- a/drivers/common/octeontx2/rte_common_octeontx2_version.map +++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map @@ -21,6 +21,15 @@ DPDK_19.08 { otx2_mbox_msg_send; otx2_mbox_wait_for_rsp; + otx2_intra_dev_get_cfg; + otx2_npa_lf_active; + otx2_npa_lf_obj_get; + otx2_npa_lf_obj_ref; + otx2_npa_pf_func_get; + otx2_npa_set_defaults; + otx2_sso_pf_func_get; + otx2_sso_pf_func_set; + otx2_disable_irqs; otx2_unregister_irq; otx2_register_irq; -- 2.20.1