common/octeontx2: handle intra device operations
authorJerin Jacob <jerinj@marvell.com>
Sat, 22 Jun 2019 13:23:59 +0000 (18:53 +0530)
committerThomas Monjalon <thomas@monjalon.net>
Tue, 25 Jun 2019 21:35:57 +0000 (23:35 +0200)
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 <jerinj@marvell.com>
Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
Signed-off-by: Pavan Nikhilesh <pbhagavatula@marvell.com>
drivers/common/octeontx2/otx2_common.c
drivers/common/octeontx2/otx2_common.h
drivers/common/octeontx2/otx2_dev.c
drivers/common/octeontx2/otx2_dev.h
drivers/common/octeontx2/rte_common_octeontx2_version.map

index a4b91b4..7e45366 100644 (file)
@@ -2,9 +2,172 @@
  * Copyright(C) 2019 Marvell International Ltd.
  */
 
+#include <rte_atomic.h>
+#include <rte_malloc.h>
 #include <rte_log.h>
 
 #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
index b9e7a7f..cbc5c65 100644 (file)
@@ -5,9 +5,12 @@
 #ifndef _OTX2_COMMON_H_
 #define _OTX2_COMMON_H_
 
+#include <rte_atomic.h>
 #include <rte_common.h>
-#include <rte_io.h>
+#include <rte_cycles.h>
 #include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_io.h>
 
 #include "hw/otx2_rvu.h"
 #include "hw/otx2_nix.h"
 #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;
index 486b1b7..c3b3f9b 100644 (file)
@@ -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)
index a89570b..70104df 100644 (file)
@@ -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
index 007649a..efcf0cb 100644 (file)
@@ -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;