Add ntnic logging API and utilities.

Signed-off-by: Serhii Iliushyk <sil-...@napatech.com>
---
 drivers/net/ntnic/ntlog/include/ntlog.h    | 162 +++++++++++++++++++++
 drivers/net/ntnic/ntlog/ntlog.c            | 108 ++++++++++++++
 drivers/net/ntnic/ntutil/include/nt_util.h |  51 +++++++
 drivers/net/ntnic/ntutil/nt_util.c         |  98 +++++++++++++
 4 files changed, 419 insertions(+)
 create mode 100644 drivers/net/ntnic/ntlog/include/ntlog.h
 create mode 100644 drivers/net/ntnic/ntlog/ntlog.c
 create mode 100644 drivers/net/ntnic/ntutil/include/nt_util.h
 create mode 100644 drivers/net/ntnic/ntutil/nt_util.c

diff --git a/drivers/net/ntnic/ntlog/include/ntlog.h 
b/drivers/net/ntnic/ntlog/include/ntlog.h
new file mode 100644
index 0000000000..75fc08d4e1
--- /dev/null
+++ b/drivers/net/ntnic/ntlog/include/ntlog.h
@@ -0,0 +1,162 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef NTOSS_SYSTEM_NTLOG_H
+#define NTOSS_SYSTEM_NTLOG_H
+
+#include <stdarg.h>
+#include <stdint.h>
+
+#ifndef NT_LOG_MODULE_PREFIX
+
+/* DPDK modules */
+#define NT_LOG_MODULE_EAL 0
+#define NT_LOG_MODULE_MALLOC 1
+#define NT_LOG_MODULE_RING 2
+#define NT_LOG_MODULE_MEMPOOL 3
+#define NT_LOG_MODULE_TIMER 4
+#define NT_LOG_MODULE_PMD 5
+#define NT_LOG_MODULE_HASH 6
+#define NT_LOG_MODULE_LPM 7
+#define NT_LOG_MODULE_KNI 8
+#define NT_LOG_MODULE_ACL 9
+#define NT_LOG_MODULE_POWER 10
+#define NT_LOG_MODULE_METER 11
+#define NT_LOG_MODULE_SCHED 12
+#define NT_LOG_MODULE_PORT 13
+#define NT_LOG_MODULE_TABLE 14
+#define NT_LOG_MODULE_PIPELINE 15
+#define NT_LOG_MODULE_MBUF 16
+#define NT_LOG_MODULE_CRYPTODEV 17
+#define NT_LOG_MODULE_EFD 18
+#define NT_LOG_MODULE_EVENTDEV 19
+#define NT_LOG_MODULE_GSO 20
+#define NT_LOG_MODULE_USER1 24
+#define NT_LOG_MODULE_USER2 25
+#define NT_LOG_MODULE_USER3 26
+#define NT_LOG_MODULE_USER4 27
+#define NT_LOG_MODULE_USER5 28
+#define NT_LOG_MODULE_USER6 29
+#define NT_LOG_MODULE_USER7 30
+#define NT_LOG_MODULE_USER8 31
+
+/* NT modules */
+#define NT_LOG_MODULE_GENERAL 10000    /* Should always be a first (smallest) 
*/
+#define NT_LOG_MODULE_NTHW 10001
+#define NT_LOG_MODULE_FILTER 10002
+#define NT_LOG_MODULE_DRV 10003
+#define NT_LOG_MODULE_VDPA 10004
+#define NT_LOG_MODULE_FPGA 10005
+#define NT_LOG_MODULE_NTCONNECT 10006
+#define NT_LOG_MODULE_ETHDEV 10007
+#define NT_LOG_MODULE_SENSOR 10008
+#define NT_LOG_MODULE_END 10009        /* Mark for the range end of NT_LOG */
+
+#define NT_LOG_MODULE_COUNT (NT_LOG_MODULE_END - NT_LOG_MODULE_GENERAL)
+#define NT_LOG_MODULE_INDEX(module) ((module) - (NT_LOG_MODULE_GENERAL))
+#define NT_LOG_MODULE_PREFIX(type) NT_LOG_MODULE_##type
+
+#endif
+
+#ifndef NT_LOG_ENABLE
+#define NT_LOG_ENABLE 1
+#endif
+
+#if defined NT_LOG_ENABLE && NT_LOG_ENABLE > 0
+#ifndef NT_LOG_ENABLE_ERR
+#define NT_LOG_ENABLE_ERR 1
+#endif
+#ifndef NT_LOG_ENABLE_WRN
+#define NT_LOG_ENABLE_WRN 1
+#endif
+#ifndef NT_LOG_ENABLE_INF
+#define NT_LOG_ENABLE_INF 1
+#endif
+#ifndef NT_LOG_ENABLE_DBG
+#define NT_LOG_ENABLE_DBG 1
+#endif
+#ifndef NT_LOG_ENABLE_DB1
+#define NT_LOG_ENABLE_DB1 0
+#endif
+#ifndef NT_LOG_ENABLE_DB2
+#define NT_LOG_ENABLE_DB2 0
+#endif
+#endif
+
+#if defined NT_LOG_ENABLE_ERR && NT_LOG_ENABLE_ERR > 0
+#define NT_LOG_NT_LOG_ERR(...) nt_log(__VA_ARGS__)
+#else
+#define NT_LOG_NT_LOG_ERR(...)
+#endif
+
+#if defined NT_LOG_ENABLE_WRN && NT_LOG_ENABLE_WRN > 0
+#define NT_LOG_NT_LOG_WRN(...) nt_log(__VA_ARGS__)
+#else
+#define NT_LOG_NT_LOG_WRN(...)
+#endif
+
+#if defined NT_LOG_ENABLE_INF && NT_LOG_ENABLE_INF > 0
+#define NT_LOG_NT_LOG_INF(...) nt_log(__VA_ARGS__)
+#else
+#define NT_LOG_NT_LOG_INF(...)
+#endif
+
+#if defined NT_LOG_ENABLE_DBG && NT_LOG_ENABLE_DBG > 0
+#define NT_LOG_NT_LOG_DBG(...) nt_log(__VA_ARGS__)
+#else
+#define NT_LOG_NT_LOG_DBG(...)
+#endif
+
+#if defined NT_LOG_ENABLE_DB1 && NT_LOG_ENABLE_DB1 > 0
+#define NT_LOG_NT_LOG_DB1(...) nt_log(__VA_ARGS__)
+#else
+#define NT_LOG_NT_LOG_DB1(...)
+#endif
+
+#if defined NT_LOG_ENABLE_DB2 && NT_LOG_ENABLE_DB2 > 0
+#define NT_LOG_NT_LOG_DB2(...) nt_log(__VA_ARGS__)
+#else
+#define NT_LOG_NT_LOG_DB2(...)
+#endif
+
+#define NT_LOG(level, module, ...)                                             
                   \
+       NT_LOG_NT_LOG_##level(NT_LOG_##level, NT_LOG_MODULE_PREFIX(module),     
                  \
+                             #module ": " #level ": " __VA_ARGS__)
+
+enum nt_log_level {
+       NT_LOG_ERR = 0x001,
+       NT_LOG_WRN = 0x002,
+       NT_LOG_INF = 0x004,
+       NT_LOG_DBG = 0x008,
+       NT_LOG_DB1 = 0x010,
+       NT_LOG_DB2 = 0x020,
+};
+
+struct nt_log_impl {
+       int (*init)(void);
+       int (*log)(enum nt_log_level level, uint32_t module, const char 
*format, va_list args);
+       int (*is_debug)(uint32_t module);
+};
+
+int nt_log_init(struct nt_log_impl *impl);
+
+int nt_log(enum nt_log_level level, uint32_t module, const char *format, ...);
+
+/* Returns 1 if RTE_DEBUG, 0 if lower log level, -1 if incorrect module */
+int nt_log_is_debug(uint32_t module);
+
+/*
+ * nt log helper functions
+ * to create a string for NT_LOG usage to output a one-liner log
+ * to use when one single function call to NT_LOG is not optimal - that is
+ * you do not know the number of parameters at programming time or it is 
variable
+ */
+char *ntlog_helper_str_alloc(const char *sinit);
+
+void ntlog_helper_str_add(char *s, const char *format, ...);
+
+void ntlog_helper_str_free(char *s);
+
+#endif /* NTOSS_SYSTEM_NTLOG_H */
diff --git a/drivers/net/ntnic/ntlog/ntlog.c b/drivers/net/ntnic/ntlog/ntlog.c
new file mode 100644
index 0000000000..a4f104efad
--- /dev/null
+++ b/drivers/net/ntnic/ntlog/ntlog.c
@@ -0,0 +1,108 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include "ntlog.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#define NTLOG_HELPER_STR_SIZE_MAX (1024)
+
+static struct nt_log_impl *user_impl;
+
+int nt_log_init(struct nt_log_impl *impl)
+{
+       user_impl = impl;
+       return user_impl->init();
+}
+
+static char *last_trailing_eol(char *s)
+{
+       int i = strlen(s) - 1;
+
+       /* Skip spaces */
+       while (i > 0 && s[i] == ' ')
+               --i;
+
+       if (s[i] != '\n')
+               return NULL;
+
+       /*
+        * Find the last trailing EOL "hello_world\n\n\n"
+        *                                         ^
+        */
+       while (i > 1 && s[i] == '\n' && s[i - 1] == '\n')
+               --i;
+
+       return &s[i];
+}
+
+/* Always terminates the NT_LOG statement with a !!!single!!! EOL. */
+int nt_log(enum nt_log_level level, uint32_t module, const char *format, ...)
+{
+       int rv = -1;
+       va_list args;
+
+       if (user_impl == NULL)
+               return rv;
+
+       char *actual_format = ntlog_helper_str_alloc(format);
+       char *eol = last_trailing_eol(actual_format);
+
+       if (!eol)       /* If log line is not terminated with '\n' we add it. */
+               strncat(actual_format, "\n", NTLOG_HELPER_STR_SIZE_MAX - 
strlen(actual_format));
+
+       else    /* If multiple trailing EOLs, then keep just one of them. */
+               *(eol + 1) = '\0';
+
+       va_start(args, format);
+       rv = user_impl->log(level, module, actual_format, args);
+       va_end(args);
+
+       ntlog_helper_str_free(actual_format);
+       return rv;
+}
+
+int nt_log_is_debug(uint32_t module)
+{
+       return user_impl->is_debug(module);
+}
+
+char *ntlog_helper_str_alloc(const char *sinit)
+{
+       char *s = malloc(NTLOG_HELPER_STR_SIZE_MAX);
+
+       if (!s)
+               return NULL;
+
+       if (sinit)
+               snprintf(s, NTLOG_HELPER_STR_SIZE_MAX, "%s", sinit);
+
+       else
+               s[0] = '\0';
+
+       return s;
+}
+
+void ntlog_helper_str_add(char *s, const char *format, ...)
+{
+       if (!s)
+               return;
+
+       va_list args;
+       va_start(args, format);
+       int len = strlen(s);
+       vsnprintf(&s[len], (NTLOG_HELPER_STR_SIZE_MAX - 1 - len), format, args);
+       va_end(args);
+}
+
+void ntlog_helper_str_free(char *s)
+{
+       free(s);
+}
diff --git a/drivers/net/ntnic/ntutil/include/nt_util.h 
b/drivers/net/ntnic/ntutil/include/nt_util.h
new file mode 100644
index 0000000000..0f27698a84
--- /dev/null
+++ b/drivers/net/ntnic/ntutil/include/nt_util.h
@@ -0,0 +1,51 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#ifndef NTOSS_SYSTEM_NT_UTIL_H
+#define NTOSS_SYSTEM_NT_UTIL_H
+
+#include <stdint.h>
+
+/*
+ * Windows size in seconds for measuring FLM load
+ * and Port load.
+ * The windows size must max be 3 min in order to
+ * prevent overflow.
+ */
+#define FLM_LOAD_WINDOWS_SIZE 2ULL
+#define PORT_LOAD_WINDOWS_SIZE 2ULL
+
+/* Total max VDPA ports */
+#define MAX_VDPA_PORTS 128UL
+
+#define PCIIDENT_TO_DOMAIN(pci_ident) ((uint16_t)(((unsigned int)(pci_ident) 
>> 16) & 0xFFFFU))
+#define PCIIDENT_TO_BUSNR(pci_ident) ((uint8_t)(((unsigned int)(pci_ident) >> 
8) & 0xFFU))
+#define PCIIDENT_TO_DEVNR(pci_ident) ((uint8_t)(((unsigned int)(pci_ident) >> 
3) & 0x1FU))
+#define PCIIDENT_TO_FUNCNR(pci_ident) ((uint8_t)(((unsigned int)(pci_ident) >> 
0) & 0x7U))
+#define PCIIDENT_PRINT_STR "%04x:%02x:%02x.%x"
+#define BDF_TO_PCIIDENT(dom, bus, dev, fnc) (((dom) << 16) | ((bus) << 8) | 
((dev) << 3) | (fnc))
+
+uint64_t nt_os_get_time_monotonic_counter(void);
+void nt_os_wait_usec(int val);
+
+uint64_t nt_util_align_size(uint64_t size);
+
+struct nt_dma_s {
+       uint64_t iova;
+       uint64_t addr;
+       uint64_t size;
+};
+
+struct nt_dma_s *nt_dma_alloc(uint64_t size, uint64_t align, int numa);
+void nt_dma_free(struct nt_dma_s *vfio_addr);
+
+struct nt_util_vfio_impl {
+       int (*vfio_dma_map)(int vf_num, void *virt_addr, uint64_t *iova_addr, 
uint64_t size);
+       int (*vfio_dma_unmap)(int vf_num, void *virt_addr, uint64_t iova_addr, 
uint64_t size);
+};
+
+void nt_util_vfio_init(struct nt_util_vfio_impl *impl);
+
+#endif /* NTOSS_SYSTEM_NT_UTIL_H */
diff --git a/drivers/net/ntnic/ntutil/nt_util.c 
b/drivers/net/ntnic/ntutil/nt_util.c
new file mode 100644
index 0000000000..e4b18c1a7e
--- /dev/null
+++ b/drivers/net/ntnic/ntutil/nt_util.c
@@ -0,0 +1,98 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <rte_cycles.h>
+#include "rte_malloc.h"
+
+#include "ntlog.h"
+#include "nt_util.h"
+
+static struct nt_util_vfio_impl vfio_cb;
+
+/* uses usleep which schedules out the calling thread */
+void nt_os_wait_usec(int val)
+{
+       rte_delay_us_sleep(val);
+}
+
+uint64_t nt_os_get_time_monotonic_counter(void)
+{
+       return rte_get_timer_cycles();
+}
+
+/* Allocation size matching minimum alignment of specified size */
+uint64_t nt_util_align_size(uint64_t size)
+{
+       return 1 << rte_log2_u64(size);
+}
+
+void nt_util_vfio_init(struct nt_util_vfio_impl *impl)
+{
+       vfio_cb = *impl;
+}
+
+struct nt_dma_s *nt_dma_alloc(uint64_t size, uint64_t align, int numa)
+{
+       int res;
+       struct nt_dma_s *vfio_addr;
+
+       vfio_addr = rte_malloc(NULL, sizeof(struct nt_dma_s), 0);
+
+       if (!vfio_addr) {
+               NT_LOG(ERR, GENERAL, "VFIO rte_malloc failed\n");
+               return NULL;
+       }
+
+       void *addr = rte_malloc_socket(NULL, size, align, numa);
+
+       if (!addr) {
+               rte_free(vfio_addr);
+               NT_LOG(ERR, GENERAL, "VFIO rte_malloc_socket failed\n");
+               return NULL;
+       }
+
+       res = vfio_cb.vfio_dma_map(0, addr, &vfio_addr->iova, 
nt_util_align_size(size));
+
+       if (res != 0) {
+               rte_free(addr);
+               rte_free(vfio_addr);
+               NT_LOG(ERR, GENERAL, "VFIO nt_dma_map failed\n");
+               return NULL;
+       }
+
+       vfio_addr->addr = (uint64_t)addr;
+       vfio_addr->size = nt_util_align_size(size);
+
+       NT_LOG(DBG, GENERAL,
+               "VFIO DMA alloc addr=%" PRIX64 ", iova=%" PRIX64 ", size=%u, 
align=0x%X\n",
+               vfio_addr->addr, vfio_addr->iova, vfio_addr->size, align);
+
+       return vfio_addr;
+}
+
+void nt_dma_free(struct nt_dma_s *vfio_addr)
+{
+       NT_LOG(DBG, GENERAL, "VFIO DMA free addr=%" PRIX64 ", iova=%" PRIX64 ", 
size=%u\n",
+               vfio_addr->addr, vfio_addr->iova, vfio_addr->size);
+
+       int res = vfio_cb.vfio_dma_unmap(0, (void *)vfio_addr->addr, 
vfio_addr->iova,
+                       vfio_addr->size);
+
+       if (res != 0) {
+               NT_LOG(WRN, GENERAL,
+                       "VFIO DMA free FAILED addr=%" PRIX64 ", iova=%" PRIX64 
", size=%u\n",
+                       vfio_addr->addr, vfio_addr->iova, vfio_addr->size);
+       }
+
+       rte_free((void *)(vfio_addr->addr));
+       rte_free(vfio_addr);
+}
-- 
2.44.0

Reply via email to