From: Hemant Agrawal Date: Thu, 10 Oct 2019 06:32:21 +0000 (+0530) Subject: common/dpaax: move OF library from DPAA bus X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=8c83f28cc8a4dc7ee0fab676051dd483695d4140;p=dpdk.git common/dpaax: move OF library from DPAA bus This code is being shared by more than 1 type of driver. Common is most appropriate place for it. Signed-off-by: Hemant Agrawal --- diff --git a/drivers/bus/dpaa/Makefile b/drivers/bus/dpaa/Makefile index dfc2717a4e..454ac12bf3 100644 --- a/drivers/bus/dpaa/Makefile +++ b/drivers/bus/dpaa/Makefile @@ -17,6 +17,7 @@ CFLAGS += -Wno-cast-qual CFLAGS += -I$(RTE_BUS_DPAA)/ CFLAGS += -I$(RTE_BUS_DPAA)/include CFLAGS += -I$(RTE_BUS_DPAA)/base/qbman +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include # versioning export map @@ -32,7 +33,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += \ SRCS-$(CONFIG_RTE_LIBRTE_DPAA_BUS) += \ base/fman/fman.c \ base/fman/fman_hw.c \ - base/fman/of.c \ base/fman/netcfg_layer.c \ base/qbman/process.c \ base/qbman/bman.c \ diff --git a/drivers/bus/dpaa/base/fman/fman.c b/drivers/bus/dpaa/base/fman/fman.c index 8fa9b8caef..462efd2d4b 100644 --- a/drivers/bus/dpaa/base/fman/fman.c +++ b/drivers/bus/dpaa/base/fman/fman.c @@ -11,7 +11,7 @@ /* This header declares the driver interface we implement */ #include -#include +#include #include #include #include diff --git a/drivers/bus/dpaa/base/fman/netcfg_layer.c b/drivers/bus/dpaa/base/fman/netcfg_layer.c index bf8c77265f..6affd2e922 100644 --- a/drivers/bus/dpaa/base/fman/netcfg_layer.c +++ b/drivers/bus/dpaa/base/fman/netcfg_layer.c @@ -5,7 +5,7 @@ * */ #include -#include +#include #include #include #include diff --git a/drivers/bus/dpaa/base/fman/of.c b/drivers/bus/dpaa/base/fman/of.c deleted file mode 100644 index 1e97be54e9..0000000000 --- a/drivers/bus/dpaa/base/fman/of.c +++ /dev/null @@ -1,588 +0,0 @@ -/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) - * - * Copyright 2010-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP - * - */ - -#include -#include -#include - -static int alive; -static struct dt_dir root_dir; -static const char *base_dir; -static COMPAT_LIST_HEAD(linear); - -static int -of_open_dir(const char *relative_path, struct dirent ***d) -{ - int ret; - char full_path[PATH_MAX]; - - snprintf(full_path, PATH_MAX, "%s/%s", base_dir, relative_path); - ret = scandir(full_path, d, 0, versionsort); - if (ret < 0) - DPAA_BUS_LOG(ERR, "Failed to open directory %s", - full_path); - return ret; -} - -static void -of_close_dir(struct dirent **d, int num) -{ - while (num--) - free(d[num]); - free(d); -} - -static int -of_open_file(const char *relative_path) -{ - int ret; - char full_path[PATH_MAX]; - - snprintf(full_path, PATH_MAX, "%s/%s", base_dir, relative_path); - ret = open(full_path, O_RDONLY); - if (ret < 0) - DPAA_BUS_LOG(ERR, "Failed to open directory %s", - full_path); - return ret; -} - -static void -process_file(struct dirent *dent, struct dt_dir *parent) -{ - int fd; - struct dt_file *f = malloc(sizeof(*f)); - - if (!f) { - DPAA_BUS_LOG(DEBUG, "Unable to allocate memory for file node"); - return; - } - f->node.is_file = 1; - strlcpy(f->node.node.name, dent->d_name, NAME_MAX); - snprintf(f->node.node.full_name, PATH_MAX, "%s/%s", - parent->node.node.full_name, dent->d_name); - f->parent = parent; - fd = of_open_file(f->node.node.full_name); - if (fd < 0) { - DPAA_BUS_LOG(DEBUG, "Unable to open file node"); - free(f); - return; - } - f->len = read(fd, f->buf, OF_FILE_BUF_MAX); - close(fd); - if (f->len < 0) { - DPAA_BUS_LOG(DEBUG, "Unable to read file node"); - free(f); - return; - } - list_add_tail(&f->node.list, &parent->files); -} - -static const struct dt_dir * -node2dir(const struct device_node *n) -{ - struct dt_node *dn = container_of((struct device_node *)n, - struct dt_node, node); - const struct dt_dir *d = container_of(dn, struct dt_dir, node); - - assert(!dn->is_file); - return d; -} - -/* process_dir() calls iterate_dir(), but the latter will also call the former - * when recursing into sub-directories, so a predeclaration is needed. - */ -static int process_dir(const char *relative_path, struct dt_dir *dt); - -static int -iterate_dir(struct dirent **d, int num, struct dt_dir *dt) -{ - int loop; - /* Iterate the directory contents */ - for (loop = 0; loop < num; loop++) { - struct dt_dir *subdir; - int ret; - /* Ignore dot files of all types (especially "..") */ - if (d[loop]->d_name[0] == '.') - continue; - switch (d[loop]->d_type) { - case DT_REG: - process_file(d[loop], dt); - break; - case DT_DIR: - subdir = malloc(sizeof(*subdir)); - if (!subdir) { - perror("malloc"); - return -ENOMEM; - } - strlcpy(subdir->node.node.name, d[loop]->d_name, - NAME_MAX); - snprintf(subdir->node.node.full_name, PATH_MAX, - "%s/%s", dt->node.node.full_name, - d[loop]->d_name); - subdir->parent = dt; - ret = process_dir(subdir->node.node.full_name, subdir); - if (ret) - return ret; - list_add_tail(&subdir->node.list, &dt->subdirs); - break; - default: - DPAA_BUS_LOG(DEBUG, "Ignoring invalid dt entry %s/%s", - dt->node.node.full_name, d[loop]->d_name); - } - } - return 0; -} - -static int -process_dir(const char *relative_path, struct dt_dir *dt) -{ - struct dirent **d; - int ret, num; - - dt->node.is_file = 0; - INIT_LIST_HEAD(&dt->subdirs); - INIT_LIST_HEAD(&dt->files); - ret = of_open_dir(relative_path, &d); - if (ret < 0) - return ret; - num = ret; - ret = iterate_dir(d, num, dt); - of_close_dir(d, num); - return (ret < 0) ? ret : 0; -} - -static void -linear_dir(struct dt_dir *d) -{ - struct dt_file *f; - struct dt_dir *dd; - - d->compatible = NULL; - d->status = NULL; - d->lphandle = NULL; - d->a_cells = NULL; - d->s_cells = NULL; - d->reg = NULL; - list_for_each_entry(f, &d->files, node.list) { - if (!strcmp(f->node.node.name, "compatible")) { - if (d->compatible) - DPAA_BUS_LOG(DEBUG, "Duplicate compatible in" - " %s", d->node.node.full_name); - d->compatible = f; - } else if (!strcmp(f->node.node.name, "status")) { - if (d->status) - DPAA_BUS_LOG(DEBUG, "Duplicate status in %s", - d->node.node.full_name); - d->status = f; - } else if (!strcmp(f->node.node.name, "linux,phandle")) { - if (d->lphandle) - DPAA_BUS_LOG(DEBUG, "Duplicate lphandle in %s", - d->node.node.full_name); - d->lphandle = f; - } else if (!strcmp(f->node.node.name, "phandle")) { - if (d->lphandle) - DPAA_BUS_LOG(DEBUG, "Duplicate lphandle in %s", - d->node.node.full_name); - d->lphandle = f; - } else if (!strcmp(f->node.node.name, "#address-cells")) { - if (d->a_cells) - DPAA_BUS_LOG(DEBUG, "Duplicate a_cells in %s", - d->node.node.full_name); - d->a_cells = f; - } else if (!strcmp(f->node.node.name, "#size-cells")) { - if (d->s_cells) - DPAA_BUS_LOG(DEBUG, "Duplicate s_cells in %s", - d->node.node.full_name); - d->s_cells = f; - } else if (!strcmp(f->node.node.name, "reg")) { - if (d->reg) - DPAA_BUS_LOG(DEBUG, "Duplicate reg in %s", - d->node.node.full_name); - d->reg = f; - } - } - - list_for_each_entry(dd, &d->subdirs, node.list) { - list_add_tail(&dd->linear, &linear); - linear_dir(dd); - } -} - -int -of_init_path(const char *dt_path) -{ - int ret; - - base_dir = dt_path; - - /* This needs to be singleton initialization */ - DPAA_BUS_HWWARN(alive, "Double-init of device-tree driver!"); - - /* Prepare root node (the remaining fields are set in process_dir()) */ - root_dir.node.node.name[0] = '\0'; - root_dir.node.node.full_name[0] = '\0'; - INIT_LIST_HEAD(&root_dir.node.list); - root_dir.parent = NULL; - - /* Kick things off... */ - ret = process_dir("", &root_dir); - if (ret) { - DPAA_BUS_LOG(ERR, "Unable to parse device tree"); - return ret; - } - - /* Now make a flat, linear list of directories */ - linear_dir(&root_dir); - alive = 1; - return 0; -} - -static void -destroy_dir(struct dt_dir *d) -{ - struct dt_file *f, *tmpf; - struct dt_dir *dd, *tmpd; - - list_for_each_entry_safe(f, tmpf, &d->files, node.list) { - list_del(&f->node.list); - free(f); - } - list_for_each_entry_safe(dd, tmpd, &d->subdirs, node.list) { - destroy_dir(dd); - list_del(&dd->node.list); - free(dd); - } -} - -void -of_finish(void) -{ - DPAA_BUS_HWWARN(!alive, "Double-finish of device-tree driver!"); - - destroy_dir(&root_dir); - INIT_LIST_HEAD(&linear); - alive = 0; -} - -static const struct dt_dir * -next_linear(const struct dt_dir *f) -{ - if (f->linear.next == &linear) - return NULL; - return list_entry(f->linear.next, struct dt_dir, linear); -} - -static int -check_compatible(const struct dt_file *f, const char *compatible) -{ - const char *c = (char *)f->buf; - unsigned int len, remains = f->len; - - while (remains) { - len = strlen(c); - if (!strcmp(c, compatible)) - return 1; - - if (remains < len + 1) - break; - - c += (len + 1); - remains -= (len + 1); - } - return 0; -} - -const struct device_node * -of_find_compatible_node(const struct device_node *from, - const char *type __always_unused, - const char *compatible) -{ - const struct dt_dir *d; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - - if (list_empty(&linear)) - return NULL; - if (!from) - d = list_entry(linear.next, struct dt_dir, linear); - else - d = node2dir(from); - for (d = next_linear(d); d && (!d->compatible || - !check_compatible(d->compatible, - compatible)); - d = next_linear(d)) - ; - if (d) - return &d->node.node; - return NULL; -} - -const void * -of_get_property(const struct device_node *from, const char *name, - size_t *lenp) -{ - const struct dt_dir *d; - const struct dt_file *f; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - - d = node2dir(from); - list_for_each_entry(f, &d->files, node.list) - if (!strcmp(f->node.node.name, name)) { - if (lenp) - *lenp = f->len; - return f->buf; - } - return NULL; -} - -bool -of_device_is_available(const struct device_node *dev_node) -{ - const struct dt_dir *d; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - d = node2dir(dev_node); - if (!d->status) - return true; - if (!strcmp((char *)d->status->buf, "okay")) - return true; - if (!strcmp((char *)d->status->buf, "ok")) - return true; - return false; -} - -const struct device_node * -of_find_node_by_phandle(phandle ph) -{ - const struct dt_dir *d; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - list_for_each_entry(d, &linear, linear) - if (d->lphandle && (d->lphandle->len == 4) && - !memcmp(d->lphandle->buf, &ph, 4)) - return &d->node.node; - return NULL; -} - -const struct device_node * -of_get_parent(const struct device_node *dev_node) -{ - const struct dt_dir *d; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - - if (!dev_node) - return NULL; - d = node2dir(dev_node); - if (!d->parent) - return NULL; - return &d->parent->node.node; -} - -const struct device_node * -of_get_next_child(const struct device_node *dev_node, - const struct device_node *prev) -{ - const struct dt_dir *p, *c; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - - if (!dev_node) - return NULL; - p = node2dir(dev_node); - if (prev) { - c = node2dir(prev); - DPAA_BUS_HWWARN((c->parent != p), "Parent/child mismatch"); - if (c->parent != p) - return NULL; - if (c->node.list.next == &p->subdirs) - /* prev was the last child */ - return NULL; - c = list_entry(c->node.list.next, struct dt_dir, node.list); - return &c->node.node; - } - /* Return first child */ - if (list_empty(&p->subdirs)) - return NULL; - c = list_entry(p->subdirs.next, struct dt_dir, node.list); - return &c->node.node; -} - -uint32_t -of_n_addr_cells(const struct device_node *dev_node) -{ - const struct dt_dir *d; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised"); - if (!dev_node) - return OF_DEFAULT_NA; - d = node2dir(dev_node); - while ((d = d->parent)) - if (d->a_cells) { - unsigned char *buf = - (unsigned char *)&d->a_cells->buf[0]; - assert(d->a_cells->len == 4); - return ((uint32_t)buf[0] << 24) | - ((uint32_t)buf[1] << 16) | - ((uint32_t)buf[2] << 8) | - (uint32_t)buf[3]; - } - return OF_DEFAULT_NA; -} - -uint32_t -of_n_size_cells(const struct device_node *dev_node) -{ - const struct dt_dir *d; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - if (!dev_node) - return OF_DEFAULT_NA; - d = node2dir(dev_node); - while ((d = d->parent)) - if (d->s_cells) { - unsigned char *buf = - (unsigned char *)&d->s_cells->buf[0]; - assert(d->s_cells->len == 4); - return ((uint32_t)buf[0] << 24) | - ((uint32_t)buf[1] << 16) | - ((uint32_t)buf[2] << 8) | - (uint32_t)buf[3]; - } - return OF_DEFAULT_NS; -} - -const uint32_t * -of_get_address(const struct device_node *dev_node, size_t idx, - uint64_t *size, uint32_t *flags __rte_unused) -{ - const struct dt_dir *d; - const unsigned char *buf; - uint32_t na = of_n_addr_cells(dev_node); - uint32_t ns = of_n_size_cells(dev_node); - - if (!dev_node) - d = &root_dir; - else - d = node2dir(dev_node); - if (!d->reg) - return NULL; - assert(d->reg->len % ((na + ns) * 4) == 0); - assert(d->reg->len / ((na + ns) * 4) > (unsigned int) idx); - buf = (const unsigned char *)&d->reg->buf[0]; - buf += (na + ns) * idx * 4; - if (size) - for (*size = 0; ns > 0; ns--, na++) - *size = (*size << 32) + - (((uint32_t)buf[4 * na] << 24) | - ((uint32_t)buf[4 * na + 1] << 16) | - ((uint32_t)buf[4 * na + 2] << 8) | - (uint32_t)buf[4 * na + 3]); - return (const uint32_t *)buf; -} - -uint64_t -of_translate_address(const struct device_node *dev_node, - const uint32_t *addr) -{ - uint64_t phys_addr, tmp_addr; - const struct device_node *parent; - const uint32_t *ranges; - size_t rlen; - uint32_t na, pna; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - assert(dev_node != NULL); - - na = of_n_addr_cells(dev_node); - phys_addr = of_read_number(addr, na); - - dev_node = of_get_parent(dev_node); - if (!dev_node) - return 0; - else if (node2dir(dev_node) == &root_dir) - return phys_addr; - - do { - pna = of_n_addr_cells(dev_node); - parent = of_get_parent(dev_node); - if (!parent) - return 0; - - ranges = of_get_property(dev_node, "ranges", &rlen); - /* "ranges" property is missing. Translation breaks */ - if (!ranges) - return 0; - /* "ranges" property is empty. Do 1:1 translation */ - else if (rlen == 0) - continue; - else - tmp_addr = of_read_number(ranges + na, pna); - - na = pna; - dev_node = parent; - phys_addr += tmp_addr; - } while (node2dir(parent) != &root_dir); - - return phys_addr; -} - -bool -of_device_is_compatible(const struct device_node *dev_node, - const char *compatible) -{ - const struct dt_dir *d; - - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); - if (!dev_node) - d = &root_dir; - else - d = node2dir(dev_node); - if (d->compatible && check_compatible(d->compatible, compatible)) - return true; - return false; -} - -static const void *of_get_mac_addr(const struct device_node *np, - const char *name) -{ - return of_get_property(np, name, NULL); -} - -/** - * Search the device tree for the best MAC address to use. 'mac-address' is - * checked first, because that is supposed to contain to "most recent" MAC - * address. If that isn't set, then 'local-mac-address' is checked next, - * because that is the default address. If that isn't set, then the obsolete - * 'address' is checked, just in case we're using an old device tree. - * - * Note that the 'address' property is supposed to contain a virtual address of - * the register set, but some DTS files have redefined that property to be the - * MAC address. - * - * All-zero MAC addresses are rejected, because those could be properties that - * exist in the device tree, but were not set by U-Boot. For example, the - * DTS could define 'mac-address' and 'local-mac-address', with zero MAC - * addresses. Some older U-Boots only initialized 'local-mac-address'. In - * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists - * but is all zeros. - */ -const void *of_get_mac_address(const struct device_node *np) -{ - const void *addr; - - addr = of_get_mac_addr(np, "mac-address"); - if (addr) - return addr; - - addr = of_get_mac_addr(np, "local-mac-address"); - if (addr) - return addr; - - return of_get_mac_addr(np, "address"); -} diff --git a/drivers/bus/dpaa/base/qbman/dpaa_sys.h b/drivers/bus/dpaa/base/qbman/dpaa_sys.h index 034991ba1b..9377738dfa 100644 --- a/drivers/bus/dpaa/base/qbman/dpaa_sys.h +++ b/drivers/bus/dpaa/base/qbman/dpaa_sys.h @@ -8,7 +8,8 @@ #ifndef __DPAA_SYS_H #define __DPAA_SYS_H -#include +#include +#include /* For 2-element tables related to cache-inhibited and cache-enabled mappings */ #define DPAA_PORTAL_CE 0 diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c index 770e43f177..b53eb9e5ee 100644 --- a/drivers/bus/dpaa/base/qbman/qman.c +++ b/drivers/bus/dpaa/base/qbman/qman.c @@ -11,6 +11,8 @@ #include #include +#include + /* Compilation constants */ #define DQRR_MAXFILL 15 #define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */ diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c index 1d8a294b1b..d028ef3bef 100644 --- a/drivers/bus/dpaa/dpaa_bus.c +++ b/drivers/bus/dpaa/dpaa_bus.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -39,7 +40,6 @@ #include #include #include -#include #include int dpaa_logtype_bus; diff --git a/drivers/bus/dpaa/include/compat.h b/drivers/bus/dpaa/include/compat.h deleted file mode 100644 index 277ce63696..0000000000 --- a/drivers/bus/dpaa/include/compat.h +++ /dev/null @@ -1,396 +0,0 @@ -/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) - * - * Copyright 2011 Freescale Semiconductor, Inc. - * All rights reserved. - * Copyright 2019 NXP - * - */ - -#ifndef __COMPAT_H -#define __COMPAT_H - -#include - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* The following definitions are primarily to allow the single-source driver - * interfaces to be included by arbitrary program code. Ie. for interfaces that - * are also available in kernel-space, these definitions provide compatibility - * with certain attributes and types used in those interfaces. - */ - -/* Required compiler attributes */ -#ifndef __maybe_unused -#define __maybe_unused __rte_unused -#endif -#ifndef __always_unused -#define __always_unused __rte_unused -#endif -#ifndef __packed -#define __packed __rte_packed -#endif -#ifndef noinline -#define noinline __attribute__((noinline)) -#endif -#define L1_CACHE_BYTES 64 -#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) -#define __stringify_1(x) #x -#define __stringify(x) __stringify_1(x) - -#ifdef ARRAY_SIZE -#undef ARRAY_SIZE -#endif -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -/* Debugging */ -#define prflush(fmt, args...) \ - do { \ - printf(fmt, ##args); \ - fflush(stdout); \ - } while (0) -#ifndef pr_crit -#define pr_crit(fmt, args...) prflush("CRIT:" fmt, ##args) -#endif -#ifndef pr_err -#define pr_err(fmt, args...) prflush("ERR:" fmt, ##args) -#endif -#ifndef pr_warn -#define pr_warn(fmt, args...) prflush("WARN:" fmt, ##args) -#endif -#ifndef pr_info -#define pr_info(fmt, args...) prflush(fmt, ##args) -#endif -#ifndef pr_debug -#ifdef RTE_LIBRTE_DPAA_DEBUG_BUS -#define pr_debug(fmt, args...) printf(fmt, ##args) -#else -#define pr_debug(fmt, args...) {} -#endif -#endif - -#define DPAA_BUG_ON(x) RTE_ASSERT(x) - -/* Required types */ -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef uint64_t dma_addr_t; -typedef cpu_set_t cpumask_t; -typedef uint32_t phandle; -typedef uint32_t gfp_t; -typedef uint32_t irqreturn_t; - -#define ETHER_ADDR_LEN 6 - -#define IRQ_HANDLED 0 -#define request_irq qbman_request_irq -#define free_irq qbman_free_irq - -#define __iomem -#define GFP_KERNEL 0 -#define __raw_readb(p) (*(const volatile unsigned char *)(p)) -#define __raw_readl(p) (*(const volatile unsigned int *)(p)) -#define __raw_writel(v, p) {*(volatile unsigned int *)(p) = (v); } - -/* to be used as an upper-limit only */ -#define NR_CPUS 64 - -/* Waitqueue stuff */ -typedef struct { } wait_queue_head_t; -#define DECLARE_WAIT_QUEUE_HEAD(x) int dummy_##x __always_unused -#define wake_up(x) do { } while (0) - -/* I/O operations */ -static inline u32 in_be32(volatile void *__p) -{ - volatile u32 *p = __p; - return rte_be_to_cpu_32(*p); -} - -static inline void out_be32(volatile void *__p, u32 val) -{ - volatile u32 *p = __p; - *p = rte_cpu_to_be_32(val); -} - -#define hwsync() rte_rmb() -#define lwsync() rte_wmb() - -#define dcbt_ro(p) __builtin_prefetch(p, 0) -#define dcbt_rw(p) __builtin_prefetch(p, 1) - -#if defined(RTE_ARCH_ARM64) -#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); } -#define dcbz_64(p) dcbz(p) -#define dcbf(p) { asm volatile("dc cvac, %0" : : "r"(p) : "memory"); } -#define dcbf_64(p) dcbf(p) -#define dccivac(p) { asm volatile("dc civac, %0" : : "r"(p) : "memory"); } - -#define dcbit_ro(p) \ - do { \ - dccivac(p); \ - asm volatile("prfm pldl1keep, [%0, #64]" : : "r" (p)); \ - } while (0) - -#elif defined(RTE_ARCH_ARM) -#define dcbz(p) memset((p), 0, 32) -#define dcbz_64(p) memset((p), 0, 64) -#define dcbf(p) RTE_SET_USED(p) -#define dcbf_64(p) dcbf(p) -#define dccivac(p) RTE_SET_USED(p) -#define dcbit_ro(p) RTE_SET_USED(p) - -#else -#define dcbz(p) RTE_SET_USED(p) -#define dcbz_64(p) dcbz(p) -#define dcbf(p) RTE_SET_USED(p) -#define dcbf_64(p) dcbf(p) -#define dccivac(p) RTE_SET_USED(p) -#define dcbit_ro(p) RTE_SET_USED(p) -#endif - -#define barrier() { asm volatile ("" : : : "memory"); } -#define cpu_relax barrier - -#if defined(RTE_ARCH_ARM64) -static inline uint64_t mfatb(void) -{ - uint64_t ret, ret_new, timeout = 200; - - asm volatile ("mrs %0, cntvct_el0" : "=r" (ret)); - asm volatile ("mrs %0, cntvct_el0" : "=r" (ret_new)); - while (ret != ret_new && timeout--) { - ret = ret_new; - asm volatile ("mrs %0, cntvct_el0" : "=r" (ret_new)); - } - DPAA_BUG_ON(!timeout && (ret != ret_new)); - return ret * 64; -} -#else - -#define mfatb rte_rdtsc - -#endif - -/* Spin for a few cycles without bothering the bus */ -static inline void cpu_spin(int cycles) -{ - uint64_t now = mfatb(); - - while (mfatb() < (now + cycles)) - ; -} - -/* Qman/Bman API inlines and macros; */ -#ifdef lower_32_bits -#undef lower_32_bits -#endif -#define lower_32_bits(x) ((u32)(x)) - -#ifdef upper_32_bits -#undef upper_32_bits -#endif -#define upper_32_bits(x) ((u32)(((x) >> 16) >> 16)) - -/* - * Swap bytes of a 48-bit value. - */ -static inline uint64_t -__bswap_48(uint64_t x) -{ - return ((x & 0x0000000000ffULL) << 40) | - ((x & 0x00000000ff00ULL) << 24) | - ((x & 0x000000ff0000ULL) << 8) | - ((x & 0x0000ff000000ULL) >> 8) | - ((x & 0x00ff00000000ULL) >> 24) | - ((x & 0xff0000000000ULL) >> 40); -} - -/* - * Swap bytes of a 40-bit value. - */ -static inline uint64_t -__bswap_40(uint64_t x) -{ - return ((x & 0x00000000ffULL) << 32) | - ((x & 0x000000ff00ULL) << 16) | - ((x & 0x0000ff0000ULL)) | - ((x & 0x00ff000000ULL) >> 16) | - ((x & 0xff00000000ULL) >> 32); -} - -/* - * Swap bytes of a 24-bit value. - */ -static inline uint32_t -__bswap_24(uint32_t x) -{ - return ((x & 0x0000ffULL) << 16) | - ((x & 0x00ff00ULL)) | - ((x & 0xff0000ULL) >> 16); -} - -#define be64_to_cpu(x) rte_be_to_cpu_64(x) -#define be32_to_cpu(x) rte_be_to_cpu_32(x) -#define be16_to_cpu(x) rte_be_to_cpu_16(x) - -#define cpu_to_be64(x) rte_cpu_to_be_64(x) -#if !defined(cpu_to_be32) -#define cpu_to_be32(x) rte_cpu_to_be_32(x) -#endif -#define cpu_to_be16(x) rte_cpu_to_be_16(x) - -#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN - -#define cpu_to_be48(x) __bswap_48(x) -#define be48_to_cpu(x) __bswap_48(x) - -#define cpu_to_be40(x) __bswap_40(x) -#define be40_to_cpu(x) __bswap_40(x) - -#define cpu_to_be24(x) __bswap_24(x) -#define be24_to_cpu(x) __bswap_24(x) - -#else /* RTE_BIG_ENDIAN */ - -#define cpu_to_be48(x) (x) -#define be48_to_cpu(x) (x) - -#define cpu_to_be40(x) (x) -#define be40_to_cpu(x) (x) - -#define cpu_to_be24(x) (x) -#define be24_to_cpu(x) (x) - -#endif /* RTE_BIG_ENDIAN */ - -/* When copying aligned words or shorts, try to avoid memcpy() */ -/* memcpy() stuff - when you know alignments in advance */ -#define CONFIG_TRY_BETTER_MEMCPY - -#ifdef CONFIG_TRY_BETTER_MEMCPY -static inline void copy_words(void *dest, const void *src, size_t sz) -{ - u32 *__dest = dest; - const u32 *__src = src; - size_t __sz = sz >> 2; - - DPAA_BUG_ON((unsigned long)dest & 0x3); - DPAA_BUG_ON((unsigned long)src & 0x3); - DPAA_BUG_ON(sz & 0x3); - while (__sz--) - *(__dest++) = *(__src++); -} - -static inline void copy_shorts(void *dest, const void *src, size_t sz) -{ - u16 *__dest = dest; - const u16 *__src = src; - size_t __sz = sz >> 1; - - DPAA_BUG_ON((unsigned long)dest & 0x1); - DPAA_BUG_ON((unsigned long)src & 0x1); - DPAA_BUG_ON(sz & 0x1); - while (__sz--) - *(__dest++) = *(__src++); -} - -static inline void copy_bytes(void *dest, const void *src, size_t sz) -{ - u8 *__dest = dest; - const u8 *__src = src; - - while (sz--) - *(__dest++) = *(__src++); -} -#else -#define copy_words memcpy -#define copy_shorts memcpy -#define copy_bytes memcpy -#endif - -/* Allocator stuff */ -#define kmalloc(sz, t) rte_malloc(NULL, sz, 0) -#define vmalloc(sz) rte_malloc(NULL, sz, 0) -#define kfree(p) { if (p) rte_free(p); } -static inline void *kzalloc(size_t sz, gfp_t __foo __rte_unused) -{ - void *ptr = rte_malloc(NULL, sz, 0); - - if (ptr) - memset(ptr, 0, sz); - return ptr; -} - -static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused) -{ - void *p; - - if (posix_memalign(&p, 4096, 4096)) - return 0; - memset(p, 0, 4096); - return (unsigned long)p; -} - -/* Spinlock stuff */ -#define spinlock_t rte_spinlock_t -#define __SPIN_LOCK_UNLOCKED(x) RTE_SPINLOCK_INITIALIZER -#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) -#define spin_lock_init(x) rte_spinlock_init(x) -#define spin_lock_destroy(x) -#define spin_lock(x) rte_spinlock_lock(x) -#define spin_unlock(x) rte_spinlock_unlock(x) -#define spin_lock_irq(x) spin_lock(x) -#define spin_unlock_irq(x) spin_unlock(x) -#define spin_lock_irqsave(x, f) spin_lock_irq(x) -#define spin_unlock_irqrestore(x, f) spin_unlock_irq(x) - -#define atomic_t rte_atomic32_t -#define atomic_read(v) rte_atomic32_read(v) -#define atomic_set(v, i) rte_atomic32_set(v, i) - -#define atomic_inc(v) rte_atomic32_add(v, 1) -#define atomic_dec(v) rte_atomic32_sub(v, 1) - -#define atomic_inc_and_test(v) rte_atomic32_inc_and_test(v) -#define atomic_dec_and_test(v) rte_atomic32_dec_and_test(v) - -#define atomic_inc_return(v) rte_atomic32_add_return(v, 1) -#define atomic_dec_return(v) rte_atomic32_sub_return(v, 1) -#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0) - -#include -#include - -#endif /* __COMPAT_H */ diff --git a/drivers/bus/dpaa/include/dpaa_list.h b/drivers/bus/dpaa/include/dpaa_list.h deleted file mode 100644 index e94575982b..0000000000 --- a/drivers/bus/dpaa/include/dpaa_list.h +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright 2017 NXP - * - */ - -#ifndef __DPAA_LIST_H -#define __DPAA_LIST_H - -/****************/ -/* Linked-lists */ -/****************/ - -struct list_head { - struct list_head *prev; - struct list_head *next; -}; - -#define COMPAT_LIST_HEAD(n) \ -struct list_head n = { \ - .prev = &n, \ - .next = &n \ -} - -#define INIT_LIST_HEAD(p) \ -do { \ - struct list_head *__p298 = (p); \ - __p298->next = __p298; \ - __p298->prev = __p298->next; \ -} while (0) -#define list_entry(node, type, member) \ - (type *)((void *)node - offsetof(type, member)) -#define list_empty(p) \ -({ \ - const struct list_head *__p298 = (p); \ - ((__p298->next == __p298) && (__p298->prev == __p298)); \ -}) -#define list_add(p, l) \ -do { \ - struct list_head *__p298 = (p); \ - struct list_head *__l298 = (l); \ - __p298->next = __l298->next; \ - __p298->prev = __l298; \ - __l298->next->prev = __p298; \ - __l298->next = __p298; \ -} while (0) -#define list_add_tail(p, l) \ -do { \ - struct list_head *__p298 = (p); \ - struct list_head *__l298 = (l); \ - __p298->prev = __l298->prev; \ - __p298->next = __l298; \ - __l298->prev->next = __p298; \ - __l298->prev = __p298; \ -} while (0) -#define list_for_each(i, l) \ - for (i = (l)->next; i != (l); i = i->next) -#define list_for_each_safe(i, j, l) \ - for (i = (l)->next, j = i->next; i != (l); \ - i = j, j = i->next) -#define list_for_each_entry(i, l, name) \ - for (i = list_entry((l)->next, typeof(*i), name); &i->name != (l); \ - i = list_entry(i->name.next, typeof(*i), name)) -#define list_for_each_entry_safe(i, j, l, name) \ - for (i = list_entry((l)->next, typeof(*i), name), \ - j = list_entry(i->name.next, typeof(*j), name); \ - &i->name != (l); \ - i = j, j = list_entry(j->name.next, typeof(*j), name)) -#define list_del(i) \ -do { \ - (i)->next->prev = (i)->prev; \ - (i)->prev->next = (i)->next; \ -} while (0) - -#endif /* __DPAA_LIST_H */ diff --git a/drivers/bus/dpaa/include/fman.h b/drivers/bus/dpaa/include/fman.h index d6eebc877a..c02d32d22f 100644 --- a/drivers/bus/dpaa/include/fman.h +++ b/drivers/bus/dpaa/include/fman.h @@ -15,6 +15,7 @@ #include #include +#include #ifndef FMAN_DEVICE_PATH #define FMAN_DEVICE_PATH "/dev/mem" diff --git a/drivers/bus/dpaa/include/fsl_usd.h b/drivers/bus/dpaa/include/fsl_usd.h index 3c26d6ccb3..263d9bb976 100644 --- a/drivers/bus/dpaa/include/fsl_usd.h +++ b/drivers/bus/dpaa/include/fsl_usd.h @@ -10,6 +10,7 @@ #define __FSL_USD_H #include +#include #include #ifdef __cplusplus diff --git a/drivers/bus/dpaa/include/of.h b/drivers/bus/dpaa/include/of.h deleted file mode 100644 index 7ea7608fca..0000000000 --- a/drivers/bus/dpaa/include/of.h +++ /dev/null @@ -1,159 +0,0 @@ -/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) - * - * Copyright 2010-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP - * - */ - -#ifndef __OF_H -#define __OF_H - -#include - -#ifndef OF_INIT_DEFAULT_PATH -#define OF_INIT_DEFAULT_PATH "/proc/device-tree" -#endif - -#define OF_DEFAULT_NA 1 -#define OF_DEFAULT_NS 1 - -#define OF_FILE_BUF_MAX 256 - -/** - * Layout of Device Tree: - * dt_dir - * |- dt_dir - * | |- dt_dir - * | | |- dt_dir - * | | | |- dt_file - * | | | ``- dt_file - * | | ``- dt_file - * | `-dt_file` - * ``- dt_file - * - * +------------------+ - * |dt_dir | - * |+----------------+| - * ||dt_node || - * ||+--------------+|| - * |||device_node ||| - * ||+--------------+|| - * || list_dt_nodes || - * |+----------------+| - * | list of subdir | - * | list of files | - * +------------------+ - */ - -/** - * Device description on of a device node in device tree. - */ -struct device_node { - char name[NAME_MAX]; - char full_name[PATH_MAX]; -}; - -/** - * List of device nodes available in a device tree layout - */ -struct dt_node { - struct device_node node; /**< Property of node */ - int is_file; /**< FALSE==dir, TRUE==file */ - struct list_head list; /**< Nodes within a parent subdir */ -}; - -/** - * Types we use to represent directories and files - */ -struct dt_file; -struct dt_dir { - struct dt_node node; - struct list_head subdirs; - struct list_head files; - struct list_head linear; - struct dt_dir *parent; - struct dt_file *compatible; - struct dt_file *status; - struct dt_file *lphandle; - struct dt_file *a_cells; - struct dt_file *s_cells; - struct dt_file *reg; -}; - -struct dt_file { - struct dt_node node; - struct dt_dir *parent; - ssize_t len; - uint64_t buf[OF_FILE_BUF_MAX >> 3]; -}; - -const struct device_node *of_find_compatible_node( - const struct device_node *from, - const char *type __always_unused, - const char *compatible) - __attribute__((nonnull(3))); - -#define for_each_compatible_node(dev_node, type, compatible) \ - for (dev_node = of_find_compatible_node(NULL, type, compatible); \ - dev_node != NULL; \ - dev_node = of_find_compatible_node(dev_node, type, compatible)) - -const void *of_get_property(const struct device_node *from, const char *name, - size_t *lenp) __attribute__((nonnull(2))); -bool of_device_is_available(const struct device_node *dev_node); - -const struct device_node *of_find_node_by_phandle(phandle ph); - -const struct device_node *of_get_parent(const struct device_node *dev_node); - -const struct device_node *of_get_next_child(const struct device_node *dev_node, - const struct device_node *prev); - -const void *of_get_mac_address(const struct device_node *np); - -#define for_each_child_node(parent, child) \ - for (child = of_get_next_child(parent, NULL); child != NULL; \ - child = of_get_next_child(parent, child)) - -uint32_t of_n_addr_cells(const struct device_node *dev_node); -uint32_t of_n_size_cells(const struct device_node *dev_node); - -const uint32_t *of_get_address(const struct device_node *dev_node, size_t idx, - uint64_t *size, uint32_t *flags); - -uint64_t of_translate_address(const struct device_node *dev_node, - const u32 *addr) __attribute__((nonnull)); - -bool of_device_is_compatible(const struct device_node *dev_node, - const char *compatible); - -/* of_init() must be called prior to initialisation or use of any driver - * subsystem that is device-tree-dependent. Eg. Qman/Bman, config layers, etc. - * The path should usually be "/proc/device-tree". - */ -int of_init_path(const char *dt_path); - -/* of_finish() allows a controlled tear-down of the device-tree layer, eg. if a - * full reload is desired without a process exit. - */ -void of_finish(void); - -/* Use of this wrapper is recommended. */ -static inline int of_init(void) -{ - return of_init_path(OF_INIT_DEFAULT_PATH); -} - -/* Read a numeric property according to its size and return it as a 64-bit - * value. - */ -static inline uint64_t of_read_number(const __be32 *cell, int size) -{ - uint64_t r = 0; - - while (size--) - r = (r << 32) | be32toh(*(cell++)); - return r; -} - -#endif /* __OF_H */ diff --git a/drivers/bus/dpaa/meson.build b/drivers/bus/dpaa/meson.build index c9c3b2415e..0e561c2608 100644 --- a/drivers/bus/dpaa/meson.build +++ b/drivers/bus/dpaa/meson.build @@ -12,7 +12,6 @@ deps += ['common_dpaax', 'eventdev'] sources = files('base/fman/fman.c', 'base/fman/fman_hw.c', 'base/fman/netcfg_layer.c', - 'base/fman/of.c', 'base/qbman/bman.c', 'base/qbman/bman_driver.c', 'base/qbman/dpaa_alloc.c', diff --git a/drivers/bus/dpaa/rte_bus_dpaa_version.map b/drivers/bus/dpaa/rte_bus_dpaa_version.map index a221522c23..97f4f622db 100644 --- a/drivers/bus/dpaa/rte_bus_dpaa_version.map +++ b/drivers/bus/dpaa/rte_bus_dpaa_version.map @@ -40,8 +40,6 @@ DPDK_17.11 { fman_ip_rev; netcfg_acquire; netcfg_release; - of_find_compatible_node; - of_get_property; qm_channel_caam; qman_create_fq; qman_dequeue; @@ -97,7 +95,6 @@ DPDK_18.08 { fman_if_get_sg_enable; fman_if_set_sg; - of_get_mac_address; } DPDK_18.02; diff --git a/drivers/bus/dpaa/rte_dpaa_bus.h b/drivers/bus/dpaa/rte_dpaa_bus.h index 9601aebddd..c2b2375343 100644 --- a/drivers/bus/dpaa/rte_dpaa_bus.h +++ b/drivers/bus/dpaa/rte_dpaa_bus.h @@ -10,10 +10,10 @@ #include #include +#include #include #include #include -#include #include #define DPAA_MEMPOOL_OPS_NAME "dpaa" diff --git a/drivers/bus/fslmc/Makefile b/drivers/bus/fslmc/Makefile index 218d9bd28e..16f0a2ca4a 100644 --- a/drivers/bus/fslmc/Makefile +++ b/drivers/bus/fslmc/Makefile @@ -16,6 +16,7 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring LDLIBS += -lrte_ethdev diff --git a/drivers/common/dpaax/Makefile b/drivers/common/dpaax/Makefile index 94d2cf0ce7..a0a1de0283 100644 --- a/drivers/common/dpaax/Makefile +++ b/drivers/common/dpaax/Makefile @@ -12,6 +12,10 @@ LIB = librte_common_dpaax.a CFLAGS += -DALLOW_EXPERIMENTAL_API CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) +CFLAGS += -Wno-pointer-arith +CFLAGS += -Wno-cast-qual + +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax # versioning export map EXPORT_MAP := rte_common_dpaax_version.map @@ -22,10 +26,8 @@ LIBABIVER := 1 # # all source are stored in SRCS-y # -SRCS-y += dpaax_iova_table.c +SRCS-y += dpaax_iova_table.c dpaa_of.c LDLIBS += -lrte_eal -SYMLINK-y-include += dpaax_iova_table.h - -include $(RTE_SDK)/mk/rte.lib.mk \ No newline at end of file +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/common/dpaax/compat.h b/drivers/common/dpaax/compat.h new file mode 100644 index 0000000000..12c9d99179 --- /dev/null +++ b/drivers/common/dpaax/compat.h @@ -0,0 +1,393 @@ +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) + * + * Copyright 2011 Freescale Semiconductor, Inc. + * All rights reserved. + * Copyright 2019 NXP + * + */ + +#ifndef __COMPAT_H +#define __COMPAT_H + +#include + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The following definitions are primarily to allow the single-source driver + * interfaces to be included by arbitrary program code. Ie. for interfaces that + * are also available in kernel-space, these definitions provide compatibility + * with certain attributes and types used in those interfaces. + */ + +/* Required compiler attributes */ +#ifndef __maybe_unused +#define __maybe_unused __rte_unused +#endif +#ifndef __always_unused +#define __always_unused __rte_unused +#endif +#ifndef __packed +#define __packed __rte_packed +#endif +#ifndef noinline +#define noinline __attribute__((noinline)) +#endif +#define L1_CACHE_BYTES 64 +#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES))) +#define __stringify_1(x) #x +#define __stringify(x) __stringify_1(x) + +#ifdef ARRAY_SIZE +#undef ARRAY_SIZE +#endif +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +/* Debugging */ +#define prflush(fmt, args...) \ + do { \ + printf(fmt, ##args); \ + fflush(stdout); \ + } while (0) +#ifndef pr_crit +#define pr_crit(fmt, args...) prflush("CRIT:" fmt, ##args) +#endif +#ifndef pr_err +#define pr_err(fmt, args...) prflush("ERR:" fmt, ##args) +#endif +#ifndef pr_warn +#define pr_warn(fmt, args...) prflush("WARN:" fmt, ##args) +#endif +#ifndef pr_info +#define pr_info(fmt, args...) prflush(fmt, ##args) +#endif +#ifndef pr_debug +#ifdef RTE_LIBRTE_DPAA_DEBUG_BUS +#define pr_debug(fmt, args...) printf(fmt, ##args) +#else +#define pr_debug(fmt, args...) {} +#endif +#endif + +#define DPAA_BUG_ON(x) RTE_ASSERT(x) + +/* Required types */ +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef uint64_t dma_addr_t; +typedef cpu_set_t cpumask_t; +typedef uint32_t phandle; +typedef uint32_t gfp_t; +typedef uint32_t irqreturn_t; + +#define ETHER_ADDR_LEN 6 + +#define IRQ_HANDLED 0 +#define request_irq qbman_request_irq +#define free_irq qbman_free_irq + +#define __iomem +#define GFP_KERNEL 0 +#define __raw_readb(p) (*(const volatile unsigned char *)(p)) +#define __raw_readl(p) (*(const volatile unsigned int *)(p)) +#define __raw_writel(v, p) {*(volatile unsigned int *)(p) = (v); } + +/* to be used as an upper-limit only */ +#define NR_CPUS 64 + +/* Waitqueue stuff */ +typedef struct { } wait_queue_head_t; +#define DECLARE_WAIT_QUEUE_HEAD(x) int dummy_##x __always_unused +#define wake_up(x) do { } while (0) + +/* I/O operations */ +static inline u32 in_be32(volatile void *__p) +{ + volatile u32 *p = __p; + return rte_be_to_cpu_32(*p); +} + +static inline void out_be32(volatile void *__p, u32 val) +{ + volatile u32 *p = __p; + *p = rte_cpu_to_be_32(val); +} + +#define hwsync() rte_rmb() +#define lwsync() rte_wmb() + +#define dcbt_ro(p) __builtin_prefetch(p, 0) +#define dcbt_rw(p) __builtin_prefetch(p, 1) + +#if defined(RTE_ARCH_ARM64) +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); } +#define dcbz_64(p) dcbz(p) +#define dcbf(p) { asm volatile("dc cvac, %0" : : "r"(p) : "memory"); } +#define dcbf_64(p) dcbf(p) +#define dccivac(p) { asm volatile("dc civac, %0" : : "r"(p) : "memory"); } + +#define dcbit_ro(p) \ + do { \ + dccivac(p); \ + asm volatile("prfm pldl1keep, [%0, #64]" : : "r" (p)); \ + } while (0) + +#elif defined(RTE_ARCH_ARM) +#define dcbz(p) memset((p), 0, 32) +#define dcbz_64(p) memset((p), 0, 64) +#define dcbf(p) RTE_SET_USED(p) +#define dcbf_64(p) dcbf(p) +#define dccivac(p) RTE_SET_USED(p) +#define dcbit_ro(p) RTE_SET_USED(p) + +#else +#define dcbz(p) RTE_SET_USED(p) +#define dcbz_64(p) dcbz(p) +#define dcbf(p) RTE_SET_USED(p) +#define dcbf_64(p) dcbf(p) +#define dccivac(p) RTE_SET_USED(p) +#define dcbit_ro(p) RTE_SET_USED(p) +#endif + +#define barrier() { asm volatile ("" : : : "memory"); } +#define cpu_relax barrier + +#if defined(RTE_ARCH_ARM64) +static inline uint64_t mfatb(void) +{ + uint64_t ret, ret_new, timeout = 200; + + asm volatile ("mrs %0, cntvct_el0" : "=r" (ret)); + asm volatile ("mrs %0, cntvct_el0" : "=r" (ret_new)); + while (ret != ret_new && timeout--) { + ret = ret_new; + asm volatile ("mrs %0, cntvct_el0" : "=r" (ret_new)); + } + DPAA_BUG_ON(!timeout && (ret != ret_new)); + return ret * 64; +} +#else + +#define mfatb rte_rdtsc + +#endif + +/* Spin for a few cycles without bothering the bus */ +static inline void cpu_spin(int cycles) +{ + uint64_t now = mfatb(); + + while (mfatb() < (now + cycles)) + ; +} + +/* Qman/Bman API inlines and macros; */ +#ifdef lower_32_bits +#undef lower_32_bits +#endif +#define lower_32_bits(x) ((u32)(x)) + +#ifdef upper_32_bits +#undef upper_32_bits +#endif +#define upper_32_bits(x) ((u32)(((x) >> 16) >> 16)) + +/* + * Swap bytes of a 48-bit value. + */ +static inline uint64_t +__bswap_48(uint64_t x) +{ + return ((x & 0x0000000000ffULL) << 40) | + ((x & 0x00000000ff00ULL) << 24) | + ((x & 0x000000ff0000ULL) << 8) | + ((x & 0x0000ff000000ULL) >> 8) | + ((x & 0x00ff00000000ULL) >> 24) | + ((x & 0xff0000000000ULL) >> 40); +} + +/* + * Swap bytes of a 40-bit value. + */ +static inline uint64_t +__bswap_40(uint64_t x) +{ + return ((x & 0x00000000ffULL) << 32) | + ((x & 0x000000ff00ULL) << 16) | + ((x & 0x0000ff0000ULL)) | + ((x & 0x00ff000000ULL) >> 16) | + ((x & 0xff00000000ULL) >> 32); +} + +/* + * Swap bytes of a 24-bit value. + */ +static inline uint32_t +__bswap_24(uint32_t x) +{ + return ((x & 0x0000ffULL) << 16) | + ((x & 0x00ff00ULL)) | + ((x & 0xff0000ULL) >> 16); +} + +#define be64_to_cpu(x) rte_be_to_cpu_64(x) +#define be32_to_cpu(x) rte_be_to_cpu_32(x) +#define be16_to_cpu(x) rte_be_to_cpu_16(x) + +#define cpu_to_be64(x) rte_cpu_to_be_64(x) +#if !defined(cpu_to_be32) +#define cpu_to_be32(x) rte_cpu_to_be_32(x) +#endif +#define cpu_to_be16(x) rte_cpu_to_be_16(x) + +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN + +#define cpu_to_be48(x) __bswap_48(x) +#define be48_to_cpu(x) __bswap_48(x) + +#define cpu_to_be40(x) __bswap_40(x) +#define be40_to_cpu(x) __bswap_40(x) + +#define cpu_to_be24(x) __bswap_24(x) +#define be24_to_cpu(x) __bswap_24(x) + +#else /* RTE_BIG_ENDIAN */ + +#define cpu_to_be48(x) (x) +#define be48_to_cpu(x) (x) + +#define cpu_to_be40(x) (x) +#define be40_to_cpu(x) (x) + +#define cpu_to_be24(x) (x) +#define be24_to_cpu(x) (x) + +#endif /* RTE_BIG_ENDIAN */ + +/* When copying aligned words or shorts, try to avoid memcpy() */ +/* memcpy() stuff - when you know alignments in advance */ +#define CONFIG_TRY_BETTER_MEMCPY + +#ifdef CONFIG_TRY_BETTER_MEMCPY +static inline void copy_words(void *dest, const void *src, size_t sz) +{ + u32 *__dest = dest; + const u32 *__src = src; + size_t __sz = sz >> 2; + + DPAA_BUG_ON((unsigned long)dest & 0x3); + DPAA_BUG_ON((unsigned long)src & 0x3); + DPAA_BUG_ON(sz & 0x3); + while (__sz--) + *(__dest++) = *(__src++); +} + +static inline void copy_shorts(void *dest, const void *src, size_t sz) +{ + u16 *__dest = dest; + const u16 *__src = src; + size_t __sz = sz >> 1; + + DPAA_BUG_ON((unsigned long)dest & 0x1); + DPAA_BUG_ON((unsigned long)src & 0x1); + DPAA_BUG_ON(sz & 0x1); + while (__sz--) + *(__dest++) = *(__src++); +} + +static inline void copy_bytes(void *dest, const void *src, size_t sz) +{ + u8 *__dest = dest; + const u8 *__src = src; + + while (sz--) + *(__dest++) = *(__src++); +} +#else +#define copy_words memcpy +#define copy_shorts memcpy +#define copy_bytes memcpy +#endif + +/* Allocator stuff */ +#define kmalloc(sz, t) rte_malloc(NULL, sz, 0) +#define vmalloc(sz) rte_malloc(NULL, sz, 0) +#define kfree(p) { if (p) rte_free(p); } +static inline void *kzalloc(size_t sz, gfp_t __foo __rte_unused) +{ + void *ptr = rte_malloc(NULL, sz, 0); + + if (ptr) + memset(ptr, 0, sz); + return ptr; +} + +static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused) +{ + void *p; + + if (posix_memalign(&p, 4096, 4096)) + return 0; + memset(p, 0, 4096); + return (unsigned long)p; +} + +/* Spinlock stuff */ +#define spinlock_t rte_spinlock_t +#define __SPIN_LOCK_UNLOCKED(x) RTE_SPINLOCK_INITIALIZER +#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x) +#define spin_lock_init(x) rte_spinlock_init(x) +#define spin_lock_destroy(x) +#define spin_lock(x) rte_spinlock_lock(x) +#define spin_unlock(x) rte_spinlock_unlock(x) +#define spin_lock_irq(x) spin_lock(x) +#define spin_unlock_irq(x) spin_unlock(x) +#define spin_lock_irqsave(x, f) spin_lock_irq(x) +#define spin_unlock_irqrestore(x, f) spin_unlock_irq(x) + +#define atomic_t rte_atomic32_t +#define atomic_read(v) rte_atomic32_read(v) +#define atomic_set(v, i) rte_atomic32_set(v, i) + +#define atomic_inc(v) rte_atomic32_add(v, 1) +#define atomic_dec(v) rte_atomic32_sub(v, 1) + +#define atomic_inc_and_test(v) rte_atomic32_inc_and_test(v) +#define atomic_dec_and_test(v) rte_atomic32_dec_and_test(v) + +#define atomic_inc_return(v) rte_atomic32_add_return(v, 1) +#define atomic_dec_return(v) rte_atomic32_sub_return(v, 1) +#define atomic_sub_and_test(i, v) (rte_atomic32_sub_return(v, i) == 0) + +#endif /* __COMPAT_H */ diff --git a/drivers/common/dpaax/dpaa_list.h b/drivers/common/dpaax/dpaa_list.h new file mode 100644 index 0000000000..e94575982b --- /dev/null +++ b/drivers/common/dpaax/dpaa_list.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright 2017 NXP + * + */ + +#ifndef __DPAA_LIST_H +#define __DPAA_LIST_H + +/****************/ +/* Linked-lists */ +/****************/ + +struct list_head { + struct list_head *prev; + struct list_head *next; +}; + +#define COMPAT_LIST_HEAD(n) \ +struct list_head n = { \ + .prev = &n, \ + .next = &n \ +} + +#define INIT_LIST_HEAD(p) \ +do { \ + struct list_head *__p298 = (p); \ + __p298->next = __p298; \ + __p298->prev = __p298->next; \ +} while (0) +#define list_entry(node, type, member) \ + (type *)((void *)node - offsetof(type, member)) +#define list_empty(p) \ +({ \ + const struct list_head *__p298 = (p); \ + ((__p298->next == __p298) && (__p298->prev == __p298)); \ +}) +#define list_add(p, l) \ +do { \ + struct list_head *__p298 = (p); \ + struct list_head *__l298 = (l); \ + __p298->next = __l298->next; \ + __p298->prev = __l298; \ + __l298->next->prev = __p298; \ + __l298->next = __p298; \ +} while (0) +#define list_add_tail(p, l) \ +do { \ + struct list_head *__p298 = (p); \ + struct list_head *__l298 = (l); \ + __p298->prev = __l298->prev; \ + __p298->next = __l298; \ + __l298->prev->next = __p298; \ + __l298->prev = __p298; \ +} while (0) +#define list_for_each(i, l) \ + for (i = (l)->next; i != (l); i = i->next) +#define list_for_each_safe(i, j, l) \ + for (i = (l)->next, j = i->next; i != (l); \ + i = j, j = i->next) +#define list_for_each_entry(i, l, name) \ + for (i = list_entry((l)->next, typeof(*i), name); &i->name != (l); \ + i = list_entry(i->name.next, typeof(*i), name)) +#define list_for_each_entry_safe(i, j, l, name) \ + for (i = list_entry((l)->next, typeof(*i), name), \ + j = list_entry(i->name.next, typeof(*j), name); \ + &i->name != (l); \ + i = j, j = list_entry(j->name.next, typeof(*j), name)) +#define list_del(i) \ +do { \ + (i)->next->prev = (i)->prev; \ + (i)->prev->next = (i)->next; \ +} while (0) + +#endif /* __DPAA_LIST_H */ diff --git a/drivers/common/dpaax/dpaa_of.c b/drivers/common/dpaax/dpaa_of.c new file mode 100644 index 0000000000..bb2c8fc66b --- /dev/null +++ b/drivers/common/dpaax/dpaa_of.c @@ -0,0 +1,589 @@ +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) + * + * Copyright 2010-2016 Freescale Semiconductor Inc. + * Copyright 2017 NXP + * + */ + +#include +#include +#include +#include + +static int alive; +static struct dt_dir root_dir; +static const char *base_dir; +static COMPAT_LIST_HEAD(linear); + +static int +of_open_dir(const char *relative_path, struct dirent ***d) +{ + int ret; + char full_path[PATH_MAX]; + + snprintf(full_path, PATH_MAX, "%s/%s", base_dir, relative_path); + ret = scandir(full_path, d, 0, versionsort); + if (ret < 0) + DPAAX_LOG(ERR, "Failed to open directory %s", + full_path); + return ret; +} + +static void +of_close_dir(struct dirent **d, int num) +{ + while (num--) + free(d[num]); + free(d); +} + +static int +of_open_file(const char *relative_path) +{ + int ret; + char full_path[PATH_MAX]; + + snprintf(full_path, PATH_MAX, "%s/%s", base_dir, relative_path); + ret = open(full_path, O_RDONLY); + if (ret < 0) + DPAAX_LOG(ERR, "Failed to open directory %s", + full_path); + return ret; +} + +static void +process_file(struct dirent *dent, struct dt_dir *parent) +{ + int fd; + struct dt_file *f = malloc(sizeof(*f)); + + if (!f) { + DPAAX_LOG(DEBUG, "Unable to allocate memory for file node"); + return; + } + f->node.is_file = 1; + strlcpy(f->node.node.name, dent->d_name, NAME_MAX); + snprintf(f->node.node.full_name, PATH_MAX, "%s/%s", + parent->node.node.full_name, dent->d_name); + f->parent = parent; + fd = of_open_file(f->node.node.full_name); + if (fd < 0) { + DPAAX_LOG(DEBUG, "Unable to open file node"); + free(f); + return; + } + f->len = read(fd, f->buf, OF_FILE_BUF_MAX); + close(fd); + if (f->len < 0) { + DPAAX_LOG(DEBUG, "Unable to read file node"); + free(f); + return; + } + list_add_tail(&f->node.list, &parent->files); +} + +static const struct dt_dir * +node2dir(const struct device_node *n) +{ + struct dt_node *dn = container_of((struct device_node *)n, + struct dt_node, node); + const struct dt_dir *d = container_of(dn, struct dt_dir, node); + + assert(!dn->is_file); + return d; +} + +/* process_dir() calls iterate_dir(), but the latter will also call the former + * when recursing into sub-directories, so a predeclaration is needed. + */ +static int process_dir(const char *relative_path, struct dt_dir *dt); + +static int +iterate_dir(struct dirent **d, int num, struct dt_dir *dt) +{ + int loop; + /* Iterate the directory contents */ + for (loop = 0; loop < num; loop++) { + struct dt_dir *subdir; + int ret; + /* Ignore dot files of all types (especially "..") */ + if (d[loop]->d_name[0] == '.') + continue; + switch (d[loop]->d_type) { + case DT_REG: + process_file(d[loop], dt); + break; + case DT_DIR: + subdir = malloc(sizeof(*subdir)); + if (!subdir) { + perror("malloc"); + return -ENOMEM; + } + strlcpy(subdir->node.node.name, d[loop]->d_name, + NAME_MAX); + snprintf(subdir->node.node.full_name, PATH_MAX, + "%s/%s", dt->node.node.full_name, + d[loop]->d_name); + subdir->parent = dt; + ret = process_dir(subdir->node.node.full_name, subdir); + if (ret) + return ret; + list_add_tail(&subdir->node.list, &dt->subdirs); + break; + default: + DPAAX_LOG(DEBUG, "Ignoring invalid dt entry %s/%s", + dt->node.node.full_name, d[loop]->d_name); + } + } + return 0; +} + +static int +process_dir(const char *relative_path, struct dt_dir *dt) +{ + struct dirent **d; + int ret, num; + + dt->node.is_file = 0; + INIT_LIST_HEAD(&dt->subdirs); + INIT_LIST_HEAD(&dt->files); + ret = of_open_dir(relative_path, &d); + if (ret < 0) + return ret; + num = ret; + ret = iterate_dir(d, num, dt); + of_close_dir(d, num); + return (ret < 0) ? ret : 0; +} + +static void +linear_dir(struct dt_dir *d) +{ + struct dt_file *f; + struct dt_dir *dd; + + d->compatible = NULL; + d->status = NULL; + d->lphandle = NULL; + d->a_cells = NULL; + d->s_cells = NULL; + d->reg = NULL; + list_for_each_entry(f, &d->files, node.list) { + if (!strcmp(f->node.node.name, "compatible")) { + if (d->compatible) + DPAAX_LOG(DEBUG, "Duplicate compatible in" + " %s", d->node.node.full_name); + d->compatible = f; + } else if (!strcmp(f->node.node.name, "status")) { + if (d->status) + DPAAX_LOG(DEBUG, "Duplicate status in %s", + d->node.node.full_name); + d->status = f; + } else if (!strcmp(f->node.node.name, "linux,phandle")) { + if (d->lphandle) + DPAAX_LOG(DEBUG, "Duplicate lphandle in %s", + d->node.node.full_name); + d->lphandle = f; + } else if (!strcmp(f->node.node.name, "phandle")) { + if (d->lphandle) + DPAAX_LOG(DEBUG, "Duplicate lphandle in %s", + d->node.node.full_name); + d->lphandle = f; + } else if (!strcmp(f->node.node.name, "#address-cells")) { + if (d->a_cells) + DPAAX_LOG(DEBUG, "Duplicate a_cells in %s", + d->node.node.full_name); + d->a_cells = f; + } else if (!strcmp(f->node.node.name, "#size-cells")) { + if (d->s_cells) + DPAAX_LOG(DEBUG, "Duplicate s_cells in %s", + d->node.node.full_name); + d->s_cells = f; + } else if (!strcmp(f->node.node.name, "reg")) { + if (d->reg) + DPAAX_LOG(DEBUG, "Duplicate reg in %s", + d->node.node.full_name); + d->reg = f; + } + } + + list_for_each_entry(dd, &d->subdirs, node.list) { + list_add_tail(&dd->linear, &linear); + linear_dir(dd); + } +} + +int +of_init_path(const char *dt_path) +{ + int ret; + + base_dir = dt_path; + + /* This needs to be singleton initialization */ + DPAAX_HWWARN(alive, "Double-init of device-tree driver!"); + + /* Prepare root node (the remaining fields are set in process_dir()) */ + root_dir.node.node.name[0] = '\0'; + root_dir.node.node.full_name[0] = '\0'; + INIT_LIST_HEAD(&root_dir.node.list); + root_dir.parent = NULL; + + /* Kick things off... */ + ret = process_dir("", &root_dir); + if (ret) { + DPAAX_LOG(ERR, "Unable to parse device tree"); + return ret; + } + + /* Now make a flat, linear list of directories */ + linear_dir(&root_dir); + alive = 1; + return 0; +} + +static void +destroy_dir(struct dt_dir *d) +{ + struct dt_file *f, *tmpf; + struct dt_dir *dd, *tmpd; + + list_for_each_entry_safe(f, tmpf, &d->files, node.list) { + list_del(&f->node.list); + free(f); + } + list_for_each_entry_safe(dd, tmpd, &d->subdirs, node.list) { + destroy_dir(dd); + list_del(&dd->node.list); + free(dd); + } +} + +void +of_finish(void) +{ + DPAAX_HWWARN(!alive, "Double-finish of device-tree driver!"); + + destroy_dir(&root_dir); + INIT_LIST_HEAD(&linear); + alive = 0; +} + +static const struct dt_dir * +next_linear(const struct dt_dir *f) +{ + if (f->linear.next == &linear) + return NULL; + return list_entry(f->linear.next, struct dt_dir, linear); +} + +static int +check_compatible(const struct dt_file *f, const char *compatible) +{ + const char *c = (char *)f->buf; + unsigned int len, remains = f->len; + + while (remains) { + len = strlen(c); + if (!strcmp(c, compatible)) + return 1; + + if (remains < len + 1) + break; + + c += (len + 1); + remains -= (len + 1); + } + return 0; +} + +const struct device_node * +of_find_compatible_node(const struct device_node *from, + const char *type __rte_unused, + const char *compatible) +{ + const struct dt_dir *d; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + + if (list_empty(&linear)) + return NULL; + if (!from) + d = list_entry(linear.next, struct dt_dir, linear); + else + d = node2dir(from); + for (d = next_linear(d); d && (!d->compatible || + !check_compatible(d->compatible, + compatible)); + d = next_linear(d)) + ; + if (d) + return &d->node.node; + return NULL; +} + +const void * +of_get_property(const struct device_node *from, const char *name, + size_t *lenp) +{ + const struct dt_dir *d; + const struct dt_file *f; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + + d = node2dir(from); + list_for_each_entry(f, &d->files, node.list) + if (!strcmp(f->node.node.name, name)) { + if (lenp) + *lenp = f->len; + return f->buf; + } + return NULL; +} + +bool +of_device_is_available(const struct device_node *dev_node) +{ + const struct dt_dir *d; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + d = node2dir(dev_node); + if (!d->status) + return true; + if (!strcmp((char *)d->status->buf, "okay")) + return true; + if (!strcmp((char *)d->status->buf, "ok")) + return true; + return false; +} + +const struct device_node * +of_find_node_by_phandle(uint64_t ph) +{ + const struct dt_dir *d; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + list_for_each_entry(d, &linear, linear) + if (d->lphandle && (d->lphandle->len == 4) && + !memcmp(d->lphandle->buf, &ph, 4)) + return &d->node.node; + return NULL; +} + +const struct device_node * +of_get_parent(const struct device_node *dev_node) +{ + const struct dt_dir *d; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + + if (!dev_node) + return NULL; + d = node2dir(dev_node); + if (!d->parent) + return NULL; + return &d->parent->node.node; +} + +const struct device_node * +of_get_next_child(const struct device_node *dev_node, + const struct device_node *prev) +{ + const struct dt_dir *p, *c; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + + if (!dev_node) + return NULL; + p = node2dir(dev_node); + if (prev) { + c = node2dir(prev); + DPAAX_HWWARN((c->parent != p), "Parent/child mismatch"); + if (c->parent != p) + return NULL; + if (c->node.list.next == &p->subdirs) + /* prev was the last child */ + return NULL; + c = list_entry(c->node.list.next, struct dt_dir, node.list); + return &c->node.node; + } + /* Return first child */ + if (list_empty(&p->subdirs)) + return NULL; + c = list_entry(p->subdirs.next, struct dt_dir, node.list); + return &c->node.node; +} + +uint32_t +of_n_addr_cells(const struct device_node *dev_node) +{ + const struct dt_dir *d; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised"); + if (!dev_node) + return OF_DEFAULT_NA; + d = node2dir(dev_node); + while ((d = d->parent)) + if (d->a_cells) { + unsigned char *buf = + (unsigned char *)&d->a_cells->buf[0]; + assert(d->a_cells->len == 4); + return ((uint32_t)buf[0] << 24) | + ((uint32_t)buf[1] << 16) | + ((uint32_t)buf[2] << 8) | + (uint32_t)buf[3]; + } + return OF_DEFAULT_NA; +} + +uint32_t +of_n_size_cells(const struct device_node *dev_node) +{ + const struct dt_dir *d; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + if (!dev_node) + return OF_DEFAULT_NA; + d = node2dir(dev_node); + while ((d = d->parent)) + if (d->s_cells) { + unsigned char *buf = + (unsigned char *)&d->s_cells->buf[0]; + assert(d->s_cells->len == 4); + return ((uint32_t)buf[0] << 24) | + ((uint32_t)buf[1] << 16) | + ((uint32_t)buf[2] << 8) | + (uint32_t)buf[3]; + } + return OF_DEFAULT_NS; +} + +const uint32_t * +of_get_address(const struct device_node *dev_node, size_t idx, + uint64_t *size, uint32_t *flags __rte_unused) +{ + const struct dt_dir *d; + const unsigned char *buf; + uint32_t na = of_n_addr_cells(dev_node); + uint32_t ns = of_n_size_cells(dev_node); + + if (!dev_node) + d = &root_dir; + else + d = node2dir(dev_node); + if (!d->reg) + return NULL; + assert(d->reg->len % ((na + ns) * 4) == 0); + assert(d->reg->len / ((na + ns) * 4) > (unsigned int) idx); + buf = (const unsigned char *)&d->reg->buf[0]; + buf += (na + ns) * idx * 4; + if (size) + for (*size = 0; ns > 0; ns--, na++) + *size = (*size << 32) + + (((uint32_t)buf[4 * na] << 24) | + ((uint32_t)buf[4 * na + 1] << 16) | + ((uint32_t)buf[4 * na + 2] << 8) | + (uint32_t)buf[4 * na + 3]); + return (const uint32_t *)buf; +} + +uint64_t +of_translate_address(const struct device_node *dev_node, + const uint32_t *addr) +{ + uint64_t phys_addr, tmp_addr; + const struct device_node *parent; + const uint32_t *ranges; + size_t rlen; + uint32_t na, pna; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + assert(dev_node != NULL); + + na = of_n_addr_cells(dev_node); + phys_addr = of_read_number(addr, na); + + dev_node = of_get_parent(dev_node); + if (!dev_node) + return 0; + else if (node2dir(dev_node) == &root_dir) + return phys_addr; + + do { + pna = of_n_addr_cells(dev_node); + parent = of_get_parent(dev_node); + if (!parent) + return 0; + + ranges = of_get_property(dev_node, "ranges", &rlen); + /* "ranges" property is missing. Translation breaks */ + if (!ranges) + return 0; + /* "ranges" property is empty. Do 1:1 translation */ + else if (rlen == 0) + continue; + else + tmp_addr = of_read_number(ranges + na, pna); + + na = pna; + dev_node = parent; + phys_addr += tmp_addr; + } while (node2dir(parent) != &root_dir); + + return phys_addr; +} + +bool +of_device_is_compatible(const struct device_node *dev_node, + const char *compatible) +{ + const struct dt_dir *d; + + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); + if (!dev_node) + d = &root_dir; + else + d = node2dir(dev_node); + if (d->compatible && check_compatible(d->compatible, compatible)) + return true; + return false; +} + +static const void *of_get_mac_addr(const struct device_node *np, + const char *name) +{ + return of_get_property(np, name, NULL); +} + +/** + * Search the device tree for the best MAC address to use. 'mac-address' is + * checked first, because that is supposed to contain to "most recent" MAC + * address. If that isn't set, then 'local-mac-address' is checked next, + * because that is the default address. If that isn't set, then the obsolete + * 'address' is checked, just in case we're using an old device tree. + * + * Note that the 'address' property is supposed to contain a virtual address of + * the register set, but some DTS files have redefined that property to be the + * MAC address. + * + * All-zero MAC addresses are rejected, because those could be properties that + * exist in the device tree, but were not set by U-Boot. For example, the + * DTS could define 'mac-address' and 'local-mac-address', with zero MAC + * addresses. Some older U-Boots only initialized 'local-mac-address'. In + * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists + * but is all zeros. + */ +const void *of_get_mac_address(const struct device_node *np) +{ + const void *addr; + + addr = of_get_mac_addr(np, "mac-address"); + if (addr) + return addr; + + addr = of_get_mac_addr(np, "local-mac-address"); + if (addr) + return addr; + + return of_get_mac_addr(np, "address"); +} diff --git a/drivers/common/dpaax/dpaa_of.h b/drivers/common/dpaax/dpaa_of.h new file mode 100644 index 0000000000..960b421766 --- /dev/null +++ b/drivers/common/dpaax/dpaa_of.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) + * + * Copyright 2010-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + */ + +#ifndef __OF_H +#define __OF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef OF_INIT_DEFAULT_PATH +#define OF_INIT_DEFAULT_PATH "/proc/device-tree" +#endif + +#define OF_DEFAULT_NA 1 +#define OF_DEFAULT_NS 1 + +#define OF_FILE_BUF_MAX 256 + +/** + * Layout of Device Tree: + * dt_dir + * |- dt_dir + * | |- dt_dir + * | | |- dt_dir + * | | | |- dt_file + * | | | ``- dt_file + * | | ``- dt_file + * | `-dt_file` + * ``- dt_file + * + * +------------------+ + * |dt_dir | + * |+----------------+| + * ||dt_node || + * ||+--------------+|| + * |||device_node ||| + * ||+--------------+|| + * || list_dt_nodes || + * |+----------------+| + * | list of subdir | + * | list of files | + * +------------------+ + */ + +/** + * Device description on of a device node in device tree. + */ +struct device_node { + char name[NAME_MAX]; + char full_name[PATH_MAX]; +}; + +/** + * List of device nodes available in a device tree layout + */ +struct dt_node { + struct device_node node; /**< Property of node */ + int is_file; /**< FALSE==dir, TRUE==file */ + struct list_head list; /**< Nodes within a parent subdir */ +}; + +/** + * Types we use to represent directories and files + */ +struct dt_file; +struct dt_dir { + struct dt_node node; + struct list_head subdirs; + struct list_head files; + struct list_head linear; + struct dt_dir *parent; + struct dt_file *compatible; + struct dt_file *status; + struct dt_file *lphandle; + struct dt_file *a_cells; + struct dt_file *s_cells; + struct dt_file *reg; +}; + +struct dt_file { + struct dt_node node; + struct dt_dir *parent; + ssize_t len; + uint64_t buf[OF_FILE_BUF_MAX >> 3]; +}; + +const struct device_node *of_find_compatible_node( + const struct device_node *from, + const char *type __rte_unused, + const char *compatible) + __attribute__((nonnull(3))); + +#define for_each_compatible_node(dev_node, type, compatible) \ + for (dev_node = of_find_compatible_node(NULL, type, compatible); \ + dev_node != NULL; \ + dev_node = of_find_compatible_node(dev_node, type, compatible)) + +const void *of_get_property(const struct device_node *from, const char *name, + size_t *lenp) __attribute__((nonnull(2))); +bool of_device_is_available(const struct device_node *dev_node); + +const struct device_node *of_find_node_by_phandle(uint64_t ph); + +const struct device_node *of_get_parent(const struct device_node *dev_node); + +const struct device_node *of_get_next_child(const struct device_node *dev_node, + const struct device_node *prev); + +const void *of_get_mac_address(const struct device_node *np); + +#define for_each_child_node(parent, child) \ + for (child = of_get_next_child(parent, NULL); child != NULL; \ + child = of_get_next_child(parent, child)) + +uint32_t of_n_addr_cells(const struct device_node *dev_node); +uint32_t of_n_size_cells(const struct device_node *dev_node); + +const uint32_t *of_get_address(const struct device_node *dev_node, size_t idx, + uint64_t *size, uint32_t *flags); + +uint64_t of_translate_address(const struct device_node *dev_node, + const uint32_t *addr) __attribute__((nonnull)); + +bool of_device_is_compatible(const struct device_node *dev_node, + const char *compatible); + +/* of_init() must be called prior to initialisation or use of any driver + * subsystem that is device-tree-dependent. Eg. Qman/Bman, config layers, etc. + * The path should usually be "/proc/device-tree". + */ +int of_init_path(const char *dt_path); + +/* of_finish() allows a controlled tear-down of the device-tree layer, eg. if a + * full reload is desired without a process exit. + */ +void of_finish(void); + +/* Use of this wrapper is recommended. */ +static inline int of_init(void) +{ + return of_init_path(OF_INIT_DEFAULT_PATH); +} + +/* Read a numeric property according to its size and return it as a 64-bit + * value. + */ +static inline uint64_t of_read_number(const uint32_t *cell, int size) +{ + uint64_t r = 0; + + while (size--) + r = (r << 32) | be32toh(*(cell++)); + return r; +} + +#endif /* __OF_H */ diff --git a/drivers/common/dpaax/dpaax_logs.h b/drivers/common/dpaax/dpaax_logs.h index bf1b27cc11..180476f675 100644 --- a/drivers/common/dpaax/dpaax_logs.h +++ b/drivers/common/dpaax/dpaax_logs.h @@ -9,6 +9,16 @@ extern int dpaax_logger; +#ifdef RTE_LIBRTE_DPAAX_DEBUG +#define DPAAX_HWWARN(cond, fmt, args...) \ + do {\ + if (cond) \ + DPAAX_LOG(DEBUG, "WARN: " fmt, ##args); \ + } while (0) +#else +#define DPAAX_HWWARN(cond, fmt, args...) do { } while (0) +#endif + #define DPAAX_LOG(level, fmt, args...) \ rte_log(RTE_LOG_ ## level, dpaax_logger, "dpaax: " fmt "\n", \ ##args) diff --git a/drivers/common/dpaax/meson.build b/drivers/common/dpaax/meson.build index a315e7786b..d41bb50732 100644 --- a/drivers/common/dpaax/meson.build +++ b/drivers/common/dpaax/meson.build @@ -8,6 +8,12 @@ if not is_linux reason = 'only supported on linux' endif -sources = files('dpaax_iova_table.c') +sources = files('dpaax_iova_table.c', 'dpaa_of.c') cflags += ['-D_GNU_SOURCE'] +if cc.has_argument('-Wno-cast-qual') + cflags += '-Wno-cast-qual' +endif +if cc.has_argument('-Wno-pointer-arith') + cflags += '-Wno-pointer-arith' +endif diff --git a/drivers/common/dpaax/rte_common_dpaax_version.map b/drivers/common/dpaax/rte_common_dpaax_version.map index 8131c9e305..a7699ae4dd 100644 --- a/drivers/common/dpaax/rte_common_dpaax_version.map +++ b/drivers/common/dpaax/rte_common_dpaax_version.map @@ -9,3 +9,21 @@ DPDK_18.11 { local: *; }; + +DPDK_19.11 { + global: + of_device_is_available; + of_device_is_compatible; + of_find_compatible_node; + of_find_node_by_phandle; + of_get_address; + of_get_mac_address; + of_get_parent; + of_get_property; + of_init_path; + of_n_addr_cells; + of_translate_address; + of_get_next_child; + + local: *; +} DPDK_18.11; diff --git a/drivers/crypto/caam_jr/Makefile b/drivers/crypto/caam_jr/Makefile index c232a20ba3..fa35b79b85 100644 --- a/drivers/crypto/caam_jr/Makefile +++ b/drivers/crypto/caam_jr/Makefile @@ -17,6 +17,7 @@ CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax/caamflib/ CFLAGS += -I$(RTE_SDK)/drivers/crypto/caam_jr CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include diff --git a/drivers/crypto/caam_jr/caam_jr.c b/drivers/crypto/caam_jr/caam_jr.c index 2fe18187a5..d1da9a64c8 100644 --- a/drivers/crypto/caam_jr/caam_jr.c +++ b/drivers/crypto/caam_jr/caam_jr.c @@ -27,9 +27,9 @@ /* RTA header files */ #include #include -#include +#include #ifdef RTE_LIBRTE_PMD_CAAM_JR_DEBUG -#define CAAM_JR_DBG 1 +#define CAAM_JR_DBG 1 #else #define CAAM_JR_DBG 0 #endif diff --git a/drivers/crypto/caam_jr/meson.build b/drivers/crypto/caam_jr/meson.build index 825fefd75f..50132aebef 100644 --- a/drivers/crypto/caam_jr/meson.build +++ b/drivers/crypto/caam_jr/meson.build @@ -15,4 +15,5 @@ sources = files('caam_jr_capabilities.c', allow_experimental_apis = true includes += include_directories('../../bus/dpaa/include/') +includes += include_directories('../../common/dpaax/') includes += include_directories('../../common/dpaax/caamflib/') diff --git a/drivers/crypto/dpaa2_sec/Makefile b/drivers/crypto/dpaa2_sec/Makefile index 1f288116ee..ba30a955a9 100644 --- a/drivers/crypto/dpaa2_sec/Makefile +++ b/drivers/crypto/dpaa2_sec/Makefile @@ -20,6 +20,7 @@ CFLAGS += -Wno-implicit-fallthrough endif endif +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax/caamflib CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/ CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/mc diff --git a/drivers/crypto/dpaa_sec/Makefile b/drivers/crypto/dpaa_sec/Makefile index abbcc86662..9acccaac4f 100644 --- a/drivers/crypto/dpaa_sec/Makefile +++ b/drivers/crypto/dpaa_sec/Makefile @@ -17,6 +17,7 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/base/qbman +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa_sec/ CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax/caamflib/ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index 632ce9fdc3..6c186338ff 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -29,7 +29,7 @@ #include #include -#include +#include /* RTA header files */ #include diff --git a/drivers/crypto/dpaa_sec/meson.build b/drivers/crypto/dpaa_sec/meson.build index 8744a05f05..9f17d3a43e 100644 --- a/drivers/crypto/dpaa_sec/meson.build +++ b/drivers/crypto/dpaa_sec/meson.build @@ -12,4 +12,5 @@ sources = files('dpaa_sec.c') allow_experimental_apis = true includes += include_directories('../../bus/dpaa/include') +includes += include_directories('../../common/dpaax') includes += include_directories('../../common/dpaax/caamflib/') diff --git a/drivers/event/dpaa/Makefile b/drivers/event/dpaa/Makefile index 1856fa4682..befb21b1b6 100644 --- a/drivers/event/dpaa/Makefile +++ b/drivers/event/dpaa/Makefile @@ -19,6 +19,7 @@ CFLAGS += -I$(RTE_SDK_DPAA)/include CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include/ CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include LDLIBS += -lrte_pmd_dpaa_sec diff --git a/drivers/event/dpaa2/Makefile b/drivers/event/dpaa2/Makefile index c4019d6883..a29284f046 100644 --- a/drivers/event/dpaa2/Makefile +++ b/drivers/event/dpaa2/Makefile @@ -17,6 +17,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/mc CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/portal CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa2 CFLAGS += -I$(RTE_SDK)/drivers/event/dpaa2 +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax LDLIBS += -lrte_eal -lrte_eventdev LDLIBS += -lrte_common_dpaax LDLIBS += -lrte_bus_fslmc -lrte_mempool_dpaa2 -lrte_pmd_dpaa2 diff --git a/drivers/mempool/dpaa/Makefile b/drivers/mempool/dpaa/Makefile index ead5029fd8..534e00733c 100644 --- a/drivers/mempool/dpaa/Makefile +++ b/drivers/mempool/dpaa/Makefile @@ -12,6 +12,7 @@ CFLAGS := -I$(SRCDIR) $(CFLAGS) CFLAGS += -O3 $(WERROR_FLAGS) CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include/ +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa CFLAGS += -I$(RTE_SDK)/lib/librte_mempool diff --git a/drivers/mempool/dpaa2/Makefile b/drivers/mempool/dpaa2/Makefile index c1df78a805..bdb9410252 100644 --- a/drivers/mempool/dpaa2/Makefile +++ b/drivers/mempool/dpaa2/Makefile @@ -12,6 +12,7 @@ LIB = librte_mempool_dpaa2.a CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include # versioning export map diff --git a/drivers/net/dpaa/Makefile b/drivers/net/dpaa/Makefile index 4fb16bd9d6..395e4d900f 100644 --- a/drivers/net/dpaa/Makefile +++ b/drivers/net/dpaa/Makefile @@ -19,6 +19,7 @@ CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include/ CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/base/qbman CFLAGS += -I$(RTE_SDK)/drivers/mempool/dpaa +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/event/dpaa CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include diff --git a/drivers/net/dpaa/dpaa_ethdev.h b/drivers/net/dpaa/dpaa_ethdev.h index f63a5f164e..182becac18 100644 --- a/drivers/net/dpaa/dpaa_ethdev.h +++ b/drivers/net/dpaa/dpaa_ethdev.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #define MAX_DPAA_CORES 4 diff --git a/drivers/net/dpaa/dpaa_rxtx.c b/drivers/net/dpaa/dpaa_rxtx.c index 2de1a1a7e1..bbe6150991 100644 --- a/drivers/net/dpaa/dpaa_rxtx.c +++ b/drivers/net/dpaa/dpaa_rxtx.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #define DPAA_MBUF_TO_CONTIG_FD(_mbuf, _fd, _bpid) \ diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile index 7924871c8c..e5a2d3fdee 100644 --- a/drivers/net/dpaa2/Makefile +++ b/drivers/net/dpaa2/Makefile @@ -12,6 +12,7 @@ LIB = librte_pmd_dpaa2.a CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2 CFLAGS += -I$(RTE_SDK)/drivers/net/dpaa2/mc CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc diff --git a/drivers/raw/dpaa2_cmdif/Makefile b/drivers/raw/dpaa2_cmdif/Makefile index 2b4150c2d4..a7c9802476 100644 --- a/drivers/raw/dpaa2_cmdif/Makefile +++ b/drivers/raw/dpaa2_cmdif/Makefile @@ -14,6 +14,7 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax LDLIBS += -lrte_bus_fslmc LDLIBS += -lrte_bus_vdev diff --git a/drivers/raw/dpaa2_qdma/Makefile b/drivers/raw/dpaa2_qdma/Makefile index 0009fd4c67..057b2a81a2 100644 --- a/drivers/raw/dpaa2_qdma/Makefile +++ b/drivers/raw/dpaa2_qdma/Makefile @@ -14,6 +14,7 @@ CFLAGS += $(WERROR_FLAGS) CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/qbman/include +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax LDLIBS += -lrte_bus_fslmc LDLIBS += -lrte_eal