From patchwork Tue Oct 1 11:01:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60312 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 00D485681; Tue, 1 Oct 2019 13:17:29 +0200 (CEST) Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) by dpdk.org (Postfix) with ESMTP id EAD42397D for ; Tue, 1 Oct 2019 13:17:25 +0200 (CEST) Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 78C2A200540; Tue, 1 Oct 2019 13:17:25 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id DC4C3200536; Tue, 1 Oct 2019 13:17:22 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 3A192402DA; Tue, 1 Oct 2019 19:17:19 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Hemant Agrawal Date: Tue, 1 Oct 2019 16:31:56 +0530 Message-Id: <20191001110209.6047-2-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 01/14] common/dpaax: moving OF lib code from dpaa bus X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Hemant Agrawal This code is being shared by more than 1 type of driver. Common is most appropriate place for it. Signed-off-by: Hemant Agrawal --- drivers/bus/dpaa/Makefile | 2 +- drivers/bus/dpaa/base/fman/fman.c | 2 +- drivers/bus/dpaa/base/fman/netcfg_layer.c | 2 +- drivers/bus/dpaa/base/qbman/dpaa_sys.h | 3 +- drivers/bus/dpaa/dpaa_bus.c | 2 +- drivers/bus/dpaa/include/compat.h | 1 - drivers/bus/dpaa/include/fman.h | 1 + drivers/bus/dpaa/include/fsl_usd.h | 1 + drivers/bus/dpaa/meson.build | 1 - drivers/bus/dpaa/rte_dpaa_bus.h | 2 +- drivers/bus/fslmc/Makefile | 1 + drivers/common/dpaax/Makefile | 10 +-- .../dpaa/include => common/dpaax}/dpaa_list.h | 0 .../base/fman/of.c => common/dpaax/dpaa_of.c} | 63 ++++++++++--------- .../include/of.h => common/dpaax/dpaa_of.h} | 27 ++++++-- drivers/common/dpaax/dpaax_logs.h | 10 +++ drivers/common/dpaax/meson.build | 5 +- .../common/dpaax/rte_common_dpaax_version.map | 18 ++++++ drivers/crypto/caam_jr/Makefile | 2 + drivers/crypto/caam_jr/caam_jr.c | 2 +- drivers/crypto/dpaa2_sec/Makefile | 2 +- drivers/crypto/dpaa_sec/Makefile | 1 + drivers/crypto/dpaa_sec/dpaa_sec.c | 2 +- drivers/event/dpaa/Makefile | 1 + drivers/event/dpaa2/Makefile | 1 + drivers/mempool/dpaa/Makefile | 1 + drivers/mempool/dpaa2/Makefile | 1 + drivers/net/dpaa/Makefile | 1 + drivers/net/dpaa/dpaa_ethdev.h | 2 +- drivers/net/dpaa/dpaa_rxtx.c | 2 +- drivers/net/dpaa2/Makefile | 1 + drivers/raw/dpaa2_cmdif/Makefile | 1 + drivers/raw/dpaa2_qdma/Makefile | 1 + 33 files changed, 118 insertions(+), 54 deletions(-) rename drivers/{bus/dpaa/include => common/dpaax}/dpaa_list.h (100%) rename drivers/{bus/dpaa/base/fman/of.c => common/dpaax/dpaa_of.c} (88%) rename drivers/{bus/dpaa/include/of.h => common/dpaax/dpaa_of.h} (86%) diff --git a/drivers/bus/dpaa/Makefile b/drivers/bus/dpaa/Makefile index dfc2717a4..454ac12bf 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 8fa9b8cae..462efd2d4 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 bf8c77265..6affd2e92 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/qbman/dpaa_sys.h b/drivers/bus/dpaa/base/qbman/dpaa_sys.h index 034991ba1..9377738df 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/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c index 07cc5c667..ec92cac79 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 index 277ce6369..fcc5b2e74 100644 --- a/drivers/bus/dpaa/include/compat.h +++ b/drivers/bus/dpaa/include/compat.h @@ -390,7 +390,6 @@ static inline unsigned long get_zeroed_page(gfp_t __foo __rte_unused) #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/fman.h b/drivers/bus/dpaa/include/fman.h index d6eebc877..c02d32d22 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 ec1ab7cee..c18747256 100644 --- a/drivers/bus/dpaa/include/fsl_usd.h +++ b/drivers/bus/dpaa/include/fsl_usd.h @@ -9,6 +9,7 @@ #define __FSL_USD_H #include +#include #include #ifdef __cplusplus diff --git a/drivers/bus/dpaa/meson.build b/drivers/bus/dpaa/meson.build index 19daaa5b5..55338cfa7 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_dpaa_bus.h b/drivers/bus/dpaa/rte_dpaa_bus.h index 554a56f2e..e3135ecaf 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 218d9bd28..16f0a2ca4 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 94d2cf0ce..a0a1de028 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/bus/dpaa/include/dpaa_list.h b/drivers/common/dpaax/dpaa_list.h similarity index 100% rename from drivers/bus/dpaa/include/dpaa_list.h rename to drivers/common/dpaax/dpaa_list.h diff --git a/drivers/bus/dpaa/base/fman/of.c b/drivers/common/dpaax/dpaa_of.c similarity index 88% rename from drivers/bus/dpaa/base/fman/of.c rename to drivers/common/dpaax/dpaa_of.c index 1e97be54e..bb2c8fc66 100644 --- a/drivers/bus/dpaa/base/fman/of.c +++ b/drivers/common/dpaax/dpaa_of.c @@ -5,9 +5,10 @@ * */ -#include +#include +#include #include -#include +#include static int alive; static struct dt_dir root_dir; @@ -23,7 +24,7 @@ of_open_dir(const char *relative_path, struct dirent ***d) 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", + DPAAX_LOG(ERR, "Failed to open directory %s", full_path); return ret; } @@ -45,7 +46,7 @@ of_open_file(const char *relative_path) 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", + DPAAX_LOG(ERR, "Failed to open directory %s", full_path); return ret; } @@ -57,7 +58,7 @@ process_file(struct dirent *dent, struct dt_dir *parent) struct dt_file *f = malloc(sizeof(*f)); if (!f) { - DPAA_BUS_LOG(DEBUG, "Unable to allocate memory for file node"); + DPAAX_LOG(DEBUG, "Unable to allocate memory for file node"); return; } f->node.is_file = 1; @@ -67,14 +68,14 @@ process_file(struct dirent *dent, struct dt_dir *parent) f->parent = parent; fd = of_open_file(f->node.node.full_name); if (fd < 0) { - DPAA_BUS_LOG(DEBUG, "Unable to open file node"); + 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) { - DPAA_BUS_LOG(DEBUG, "Unable to read file node"); + DPAAX_LOG(DEBUG, "Unable to read file node"); free(f); return; } @@ -130,7 +131,7 @@ iterate_dir(struct dirent **d, int num, struct dt_dir *dt) list_add_tail(&subdir->node.list, &dt->subdirs); break; default: - DPAA_BUS_LOG(DEBUG, "Ignoring invalid dt entry %s/%s", + DPAAX_LOG(DEBUG, "Ignoring invalid dt entry %s/%s", dt->node.node.full_name, d[loop]->d_name); } } @@ -170,37 +171,37 @@ linear_dir(struct dt_dir *d) 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" + 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) - DPAA_BUS_LOG(DEBUG, "Duplicate status in %s", + 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) - DPAA_BUS_LOG(DEBUG, "Duplicate lphandle in %s", + 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) - DPAA_BUS_LOG(DEBUG, "Duplicate lphandle in %s", + 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) - DPAA_BUS_LOG(DEBUG, "Duplicate a_cells in %s", + 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) - DPAA_BUS_LOG(DEBUG, "Duplicate s_cells in %s", + 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) - DPAA_BUS_LOG(DEBUG, "Duplicate reg in %s", + DPAAX_LOG(DEBUG, "Duplicate reg in %s", d->node.node.full_name); d->reg = f; } @@ -220,7 +221,7 @@ of_init_path(const char *dt_path) base_dir = dt_path; /* This needs to be singleton initialization */ - DPAA_BUS_HWWARN(alive, "Double-init of device-tree driver!"); + 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'; @@ -231,7 +232,7 @@ of_init_path(const char *dt_path) /* Kick things off... */ ret = process_dir("", &root_dir); if (ret) { - DPAA_BUS_LOG(ERR, "Unable to parse device tree"); + DPAAX_LOG(ERR, "Unable to parse device tree"); return ret; } @@ -261,7 +262,7 @@ destroy_dir(struct dt_dir *d) void of_finish(void) { - DPAA_BUS_HWWARN(!alive, "Double-finish of device-tree driver!"); + DPAAX_HWWARN(!alive, "Double-finish of device-tree driver!"); destroy_dir(&root_dir); INIT_LIST_HEAD(&linear); @@ -298,12 +299,12 @@ check_compatible(const struct dt_file *f, const char *compatible) const struct device_node * of_find_compatible_node(const struct device_node *from, - const char *type __always_unused, + const char *type __rte_unused, const char *compatible) { const struct dt_dir *d; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); if (list_empty(&linear)) return NULL; @@ -328,7 +329,7 @@ of_get_property(const struct device_node *from, const char *name, const struct dt_dir *d; const struct dt_file *f; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); d = node2dir(from); list_for_each_entry(f, &d->files, node.list) @@ -345,7 +346,7 @@ of_device_is_available(const struct device_node *dev_node) { const struct dt_dir *d; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); d = node2dir(dev_node); if (!d->status) return true; @@ -357,11 +358,11 @@ of_device_is_available(const struct device_node *dev_node) } const struct device_node * -of_find_node_by_phandle(phandle ph) +of_find_node_by_phandle(uint64_t ph) { const struct dt_dir *d; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + 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)) @@ -374,7 +375,7 @@ of_get_parent(const struct device_node *dev_node) { const struct dt_dir *d; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); if (!dev_node) return NULL; @@ -390,14 +391,14 @@ of_get_next_child(const struct device_node *dev_node, { const struct dt_dir *p, *c; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_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"); + DPAAX_HWWARN((c->parent != p), "Parent/child mismatch"); if (c->parent != p) return NULL; if (c->node.list.next == &p->subdirs) @@ -418,7 +419,7 @@ of_n_addr_cells(const struct device_node *dev_node) { const struct dt_dir *d; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised"); if (!dev_node) return OF_DEFAULT_NA; d = node2dir(dev_node); @@ -440,7 +441,7 @@ of_n_size_cells(const struct device_node *dev_node) { const struct dt_dir *d; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); if (!dev_node) return OF_DEFAULT_NA; d = node2dir(dev_node); @@ -496,7 +497,7 @@ of_translate_address(const struct device_node *dev_node, size_t rlen; uint32_t na, pna; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); assert(dev_node != NULL); na = of_n_addr_cells(dev_node); @@ -538,7 +539,7 @@ of_device_is_compatible(const struct device_node *dev_node, { const struct dt_dir *d; - DPAA_BUS_HWWARN(!alive, "Device-tree driver not initialised!"); + DPAAX_HWWARN(!alive, "Device-tree driver not initialised!"); if (!dev_node) d = &root_dir; else diff --git a/drivers/bus/dpaa/include/of.h b/drivers/common/dpaax/dpaa_of.h similarity index 86% rename from drivers/bus/dpaa/include/of.h rename to drivers/common/dpaax/dpaa_of.h index 7ea7608fc..e9761ce0e 100644 --- a/drivers/bus/dpaa/include/of.h +++ b/drivers/common/dpaax/dpaa_of.h @@ -8,7 +8,24 @@ #ifndef __OF_H #define __OF_H -#include +#include +#include +#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" @@ -89,7 +106,7 @@ struct dt_file { const struct device_node *of_find_compatible_node( const struct device_node *from, - const char *type __always_unused, + const char *type __rte_unused, const char *compatible) __attribute__((nonnull(3))); @@ -102,7 +119,7 @@ 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_find_node_by_phandle(uint64_t ph); const struct device_node *of_get_parent(const struct device_node *dev_node); @@ -122,7 +139,7 @@ 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)); + const uint32_t *addr) __attribute__((nonnull)); bool of_device_is_compatible(const struct device_node *dev_node, const char *compatible); @@ -147,7 +164,7 @@ static inline int of_init(void) /* 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) +static inline uint64_t of_read_number(const uint32_t *cell, int size) { uint64_t r = 0; diff --git a/drivers/common/dpaax/dpaax_logs.h b/drivers/common/dpaax/dpaax_logs.h index bf1b27cc1..180476f67 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 a315e7786..fb97be1c1 100644 --- a/drivers/common/dpaax/meson.build +++ b/drivers/common/dpaax/meson.build @@ -8,6 +8,9 @@ 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 diff --git a/drivers/common/dpaax/rte_common_dpaax_version.map b/drivers/common/dpaax/rte_common_dpaax_version.map index 8131c9e30..a7699ae4d 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 cecfbbdc8..6eee8379f 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/crypto/caam_jr #sharing the hw flib headers from dpaa2_sec pmd CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/ @@ -37,6 +38,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_CAAM_JR) += caam_jr_uio.c LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring LDLIBS += -lrte_cryptodev +LDLIBS += -lrte_common_dpaax LDLIBS += -lrte_bus_dpaa LDLIBS += -lrte_bus_vdev diff --git a/drivers/crypto/caam_jr/caam_jr.c b/drivers/crypto/caam_jr/caam_jr.c index 77c030347..f24513b43 100644 --- a/drivers/crypto/caam_jr/caam_jr.c +++ b/drivers/crypto/caam_jr/caam_jr.c @@ -27,7 +27,7 @@ /* RTA header files */ #include #include -#include +#include #define CAAM_JR_DBG 0 #define CRYPTODEV_NAME_CAAM_JR_PMD crypto_caam_jr diff --git a/drivers/crypto/dpaa2_sec/Makefile b/drivers/crypto/dpaa2_sec/Makefile index 9c6657e52..039901bec 100644 --- a/drivers/crypto/dpaa2_sec/Makefile +++ b/drivers/crypto/dpaa2_sec/Makefile @@ -19,7 +19,7 @@ ifeq ($(shell test $(GCC_VERSION) -gt 70 && echo 1), 1) CFLAGS += -Wno-implicit-fallthrough endif endif - +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/ CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/mc CFLAGS += -I$(RTE_SDK)/drivers/bus/fslmc/ diff --git a/drivers/crypto/dpaa_sec/Makefile b/drivers/crypto/dpaa_sec/Makefile index 1d8b7bec1..8d1706597 100644 --- a/drivers/crypto/dpaa_sec/Makefile +++ b/drivers/crypto/dpaa_sec/Makefile @@ -16,6 +16,7 @@ CFLAGS += $(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/crypto/dpaa_sec/ #sharing the hw flib headers from dpaa2_sec pmd CFLAGS += -I$(RTE_SDK)/drivers/crypto/dpaa2_sec/ diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index 122c80a07..b0b6e57d4 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -27,7 +27,7 @@ #include #include -#include +#include /* RTA header files */ #include diff --git a/drivers/event/dpaa/Makefile b/drivers/event/dpaa/Makefile index cf9626495..a9f8648e7 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 EXPORT_MAP := rte_pmd_dpaa_event_version.map diff --git a/drivers/event/dpaa2/Makefile b/drivers/event/dpaa2/Makefile index 470157f25..647a8372d 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_bus_fslmc -lrte_mempool_dpaa2 -lrte_pmd_dpaa2 LDLIBS += -lrte_bus_vdev diff --git a/drivers/mempool/dpaa/Makefile b/drivers/mempool/dpaa/Makefile index ead5029fd..534e00733 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 c1df78a80..bdb941025 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 4fb16bd9d..395e4d900 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 f63a5f164..182becac1 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 30b183607..9e735cc83 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 c7262ffd5..b8387706c 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 2b4150c2d..a7c980247 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 0009fd4c6..057b2a81a 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 From patchwork Tue Oct 1 11:01:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60313 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 1AA84CFA6; Tue, 1 Oct 2019 13:17:31 +0200 (CEST) Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) by dpdk.org (Postfix) with ESMTP id CA0624C93 for ; Tue, 1 Oct 2019 13:17:27 +0200 (CEST) Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 640B9200554; Tue, 1 Oct 2019 13:17:27 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 99B952001C2; Tue, 1 Oct 2019 13:17:24 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 891E44029A; Tue, 1 Oct 2019 19:17:20 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh , Akhil Goyal Date: Tue, 1 Oct 2019 16:31:57 +0530 Message-Id: <20191001110209.6047-3-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" ppfe (programmable packet forwarding engine) is a network poll mode driver for NXP SoC ls1012a. This patch introduces the framework of ppfe driver with basic functions of initialisation and teardown. Signed-off-by: Gagandeep Singh Signed-off-by: Akhil Goyal Acked-by: Nipun Gupta --- MAINTAINERS | 6 + config/common_armv8a_linux | 5 + config/common_base | 5 + doc/guides/nics/features/ppfe.ini | 8 + drivers/net/Makefile | 1 + drivers/net/meson.build | 1 + drivers/net/ppfe/Makefile | 28 ++ drivers/net/ppfe/meson.build | 11 + drivers/net/ppfe/pfe_eth.h | 73 +++++ drivers/net/ppfe/pfe_mod.h | 56 ++++ drivers/net/ppfe/ppfe_ethdev.c | 322 ++++++++++++++++++++++ drivers/net/ppfe/rte_pmd_ppfe_version.map | 4 + mk/rte.app.mk | 1 + 13 files changed, 521 insertions(+) create mode 100644 doc/guides/nics/features/ppfe.ini create mode 100644 drivers/net/ppfe/Makefile create mode 100644 drivers/net/ppfe/meson.build create mode 100644 drivers/net/ppfe/pfe_eth.h create mode 100644 drivers/net/ppfe/pfe_mod.h create mode 100644 drivers/net/ppfe/ppfe_ethdev.c create mode 100644 drivers/net/ppfe/rte_pmd_ppfe_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 6adf20107..655ccae83 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -787,6 +787,12 @@ F: drivers/net/enetc/ F: doc/guides/nics/enetc.rst F: doc/guides/nics/features/enetc.ini +NXP ppfe +M: Gagandeep Singh +M: Akhil Goyal +F: drivers/net/ppfe/ +F: doc/guides/nics/features/ppfe.ini + QLogic bnx2x M: Rasesh Mody M: Shahed Shaikh diff --git a/config/common_armv8a_linux b/config/common_armv8a_linux index 481712ebc..5b82405c5 100644 --- a/config/common_armv8a_linux +++ b/config/common_armv8a_linux @@ -36,4 +36,9 @@ CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n CONFIG_RTE_LIBRTE_AVP_PMD=n CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV=n +# +# NXP PPFE PMD Driver +# +CONFIG_RTE_LIBRTE_PPFE_PMD=y + CONFIG_RTE_SCHED_VECTOR=n diff --git a/config/common_base b/config/common_base index 6a7e00d75..fc792f738 100644 --- a/config/common_base +++ b/config/common_base @@ -218,6 +218,11 @@ CONFIG_RTE_LIBRTE_BNXT_PMD=y # CONFIG_RTE_LIBRTE_CXGBE_PMD=y +# +# Compile burst-oriented NXP PPFE PMD driver +# +CONFIG_RTE_LIBRTE_PPFE_PMD=n + # NXP DPAA Bus CONFIG_RTE_LIBRTE_DPAA_BUS=n CONFIG_RTE_LIBRTE_DPAA_MEMPOOL=n diff --git a/doc/guides/nics/features/ppfe.ini b/doc/guides/nics/features/ppfe.ini new file mode 100644 index 000000000..4bcac779c --- /dev/null +++ b/doc/guides/nics/features/ppfe.ini @@ -0,0 +1,8 @@ +; +; Supported features of the 'ppfe' network poll mode driver. +; +; Refer to default.ini for the full list of available PMD features. +; +[Features] +Linux VFIO = Y +ARMv8 = Y diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1770d8b23..d09d32177 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -50,6 +50,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += null DIRS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += octeontx DIRS-$(CONFIG_RTE_LIBRTE_OCTEONTX2_PMD) += octeontx2 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap +DIRS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += ppfe DIRS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring DIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc diff --git a/drivers/net/meson.build b/drivers/net/meson.build index eb1c6b638..e17b5ef1b 100644 --- a/drivers/net/meson.build +++ b/drivers/net/meson.build @@ -38,6 +38,7 @@ drivers = ['af_packet', 'octeontx', 'octeontx2', 'pcap', + 'ppfe', 'ring', 'sfc', 'softnic', diff --git a/drivers/net/ppfe/Makefile b/drivers/net/ppfe/Makefile new file mode 100644 index 000000000..b9e894ffd --- /dev/null +++ b/drivers/net/ppfe/Makefile @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019 NXP +# + +include $(RTE_SDK)/mk/rte.vars.mk + +# +# library name +# +LIB = librte_pmd_ppfe.a + +CFLAGS += -O3 $(WERROR_FLAGS) +CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include/ +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax + +EXPORT_MAP := rte_pmd_ppfe_version.map +LIBABIVER := 1 + +# Interfaces with DPDK +SRCS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += ppfe_ethdev.c + +LDLIBS += -lrte_bus_vdev +LDLIBS += -lrte_bus_dpaa +LDLIBS += -lrte_common_dpaax +LDLIBS += -lrte_eal +LDLIBS += -lrte_ethdev -lrte_kvargs + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/net/ppfe/meson.build b/drivers/net/ppfe/meson.build new file mode 100644 index 000000000..8ca2cb87d --- /dev/null +++ b/drivers/net/ppfe/meson.build @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019 NXP + +if host_machine.system() != 'linux' + build = false +endif +deps += ['bus_dpaa'] + +sources = files('ppfe_ethdev.c') + +includes += include_directories('../../bus/dpaa/include/') diff --git a/drivers/net/ppfe/pfe_eth.h b/drivers/net/ppfe/pfe_eth.h new file mode 100644 index 000000000..5811b54eb --- /dev/null +++ b/drivers/net/ppfe/pfe_eth.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_ETH_H_ +#define _PFE_ETH_H_ + +#include +#include +#include + +#define ETH_ALEN 6 +#define GEMAC_NO_PHY BIT(0) + +#define PFE_SOC_ID_FILE "/sys/devices/soc0/soc_id" +extern unsigned int pfe_svr; +#define SVR_LS1012A_REV2 0x87040020 +#define SVR_LS1012A_REV1 0x87040010 + +struct ls1012a_eth_platform_data { + /* device specific information */ + u32 device_flags; + char name[16]; + + /* board specific information */ + u32 mii_config; + u32 phy_flags; + u32 gem_id; + u32 bus_id; + u32 phy_id; + u32 mdio_muxval; + u8 mac_addr[ETH_ALEN]; +}; + +struct ls1012a_mdio_platform_data { + int enabled; + int irq[32]; + u32 phy_mask; + int mdc_div; +}; + +struct ls1012a_pfe_platform_data { + struct ls1012a_eth_platform_data ls1012a_eth_pdata[3]; + struct ls1012a_mdio_platform_data ls1012a_mdio_pdata[3]; +}; + +#define EMAC_TXQ_CNT 16 +#define EMAC_TXQ_DEPTH (HIF_TX_DESC_NT) + +#define JUMBO_FRAME_SIZE 10258 +#define EMAC_RXQ_CNT 1 +#define EMAC_RXQ_DEPTH HIF_RX_DESC_NT + +struct pfe_eth_priv_s { + struct pfe *pfe; + int low_tmu_q; + int high_tmu_q; + struct rte_eth_dev *ndev; + struct rte_eth_stats stats; + int id; + int promisc; + int link_fd; + + spinlock_t lock; /* protect member variables */ + void *EMAC_baseaddr; + /* This points to the EMAC base from where we access PHY */ + void *PHY_baseaddr; + void *GPI_baseaddr; + + struct ls1012a_eth_platform_data *einfo; +}; + +#endif /* _PFE_ETH_H_ */ diff --git a/drivers/net/ppfe/pfe_mod.h b/drivers/net/ppfe/pfe_mod.h new file mode 100644 index 000000000..e971547a9 --- /dev/null +++ b/drivers/net/ppfe/pfe_mod.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_MOD_H_ +#define _PFE_MOD_H_ + +struct pfe; + +#include "pfe_eth.h" + +#define PHYID_MAX_VAL 32 + +/* PPFE DPDK driver supports two interfaces. + */ +#define PFE_CDEV_ETH_COUNT 2 + +/* PPFE DPDK driver needs a kernel module named "pfe.ko", This module + * is required for PHY initialisation and creates a character device + * "pfe_us_cdev" for IOCTL support. PPFE DPDK driver uses this character + * device for link status. + */ +#define PFE_CDEV_PATH "/dev/pfe_us_cdev" +#define PFE_CDEV_INVALID_FD -1 +#define PFE_NAME_PMD eth_pfe + +/* used when 'read' call is issued, returning PFE_CDEV_ETH_COUNT number of + * pfe_shared_info as array. + */ +struct pfe_shared_info { + uint32_t phy_id; /* Link phy ID */ + uint8_t state; /* Has either 0 or 1 */ +}; + +struct pfe_eth { + struct pfe_eth_priv_s *eth_priv[PFE_CDEV_ETH_COUNT]; +}; + +struct pfe { + uint64_t ddr_phys_baseaddr; + void *ddr_baseaddr; + uint64_t ddr_size; + void *cbus_baseaddr; + uint64_t cbus_size; + struct pfe_eth eth; + int mdio_muxval[PHYID_MAX_VAL]; + uint8_t nb_devs; + uint8_t max_intf; + int cdev_fd; +}; + +/* IOCTL Commands */ +#define PFE_CDEV_ETH0_STATE_GET _IOR('R', 0, int) +#define PFE_CDEV_ETH1_STATE_GET _IOR('R', 1, int) +#define PFE_CDEV_HIF_INTR_EN _IOWR('R', 2, int) +#endif /* _PFE_MOD_H */ diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c new file mode 100644 index 000000000..1b409a134 --- /dev/null +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -0,0 +1,322 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include +#include +#include +#include + +#include "pfe_mod.h" + +#define PPFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/ +#define PPFE_VDEV_GEM_ID_ARG "intf" + +struct pfe_vdev_init_params { + int8_t gem_id; +}; +static struct pfe *g_pfe; + +/* TODO: make pfe_svr a runtime option. + * Driver should be able to get the SVR + * information from HW. + */ +unsigned int pfe_svr = SVR_LS1012A_REV1; + +static void +pfe_soc_version_get(void) +{ + FILE *svr_file = NULL; + unsigned int svr_ver = 0; + + svr_file = fopen(PFE_SOC_ID_FILE, "r"); + if (!svr_file) + return; /* Not supported on this infra */ + + if (fscanf(svr_file, "svr:%x", &svr_ver) > 0) + pfe_svr = svr_ver; + else + printf("Unable to read SoC device"); + + fclose(svr_file); +} + +static int +pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) +{ + int pfe_cdev_fd; + + if (priv == NULL) + return -1; + + pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); + if (pfe_cdev_fd < 0) { + priv->link_fd = PFE_CDEV_INVALID_FD; + return -1; + } + + priv->link_fd = pfe_cdev_fd; + + return 0; +} + +static void +pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) +{ + if (priv == NULL) + return; + + if (priv->link_fd != PFE_CDEV_INVALID_FD) { + close(priv->link_fd); + priv->link_fd = PFE_CDEV_INVALID_FD; + } +} + +static void +pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) +{ + /* Close the device file for link status */ + pfe_eth_close_cdev(dev->data->dev_private); + + rte_free(dev->data->mac_addrs); + rte_eth_dev_release_port(dev); + pfe->nb_devs--; +} + +static int +pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) +{ + struct rte_eth_dev *eth_dev = NULL; + struct pfe_eth_priv_s *priv = NULL; + int err; + + eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); + if (eth_dev == NULL) + return -ENOMEM; + + priv = eth_dev->data->dev_private; + priv->ndev = eth_dev; + priv->pfe = pfe; + + pfe->eth.eth_priv[id] = priv; + +#define HIF_GEMAC_TMUQ_BASE 6 + priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); + priv->high_tmu_q = priv->low_tmu_q + 1; + + rte_spinlock_init(&priv->lock); + + /* Copy the station address into the dev structure, */ + eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", + ETHER_ADDR_LEN * PPFE_MAX_MACS, 0); + if (eth_dev->data->mac_addrs == NULL) { + err = -ENOMEM; + goto err0; + } + + eth_dev->data->mtu = 1500; + + eth_dev->data->nb_rx_queues = 1; + eth_dev->data->nb_tx_queues = 1; + + /* For link status, open the PFE CDEV; Error from this function + * is silently ignored; In case of error, the link status will not + * be available. + */ + pfe_eth_open_cdev(priv); + rte_eth_dev_probing_finish(eth_dev); + + return 0; +err0: + rte_eth_dev_release_port(eth_dev); + return err; +} + +/* Parse integer from integer argument */ +static int +parse_integer_arg(const char *key __rte_unused, + const char *value, void *extra_args) +{ + int i; + char *end; + errno = 0; + + i = strtol(value, &end, 10); + if (*end != 0 || errno != 0 || i < 0 || i > 1) + return -EINVAL; + + *((uint32_t *)extra_args) = i; + + return 0; +} + +static int +pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params, + struct rte_vdev_device *dev) +{ + struct rte_kvargs *kvlist = NULL; + int ret = 0; + + static const char * const pfe_vdev_valid_params[] = { + PPFE_VDEV_GEM_ID_ARG, + NULL + }; + + const char *input_args = rte_vdev_device_args(dev); + + if (!input_args) + return -1; + + kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params); + if (kvlist == NULL) + return -1; + + ret = rte_kvargs_process(kvlist, + PPFE_VDEV_GEM_ID_ARG, + &parse_integer_arg, + ¶ms->gem_id); + rte_kvargs_free(kvlist); + return ret; +} + +static int +pmd_pfe_probe(struct rte_vdev_device *vdev) +{ + const u32 *prop; + const struct device_node *np; + const char *name; + const uint32_t *addr; + uint64_t cbus_addr, ddr_size, cbus_size; + int rc = -1, fd = -1, gem_id; + unsigned int interface_count = 0; + size_t size = 0; + struct pfe_vdev_init_params init_params = { + .gem_id = -1 + }; + + name = rte_vdev_device_name(vdev); + rc = pfe_parse_vdev_init_params(&init_params, vdev); + if (rc < 0) + return -EINVAL; + + if (g_pfe) { + if (g_pfe->nb_devs >= g_pfe->max_intf) + return -EINVAL; + + goto eth_init; + } + + g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE); + if (g_pfe == NULL) + return -EINVAL; + + /* Load the device-tree driver */ + rc = of_init(); + if (rc) + goto err; + + np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); + if (!np) { + rc = -EINVAL; + goto err; + } + + addr = of_get_address(np, 0, &cbus_size, NULL); + if (!addr) + goto err; + + cbus_addr = of_translate_address(np, addr); + if (!cbus_addr) + goto err; + + + addr = of_get_address(np, 1, &ddr_size, NULL); + if (!addr) + goto err; + + g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); + if (!g_pfe->ddr_phys_baseaddr) + goto err; + + g_pfe->ddr_size = ddr_size; + g_pfe->cbus_size = cbus_size; + + fd = open("/dev/mem", O_RDWR); + g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, cbus_addr); + close(fd); + if (g_pfe->cbus_baseaddr == MAP_FAILED) { + rc = -EINVAL; + goto err; + } + + /* Read interface count */ + prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); + if (!prop) { + rc = -ENXIO; + goto err_prop; + } + + interface_count = rte_be_to_cpu_32((unsigned int)*prop); + if (interface_count <= 0) { + rc = -ENXIO; + goto err_prop; + } + g_pfe->max_intf = interface_count; + pfe_soc_version_get(); +eth_init: + if (init_params.gem_id < 0) + gem_id = g_pfe->nb_devs; + else + gem_id = init_params.gem_id; + + RTE_LOG(INFO, PMD, "Init pmd_pfe for %s gem-id %d(given =%d)\n", + name, gem_id, init_params.gem_id); + + rc = pfe_eth_init(vdev, g_pfe, gem_id); + if (rc < 0) + goto err_eth; + else + g_pfe->nb_devs++; + + return 0; + +err_eth: +err_prop: + munmap(g_pfe->cbus_baseaddr, cbus_size); +err: + rte_free(g_pfe); + return rc; +} + +static int +pmd_pfe_remove(struct rte_vdev_device *vdev) +{ + const char *name; + struct rte_eth_dev *eth_dev = NULL; + + name = rte_vdev_device_name(vdev); + if (name == NULL) + return -EINVAL; + + if (!g_pfe) + return 0; + + eth_dev = rte_eth_dev_allocated(name); + if (eth_dev == NULL) + return -ENODEV; + + pfe_eth_exit(eth_dev, g_pfe); + munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size); + + return 0; +} + +static +struct rte_vdev_driver pmd_pfe_drv = { + .probe = pmd_pfe_probe, + .remove = pmd_pfe_remove, +}; + +RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); +RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PPFE_VDEV_GEM_ID_ARG "= "); diff --git a/drivers/net/ppfe/rte_pmd_ppfe_version.map b/drivers/net/ppfe/rte_pmd_ppfe_version.map new file mode 100644 index 000000000..b7b7c9168 --- /dev/null +++ b/drivers/net/ppfe/rte_pmd_ppfe_version.map @@ -0,0 +1,4 @@ +DPDK_19.11 { + + local: *; +}; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 17b991604..5e559cc7d 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -161,6 +161,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe ifeq ($(CONFIG_RTE_LIBRTE_DPAA_BUS),y) _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA_PMD) += -lrte_pmd_dpaa +_LDLIBS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += -lrte_pmd_ppfe endif ifeq ($(CONFIG_RTE_EAL_VFIO)$(CONFIG_RTE_LIBRTE_FSLMC_BUS),yy) _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_pmd_dpaa2 From patchwork Tue Oct 1 11:01:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60314 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 622221BDFD; Tue, 1 Oct 2019 13:17:33 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 2DB584C93 for ; Tue, 1 Oct 2019 13:17:28 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 0FC301A055E; Tue, 1 Oct 2019 13:17:28 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id A7DDC1A053F; Tue, 1 Oct 2019 13:17:25 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id D7022402C1; Tue, 1 Oct 2019 19:17:21 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:31:58 +0530 Message-Id: <20191001110209.6047-4-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add documentation for ppfe network poll mode driver. PPFE is a hardware programmable packet forwarding engine to provide high performance ethernet interfaces. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- MAINTAINERS | 1 + doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/index.rst | 1 + doc/guides/nics/ppfe.rst | 173 ++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 doc/guides/nics/ppfe.rst diff --git a/MAINTAINERS b/MAINTAINERS index 655ccae83..83af78144 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -790,6 +790,7 @@ F: doc/guides/nics/features/enetc.ini NXP ppfe M: Gagandeep Singh M: Akhil Goyal +F: doc/guides/nics/ppfe.rst F: drivers/net/ppfe/ F: doc/guides/nics/features/ppfe.ini diff --git a/doc/guides/nics/features/ppfe.ini b/doc/guides/nics/features/ppfe.ini index 4bcac779c..cd5f836a3 100644 --- a/doc/guides/nics/features/ppfe.ini +++ b/doc/guides/nics/features/ppfe.ini @@ -6,3 +6,4 @@ [Features] Linux VFIO = Y ARMv8 = Y +Usage doc = Y diff --git a/doc/guides/nics/index.rst b/doc/guides/nics/index.rst index d477001d9..e0c931a3e 100644 --- a/doc/guides/nics/index.rst +++ b/doc/guides/nics/index.rst @@ -48,6 +48,7 @@ Network Interface Controller Drivers nfp octeontx octeontx2 + ppfe qede sfc_efx softnic diff --git a/doc/guides/nics/ppfe.rst b/doc/guides/nics/ppfe.rst new file mode 100644 index 000000000..29b02957f --- /dev/null +++ b/doc/guides/nics/ppfe.rst @@ -0,0 +1,173 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 NXP + +PPFE Poll Mode Driver +====================== + +The PPFE NIC PMD (**librte_pmd_ppfe**) provides poll mode driver +support for the inbuilt NIC found in the **NXP LS1012** SoC. + +More information can be found at `NXP Official Website +`_. + +PPFE +----- + +This section provides an overview of the NXP PPFE +and how it is integrated into the DPDK. + +Contents summary + +- PPFE overview +- PPFE features +- Supported PPFE SoCs +- Prerequisites +- Driver compilation and testing +- Limitations + +PPFE Overview +~~~~~~~~~~~~~~ + +PPFE is a hardware programmable packet forwarding engine to provide +high performance Ethernet interfaces. The diagram below shows a +system level overview of PPFE: + +.. code-block:: console + + ====================================================+=============== + US +-----------------------------------------+ | Kernel Space + | | | + | PPFE Ethernet Driver | | + +-----------------------------------------+ | + ^ | ^ | | + PPFE RXQ| |TXQ RXQ| |TXQ | + PMD | | | | | + | v | v | +----------+ + +---------+ +----------+ | | pfe.ko | + | pfe_eth0| | pfe_eth1 | | +----------+ + +---------+ +----------+ | + ^ | ^ | | + TXQ| |RXQ TXQ| |RXQ | + | | | | | + | v | v | + +------------------------+ | + | | | + | PPFE HIF driver | | + +------------------------+ | + ^ | | + RX | TX | | + RING| RING| | + | v | + +--------------+ | + | | | + ==================| HIF |==================+=============== + +-----------+ +--------------+ + | | | | HW + | PPFE +--------------+ | + | +-----+ +-----+ | + | | MAC | | MAC | | + | | | | | | + +-------+-----+----------------+-----+----+ + | PHY | | PHY | + +-----+ +-----+ + + +The HIF, PPFE, MAC and PHY are the hardware blocks, the pfe.ko is a kernel +module, the PPFE HIF driver and the PPFE ethernet driver combined represent +as DPDK PPFE poll mode driver are running in the userspace. + +The PPFE hardware supports one HIF (host interface) RX ring and one TX ring +to send and receive packets through packet forwarding engine. Both network +interface traffic is multiplexed and send over HIF queue. + +pfe_eth0 and pfe_eth1 are logical ethernet interfaces, created by HIF client +driver. HIF driver is responsible for send and receive packets between +host interface and these logical interfaces. PPFE ethernet driver is a +hardware independent and register with the HIF client driver to transmit and +receive packets from HIF via logical interfaces. + +pfe.ko is required for PHY initialisation and also responsible for creating +the character device "pfe_us_cdev" which will be used for interacting with +the kernel layer for link status. + +PPFE Features +~~~~~~~~~~~~~~ + +- ARMv8 + +Supported PPFE SoCs +~~~~~~~~~~~~~~~~~~~~ + +- LS1012 + +Prerequisites +~~~~~~~~~~~~~ + +Below are some pre-requisites for executing PPFE PMD on a PPFE +compatible board: + +1. **ARM 64 Tool Chain** + + For example, the `*aarch64* Linaro Toolchain `_. + +2. **Linux Kernel** + + It can be obtained from `NXP's Github hosting `_. + +3. **Rootfile system** + + Any *aarch64* supporting filesystem can be used. For example, + Ubuntu 16.04 LTS (Xenial) or 18.04 (Bionic) userland which can be obtained + from `here `_. + +4. The ethernet device will be registered as virtual device, so ppfe has dependency on + **rte_bus_vdev** library and it is mandatory to use `--vdev` with value `eth_pfe` to + run DPDK application. + +The following dependencies are not part of DPDK and must be installed +separately: + +- **NXP Linux LSDK** + + NXP Layerscape software development kit (LSDK) includes support for family + of QorIQ® ARM-Architecture-based system on chip (SoC) processors + and corresponding boards. + + It includes the Linux board support packages (BSPs) for NXP SoCs, + a fully operational tool chain, kernel and board specific modules. + + LSDK and related information can be obtained from: `LSDK `_ + +- **pfe kernel module** + + pfe kernel module can be obtained from NXP Layerscape software development kit at + location `/lib/modules//kernel/drivers/staging/fsl_ppfe` in rootfs. + Module should be loaded using below command: + + .. code-block:: console + + insmod pfe.ko us=1 + + +Driver compilation and testing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Follow instructions available in the document +:ref:`compiling and testing a PMD for a NIC ` +to launch **testpmd** + +Additionally, PPFE driver needs `--vdev` as an input with value `eth_pfe` +to execute DPDK application. There is an optional parameter `intf` available +to specify port ID. PPFE driver supports only two interfaces, so valid values +for `intf` are 0 and 1. +see the command below: + + .. code-block:: console + + --vdev="eth_pfe0,intf=0" --vdev="eth_pfe1,intf=1" -- ... + + +Limitations +~~~~~~~~~~~ + +- Multi buffer pool cannot be supported. From patchwork Tue Oct 1 11:01:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60315 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 40B9A1BE3D; Tue, 1 Oct 2019 13:17:35 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 86C625B3A for ; Tue, 1 Oct 2019 13:17:29 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 43F621A053F; Tue, 1 Oct 2019 13:17:29 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id DC2A81A0548; Tue, 1 Oct 2019 13:17:26 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id EA16C40313; Tue, 1 Oct 2019 19:17:22 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:31:59 +0530 Message-Id: <20191001110209.6047-5-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 04/14] net/ppfe: support dynamic logging X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch introduces logging for the ppfe PMD. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- drivers/net/ppfe/pfe_logs.h | 31 +++++++++++++++ drivers/net/ppfe/ppfe_ethdev.c | 69 ++++++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 drivers/net/ppfe/pfe_logs.h diff --git a/drivers/net/ppfe/pfe_logs.h b/drivers/net/ppfe/pfe_logs.h new file mode 100644 index 000000000..8c6499bb8 --- /dev/null +++ b/drivers/net/ppfe/pfe_logs.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_LOGS_H_ +#define _PFE_LOGS_H_ + +extern int ppfe_logtype_pmd; + +/* PMD related logs */ +#define PFE_PMD_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, ppfe_logtype_pmd, "ppfe_net: %s()" \ + fmt "\n", __func__, ##args) + +#define PMD_INIT_FUNC_TRACE() PFE_PMD_LOG(DEBUG, " >>") + +#define PFE_PMD_DEBUG(fmt, args...) \ + PFE_PMD_LOG(DEBUG, fmt, ## args) +#define PFE_PMD_ERR(fmt, args...) \ + PFE_PMD_LOG(ERR, fmt, ## args) +#define PFE_PMD_INFO(fmt, args...) \ + PFE_PMD_LOG(INFO, fmt, ## args) + +#define PFE_PMD_WARN(fmt, args...) \ + PFE_PMD_LOG(WARNING, fmt, ## args) + +/* DP Logs, toggled out at compile time if level lower than current level */ +#define PFE_DP_LOG(level, fmt, args...) \ + RTE_LOG_DP(level, PMD, fmt, ## args) + +#endif /* _PFE_LOGS_H_ */ diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 1b409a134..77e3e5c30 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -7,6 +7,7 @@ #include #include +#include "pfe_logs.h" #include "pfe_mod.h" #define PPFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/ @@ -23,20 +24,26 @@ static struct pfe *g_pfe; */ unsigned int pfe_svr = SVR_LS1012A_REV1; +int ppfe_logtype_pmd; + static void pfe_soc_version_get(void) { FILE *svr_file = NULL; unsigned int svr_ver = 0; + PMD_INIT_FUNC_TRACE(); + svr_file = fopen(PFE_SOC_ID_FILE, "r"); - if (!svr_file) + if (!svr_file) { + PFE_PMD_ERR("Unable to open SoC device"); return; /* Not supported on this infra */ + } if (fscanf(svr_file, "svr:%x", &svr_ver) > 0) pfe_svr = svr_ver; else - printf("Unable to read SoC device"); + PFE_PMD_ERR("Unable to read SoC device"); fclose(svr_file); } @@ -51,6 +58,9 @@ pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY); if (pfe_cdev_fd < 0) { + PFE_PMD_WARN("Unable to open PFE device file (%s).\n", + PFE_CDEV_PATH); + PFE_PMD_WARN("Link status update will not be available.\n"); priv->link_fd = PFE_CDEV_INVALID_FD; return -1; } @@ -75,6 +85,8 @@ pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) static void pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) { + PMD_INIT_FUNC_TRACE(); + /* Close the device file for link status */ pfe_eth_close_cdev(dev->data->dev_private); @@ -110,6 +122,8 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", ETHER_ADDR_LEN * PPFE_MAX_MACS, 0); if (eth_dev->data->mac_addrs == NULL) { + PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses", + ETHER_ADDR_LEN * PPFE_MAX_MACS); err = -ENOMEM; goto err0; } @@ -142,8 +156,10 @@ parse_integer_arg(const char *key __rte_unused, errno = 0; i = strtol(value, &end, 10); - if (*end != 0 || errno != 0 || i < 0 || i > 1) + if (*end != 0 || errno != 0 || i < 0 || i > 1) { + PFE_PMD_ERR("Supported Port IDS are 0 and 1"); return -EINVAL; + } *((uint32_t *)extra_args) = i; @@ -199,10 +215,15 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) if (rc < 0) return -EINVAL; + RTE_LOG(INFO, PMD, "Initializing pmd_pfe for %s Given gem-id %d\n", + name, init_params.gem_id); + if (g_pfe) { - if (g_pfe->nb_devs >= g_pfe->max_intf) + if (g_pfe->nb_devs >= g_pfe->max_intf) { + PFE_PMD_ERR("PPFE %d dev already created Max is %d", + g_pfe->nb_devs, g_pfe->max_intf); return -EINVAL; - + } goto eth_init; } @@ -212,31 +233,40 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) /* Load the device-tree driver */ rc = of_init(); - if (rc) + if (rc) { + PFE_PMD_ERR("of_init failed with ret: %d", rc); goto err; + } np = of_find_compatible_node(NULL, NULL, "fsl,pfe"); if (!np) { + PFE_PMD_ERR("Invalid device node"); rc = -EINVAL; goto err; } addr = of_get_address(np, 0, &cbus_size, NULL); - if (!addr) + if (!addr) { + PFE_PMD_ERR("of_get_address cannot return qman address\n"); goto err; - + } cbus_addr = of_translate_address(np, addr); - if (!cbus_addr) + if (!cbus_addr) { + PFE_PMD_ERR("of_translate_address failed\n"); goto err; - + } addr = of_get_address(np, 1, &ddr_size, NULL); - if (!addr) + if (!addr) { + PFE_PMD_ERR("of_get_address cannot return qman address\n"); goto err; + } g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr); - if (!g_pfe->ddr_phys_baseaddr) + if (!g_pfe->ddr_phys_baseaddr) { + PFE_PMD_ERR("of_translate_address failed\n"); goto err; + } g_pfe->ddr_size = ddr_size; g_pfe->cbus_size = cbus_size; @@ -246,6 +276,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) MAP_SHARED, fd, cbus_addr); close(fd); if (g_pfe->cbus_baseaddr == MAP_FAILED) { + PFE_PMD_ERR("Can not map cbus base"); rc = -EINVAL; goto err; } @@ -253,15 +284,20 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) /* Read interface count */ prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); if (!prop) { + PFE_PMD_ERR("Failed to read number of interfaces"); rc = -ENXIO; goto err_prop; } interface_count = rte_be_to_cpu_32((unsigned int)*prop); if (interface_count <= 0) { + PFE_PMD_ERR("No ethernet interface count : %d", + interface_count); rc = -ENXIO; goto err_prop; } + PFE_PMD_INFO("num interfaces = %d ", interface_count); + g_pfe->max_intf = interface_count; pfe_soc_version_get(); eth_init: @@ -299,6 +335,8 @@ pmd_pfe_remove(struct rte_vdev_device *vdev) if (name == NULL) return -EINVAL; + PFE_PMD_INFO("Closing eventdev sw device %s", name); + if (!g_pfe) return 0; @@ -320,3 +358,10 @@ struct rte_vdev_driver pmd_pfe_drv = { RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv); RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PPFE_VDEV_GEM_ID_ARG "= "); + +RTE_INIT(ppfe_pmd_init_log) +{ + ppfe_logtype_pmd = rte_log_register("pmd.net.ppfe"); + if (ppfe_logtype_pmd >= 0) + rte_log_set_level(ppfe_logtype_pmd, RTE_LOG_NOTICE); +} From patchwork Tue Oct 1 11:02:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60316 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 371F01BE86; Tue, 1 Oct 2019 13:17:37 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 9EBA71B948 for ; Tue, 1 Oct 2019 13:17:31 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 79AA51A01DE; Tue, 1 Oct 2019 13:17:31 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 4C6D11A0096; Tue, 1 Oct 2019 13:17:28 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 2096340318; Tue, 1 Oct 2019 19:17:24 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh , Akhil Goyal Date: Tue, 1 Oct 2019 16:32:00 +0530 Message-Id: <20191001110209.6047-6-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 05/14] net/ppfe: add HW specific macros and operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add some hardware specific macros and functions that will be used by the driver. Signed-off-by: Gagandeep Singh Signed-off-by: Akhil Goyal Acked-by: Nipun Gupta --- drivers/net/ppfe/base/cbus.h | 66 +++++ drivers/net/ppfe/base/cbus/bmu.h | 41 +++ drivers/net/ppfe/base/cbus/class_csr.h | 277 ++++++++++++++++++++ drivers/net/ppfe/base/cbus/emac_mtip.h | 231 +++++++++++++++++ drivers/net/ppfe/base/cbus/gpi.h | 77 ++++++ drivers/net/ppfe/base/cbus/hif.h | 86 +++++++ drivers/net/ppfe/base/cbus/hif_nocpy.h | 36 +++ drivers/net/ppfe/base/cbus/tmu_csr.h | 154 +++++++++++ drivers/net/ppfe/base/cbus/util_csr.h | 47 ++++ drivers/net/ppfe/base/pfe.h | 339 +++++++++++++++++++++++++ 10 files changed, 1354 insertions(+) create mode 100644 drivers/net/ppfe/base/cbus.h create mode 100644 drivers/net/ppfe/base/cbus/bmu.h create mode 100644 drivers/net/ppfe/base/cbus/class_csr.h create mode 100644 drivers/net/ppfe/base/cbus/emac_mtip.h create mode 100644 drivers/net/ppfe/base/cbus/gpi.h create mode 100644 drivers/net/ppfe/base/cbus/hif.h create mode 100644 drivers/net/ppfe/base/cbus/hif_nocpy.h create mode 100644 drivers/net/ppfe/base/cbus/tmu_csr.h create mode 100644 drivers/net/ppfe/base/cbus/util_csr.h create mode 100644 drivers/net/ppfe/base/pfe.h diff --git a/drivers/net/ppfe/base/cbus.h b/drivers/net/ppfe/base/cbus.h new file mode 100644 index 000000000..2de2bfa5d --- /dev/null +++ b/drivers/net/ppfe/base/cbus.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _CBUS_H_ +#define _CBUS_H_ + +#include + +#define EMAC1_BASE_ADDR (CBUS_BASE_ADDR + 0x200000) +#define EGPI1_BASE_ADDR (CBUS_BASE_ADDR + 0x210000) +#define EMAC2_BASE_ADDR (CBUS_BASE_ADDR + 0x220000) +#define EGPI2_BASE_ADDR (CBUS_BASE_ADDR + 0x230000) +#define BMU1_BASE_ADDR (CBUS_BASE_ADDR + 0x240000) +#define BMU2_BASE_ADDR (CBUS_BASE_ADDR + 0x250000) +#define ARB_BASE_ADDR (CBUS_BASE_ADDR + 0x260000) +#define DDR_CONFIG_BASE_ADDR (CBUS_BASE_ADDR + 0x270000) +#define HIF_BASE_ADDR (CBUS_BASE_ADDR + 0x280000) +#define HGPI_BASE_ADDR (CBUS_BASE_ADDR + 0x290000) +#define LMEM_BASE_ADDR (CBUS_BASE_ADDR + 0x300000) +#define LMEM_SIZE 0x10000 +#define LMEM_END (LMEM_BASE_ADDR + LMEM_SIZE) +#define TMU_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x310000) +#define CLASS_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x320000) +#define HIF_NOCPY_BASE_ADDR (CBUS_BASE_ADDR + 0x350000) +#define UTIL_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x360000) +#define CBUS_GPT_BASE_ADDR (CBUS_BASE_ADDR + 0x370000) + +/* + * defgroup XXX_MEM_ACCESS_ADDR PE memory access through CSR + * XXX_MEM_ACCESS_ADDR register bit definitions. + */ +#define PE_MEM_ACCESS_WRITE BIT(31) /* Internal Memory Write. */ +#define PE_MEM_ACCESS_IMEM BIT(15) +#define PE_MEM_ACCESS_DMEM BIT(16) + +/* Byte Enables of the Internal memory access. These are interpred in BE */ +#define PE_MEM_ACCESS_BYTE_ENABLE(offset, size) \ + ({ typeof(size) size_ = (size); \ + (((BIT(size_) - 1) << (4 - (offset) - (size_))) & 0xf) << 24; }) + +#include "cbus/emac_mtip.h" +#include "cbus/gpi.h" +#include "cbus/bmu.h" +#include "cbus/hif.h" +#include "cbus/tmu_csr.h" +#include "cbus/class_csr.h" +#include "cbus/hif_nocpy.h" +#include "cbus/util_csr.h" + +/* PFE cores states */ +#define CORE_DISABLE 0x00000000 +#define CORE_ENABLE 0x00000001 +#define CORE_SW_RESET 0x00000002 + +/* LMEM defines */ +#define LMEM_HDR_SIZE 0x0010 +#define LMEM_BUF_SIZE_LN2 0x7 +#define LMEM_BUF_SIZE BIT(LMEM_BUF_SIZE_LN2) + +/* DDR defines */ +#define DDR_HDR_SIZE 0x0100 +#define DDR_BUF_SIZE_LN2 0xb +#define DDR_BUF_SIZE BIT(DDR_BUF_SIZE_LN2) + +#endif /* _CBUS_H_ */ diff --git a/drivers/net/ppfe/base/cbus/bmu.h b/drivers/net/ppfe/base/cbus/bmu.h new file mode 100644 index 000000000..c2a4a2813 --- /dev/null +++ b/drivers/net/ppfe/base/cbus/bmu.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _BMU_H_ +#define _BMU_H_ + +#define BMU_VERSION 0x000 +#define BMU_CTRL 0x004 +#define BMU_UCAST_CONFIG 0x008 +#define BMU_UCAST_BASE_ADDR 0x00c +#define BMU_BUF_SIZE 0x010 +#define BMU_BUF_CNT 0x014 +#define BMU_THRES 0x018 +#define BMU_INT_SRC 0x020 +#define BMU_INT_ENABLE 0x024 +#define BMU_ALLOC_CTRL 0x030 +#define BMU_FREE_CTRL 0x034 +#define BMU_FREE_ERR_ADDR 0x038 +#define BMU_CURR_BUF_CNT 0x03c +#define BMU_MCAST_CNT 0x040 +#define BMU_MCAST_ALLOC_CTRL 0x044 +#define BMU_REM_BUF_CNT 0x048 +#define BMU_LOW_WATERMARK 0x050 +#define BMU_HIGH_WATERMARK 0x054 +#define BMU_INT_MEM_ACCESS 0x100 + +struct BMU_CFG { + unsigned long baseaddr; + u32 count; + u32 size; + u32 low_watermark; + u32 high_watermark; +}; + +#define BMU1_BUF_SIZE LMEM_BUF_SIZE_LN2 +#define BMU2_BUF_SIZE DDR_BUF_SIZE_LN2 + +#define BMU2_MCAST_ALLOC_CTRL (BMU2_BASE_ADDR + BMU_MCAST_ALLOC_CTRL) + +#endif /* _BMU_H_ */ diff --git a/drivers/net/ppfe/base/cbus/class_csr.h b/drivers/net/ppfe/base/cbus/class_csr.h new file mode 100644 index 000000000..70af01a27 --- /dev/null +++ b/drivers/net/ppfe/base/cbus/class_csr.h @@ -0,0 +1,277 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _CLASS_CSR_H_ +#define _CLASS_CSR_H_ + +#include + +/* @file class_csr.h. + * class_csr - block containing all the classifier control and status register. + * Mapped on CBUS and accessible from all PE's and ARM. + */ +#define CLASS_VERSION (CLASS_CSR_BASE_ADDR + 0x000) +#define CLASS_TX_CTRL (CLASS_CSR_BASE_ADDR + 0x004) +#define CLASS_INQ_PKTPTR (CLASS_CSR_BASE_ADDR + 0x010) + +/* (ddr_hdr_size[24:16], lmem_hdr_size[5:0]) */ +#define CLASS_HDR_SIZE (CLASS_CSR_BASE_ADDR + 0x014) + +/* LMEM header size for the Classifier block.\ Data in the LMEM + * is written from this offset. + */ +#define CLASS_HDR_SIZE_LMEM(off) ((off) & 0x3f) + +/* DDR header size for the Classifier block.\ Data in the DDR + * is written from this offset. + */ +#define CLASS_HDR_SIZE_DDR(off) (((off) & 0x1ff) << 16) + +#define CLASS_PE0_QB_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x020) + +/* DMEM address of first [15:0] and second [31:16] buffers on QB side. */ +#define CLASS_PE0_QB_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x024) + +/* DMEM address of third [15:0] and fourth [31:16] buffers on QB side. */ +#define CLASS_PE0_RO_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x060) + +/* DMEM address of first [15:0] and second [31:16] buffers on RO side. */ +#define CLASS_PE0_RO_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x064) + +/* DMEM address of third [15:0] and fourth [31:16] buffers on RO side. */ + +/* @name Class PE memory access. Allows external PE's and HOST to + * read/write PMEM/DMEM memory ranges for each classifier PE. + */ +/* {sr_pe_mem_cmd[31], csr_pe_mem_wren[27:24], csr_pe_mem_addr[23:0]}, + * See \ref XXX_MEM_ACCESS_ADDR for details. + */ +#define CLASS_MEM_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x100) + +/* Internal Memory Access Write Data [31:0] */ +#define CLASS_MEM_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x104) + +/* Internal Memory Access Read Data [31:0] */ +#define CLASS_MEM_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x108) +#define CLASS_TM_INQ_ADDR (CLASS_CSR_BASE_ADDR + 0x114) +#define CLASS_PE_STATUS (CLASS_CSR_BASE_ADDR + 0x118) + +#define CLASS_PHY1_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x11c) +#define CLASS_PHY1_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x120) +#define CLASS_PHY1_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x124) +#define CLASS_PHY1_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x128) +#define CLASS_PHY1_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x12c) +#define CLASS_PHY1_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x130) +#define CLASS_PHY1_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x134) +#define CLASS_PHY1_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x138) +#define CLASS_PHY1_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x13c) +#define CLASS_PHY1_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x140) +#define CLASS_PHY2_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x144) +#define CLASS_PHY2_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x148) +#define CLASS_PHY2_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x14c) +#define CLASS_PHY2_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x150) +#define CLASS_PHY2_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x154) +#define CLASS_PHY2_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x158) +#define CLASS_PHY2_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x15c) +#define CLASS_PHY2_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x160) +#define CLASS_PHY2_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x164) +#define CLASS_PHY2_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x168) +#define CLASS_PHY3_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x16c) +#define CLASS_PHY3_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x170) +#define CLASS_PHY3_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x174) +#define CLASS_PHY3_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x178) +#define CLASS_PHY3_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x17c) +#define CLASS_PHY3_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x180) +#define CLASS_PHY3_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x184) +#define CLASS_PHY3_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x188) +#define CLASS_PHY3_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x18c) +#define CLASS_PHY3_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x190) +#define CLASS_PHY1_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x194) +#define CLASS_PHY1_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x198) +#define CLASS_PHY1_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x19c) +#define CLASS_PHY1_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a0) +#define CLASS_PHY2_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a4) +#define CLASS_PHY2_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a8) +#define CLASS_PHY2_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1ac) +#define CLASS_PHY2_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b0) +#define CLASS_PHY3_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b4) +#define CLASS_PHY3_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b8) +#define CLASS_PHY3_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1bc) +#define CLASS_PHY3_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c0) +#define CLASS_PHY4_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c4) +#define CLASS_PHY4_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c8) +#define CLASS_PHY4_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1cc) +#define CLASS_PHY4_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1d0) +#define CLASS_PHY4_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d4) +#define CLASS_PHY4_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d8) +#define CLASS_PHY4_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1dc) +#define CLASS_PHY4_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e0) +#define CLASS_PHY4_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x1e4) +#define CLASS_PHY4_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e8) +#define CLASS_PHY4_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x1ec) +#define CLASS_PHY4_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x1f0) +#define CLASS_PHY4_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f4) +#define CLASS_PHY4_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f8) + +#define CLASS_PE_SYS_CLK_RATIO (CLASS_CSR_BASE_ADDR + 0x200) +#define CLASS_AFULL_THRES (CLASS_CSR_BASE_ADDR + 0x204) +#define CLASS_GAP_BETWEEN_READS (CLASS_CSR_BASE_ADDR + 0x208) +#define CLASS_MAX_BUF_CNT (CLASS_CSR_BASE_ADDR + 0x20c) +#define CLASS_TSQ_FIFO_THRES (CLASS_CSR_BASE_ADDR + 0x210) +#define CLASS_TSQ_MAX_CNT (CLASS_CSR_BASE_ADDR + 0x214) +#define CLASS_IRAM_DATA_0 (CLASS_CSR_BASE_ADDR + 0x218) +#define CLASS_IRAM_DATA_1 (CLASS_CSR_BASE_ADDR + 0x21c) +#define CLASS_IRAM_DATA_2 (CLASS_CSR_BASE_ADDR + 0x220) +#define CLASS_IRAM_DATA_3 (CLASS_CSR_BASE_ADDR + 0x224) + +#define CLASS_BUS_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x228) + +#define CLASS_BUS_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x22c) +#define CLASS_BUS_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x230) + +/* (route_entry_size[9:0], route_hash_size[23:16] + * (this is actually ln2(size))) + */ +#define CLASS_ROUTE_HASH_ENTRY_SIZE (CLASS_CSR_BASE_ADDR + 0x234) + +#define CLASS_ROUTE_ENTRY_SIZE(size) ((size) & 0x1ff) +#define CLASS_ROUTE_HASH_SIZE(hash_bits) (((hash_bits) & 0xff) << 16) + +#define CLASS_ROUTE_TABLE_BASE (CLASS_CSR_BASE_ADDR + 0x238) + +#define CLASS_ROUTE_MULTI (CLASS_CSR_BASE_ADDR + 0x23c) +#define CLASS_SMEM_OFFSET (CLASS_CSR_BASE_ADDR + 0x240) +#define CLASS_LMEM_BUF_SIZE (CLASS_CSR_BASE_ADDR + 0x244) +#define CLASS_VLAN_ID (CLASS_CSR_BASE_ADDR + 0x248) +#define CLASS_BMU1_BUF_FREE (CLASS_CSR_BASE_ADDR + 0x24c) +#define CLASS_USE_TMU_INQ (CLASS_CSR_BASE_ADDR + 0x250) +#define CLASS_VLAN_ID1 (CLASS_CSR_BASE_ADDR + 0x254) + +#define CLASS_BUS_ACCESS_BASE (CLASS_CSR_BASE_ADDR + 0x258) +#define CLASS_BUS_ACCESS_BASE_MASK (0xFF000000) +/* bit 31:24 of PE peripheral address are stored in CLASS_BUS_ACCESS_BASE */ + +#define CLASS_HIF_PARSE (CLASS_CSR_BASE_ADDR + 0x25c) + +#define CLASS_HOST_PE0_GP (CLASS_CSR_BASE_ADDR + 0x260) +#define CLASS_PE0_GP (CLASS_CSR_BASE_ADDR + 0x264) +#define CLASS_HOST_PE1_GP (CLASS_CSR_BASE_ADDR + 0x268) +#define CLASS_PE1_GP (CLASS_CSR_BASE_ADDR + 0x26c) +#define CLASS_HOST_PE2_GP (CLASS_CSR_BASE_ADDR + 0x270) +#define CLASS_PE2_GP (CLASS_CSR_BASE_ADDR + 0x274) +#define CLASS_HOST_PE3_GP (CLASS_CSR_BASE_ADDR + 0x278) +#define CLASS_PE3_GP (CLASS_CSR_BASE_ADDR + 0x27c) +#define CLASS_HOST_PE4_GP (CLASS_CSR_BASE_ADDR + 0x280) +#define CLASS_PE4_GP (CLASS_CSR_BASE_ADDR + 0x284) +#define CLASS_HOST_PE5_GP (CLASS_CSR_BASE_ADDR + 0x288) +#define CLASS_PE5_GP (CLASS_CSR_BASE_ADDR + 0x28c) + +#define CLASS_PE_INT_SRC (CLASS_CSR_BASE_ADDR + 0x290) +#define CLASS_PE_INT_ENABLE (CLASS_CSR_BASE_ADDR + 0x294) + +#define CLASS_TPID0_TPID1 (CLASS_CSR_BASE_ADDR + 0x298) +#define CLASS_TPID2 (CLASS_CSR_BASE_ADDR + 0x29c) + +#define CLASS_L4_CHKSUM_ADDR (CLASS_CSR_BASE_ADDR + 0x2a0) + +#define CLASS_PE0_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a4) +#define CLASS_PE1_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a8) +#define CLASS_PE2_DEBUG (CLASS_CSR_BASE_ADDR + 0x2ac) +#define CLASS_PE3_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b0) +#define CLASS_PE4_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b4) +#define CLASS_PE5_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b8) + +#define CLASS_STATE (CLASS_CSR_BASE_ADDR + 0x2bc) + +/* CLASS defines */ +#define CLASS_PBUF_SIZE 0x100 /* Fixed by hardware */ +#define CLASS_PBUF_HEADER_OFFSET 0x80 /* Can be configured */ + +/* Can be configured */ +#define CLASS_PBUF0_BASE_ADDR 0x000 +/* Can be configured */ +#define CLASS_PBUF1_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_SIZE) +/* Can be configured */ +#define CLASS_PBUF2_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_SIZE) +/* Can be configured */ +#define CLASS_PBUF3_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_SIZE) + +#define CLASS_PBUF0_HEADER_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + \ + CLASS_PBUF_HEADER_OFFSET) +#define CLASS_PBUF1_HEADER_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + \ + CLASS_PBUF_HEADER_OFFSET) +#define CLASS_PBUF2_HEADER_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + \ + CLASS_PBUF_HEADER_OFFSET) +#define CLASS_PBUF3_HEADER_BASE_ADDR (CLASS_PBUF3_BASE_ADDR + \ + CLASS_PBUF_HEADER_OFFSET) + +#define CLASS_PE0_RO_DM_ADDR0_VAL ((CLASS_PBUF1_BASE_ADDR << 16) | \ + CLASS_PBUF0_BASE_ADDR) +#define CLASS_PE0_RO_DM_ADDR1_VAL ((CLASS_PBUF3_BASE_ADDR << 16) | \ + CLASS_PBUF2_BASE_ADDR) + +#define CLASS_PE0_QB_DM_ADDR0_VAL ((CLASS_PBUF1_HEADER_BASE_ADDR << 16) |\ + CLASS_PBUF0_HEADER_BASE_ADDR) +#define CLASS_PE0_QB_DM_ADDR1_VAL ((CLASS_PBUF3_HEADER_BASE_ADDR << 16) |\ + CLASS_PBUF2_HEADER_BASE_ADDR) + +#define CLASS_ROUTE_SIZE 128 +#define CLASS_MAX_ROUTE_SIZE 256 +#define CLASS_ROUTE_HASH_BITS 20 +#define CLASS_ROUTE_HASH_MASK (BIT(CLASS_ROUTE_HASH_BITS) - 1) + +/* Can be configured */ +#define CLASS_ROUTE0_BASE_ADDR 0x400 +/* Can be configured */ +#define CLASS_ROUTE1_BASE_ADDR (CLASS_ROUTE0_BASE_ADDR + CLASS_ROUTE_SIZE) +/* Can be configured */ +#define CLASS_ROUTE2_BASE_ADDR (CLASS_ROUTE1_BASE_ADDR + CLASS_ROUTE_SIZE) +/* Can be configured */ +#define CLASS_ROUTE3_BASE_ADDR (CLASS_ROUTE2_BASE_ADDR + CLASS_ROUTE_SIZE) + +#define CLASS_SA_SIZE 128 +#define CLASS_IPSEC_SA0_BASE_ADDR 0x600 +/* not used */ +#define CLASS_IPSEC_SA1_BASE_ADDR (CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE) +/* not used */ +#define CLASS_IPSEC_SA2_BASE_ADDR (CLASS_IPSEC_SA1_BASE_ADDR + CLASS_SA_SIZE) +/* not used */ +#define CLASS_IPSEC_SA3_BASE_ADDR (CLASS_IPSEC_SA2_BASE_ADDR + CLASS_SA_SIZE) + +/* generic purpose free dmem buffer, last portion of 2K dmem pbuf */ +#define CLASS_GP_DMEM_BUF_SIZE (2048 - (CLASS_PBUF_SIZE * 4) - \ + (CLASS_ROUTE_SIZE * 4) - (CLASS_SA_SIZE)) +#define CLASS_GP_DMEM_BUF ((void *)(CLASS_IPSEC_SA0_BASE_ADDR + \ + CLASS_SA_SIZE)) + +#define TWO_LEVEL_ROUTE BIT(0) +#define PHYNO_IN_HASH BIT(1) +#define HW_ROUTE_FETCH BIT(3) +#define HW_BRIDGE_FETCH BIT(5) +#define IP_ALIGNED BIT(6) +#define ARC_HIT_CHECK_EN BIT(7) +#define CLASS_TOE BIT(11) +#define HASH_NORMAL (0 << 12) +#define HASH_CRC_PORT BIT(12) +#define HASH_CRC_IP (2 << 12) +#define HASH_CRC_PORT_IP (3 << 12) +#define QB2BUS_LE BIT(15) + +#define TCP_CHKSUM_DROP BIT(0) +#define UDP_CHKSUM_DROP BIT(1) +#define IPV4_CHKSUM_DROP BIT(9) + +/*CLASS_HIF_PARSE bits*/ +#define HIF_PKT_CLASS_EN BIT(0) +#define HIF_PKT_OFFSET(ofst) (((ofst) & 0xF) << 1) + +struct class_cfg { + u32 toe_mode; + unsigned long route_table_baseaddr; + u32 route_table_hash_bits; + u32 pe_sys_clk_ratio; + u32 resume; +}; + +#endif /* _CLASS_CSR_H_ */ diff --git a/drivers/net/ppfe/base/cbus/emac_mtip.h b/drivers/net/ppfe/base/cbus/emac_mtip.h new file mode 100644 index 000000000..ea54e2ee5 --- /dev/null +++ b/drivers/net/ppfe/base/cbus/emac_mtip.h @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _EMAC_H_ +#define _EMAC_H_ + +/* This file is for Ethernet MAC registers and offsets + */ + +#include + +#define EMAC_IEVENT_REG 0x004 +#define EMAC_IMASK_REG 0x008 +#define EMAC_R_DES_ACTIVE_REG 0x010 +#define EMAC_X_DES_ACTIVE_REG 0x014 +#define EMAC_ECNTRL_REG 0x024 +#define EMAC_MII_DATA_REG 0x040 +#define EMAC_MII_CTRL_REG 0x044 +#define EMAC_MIB_CTRL_STS_REG 0x064 +#define EMAC_RCNTRL_REG 0x084 +#define EMAC_TCNTRL_REG 0x0C4 +#define EMAC_PHY_ADDR_LOW 0x0E4 +#define EMAC_PHY_ADDR_HIGH 0x0E8 +#define EMAC_GAUR 0x120 +#define EMAC_GALR 0x124 +#define EMAC_TFWR_STR_FWD 0x144 +#define EMAC_RX_SECTION_FULL 0x190 +#define EMAC_RX_SECTION_EMPTY 0x194 +#define EMAC_TX_SECTION_EMPTY 0x1A0 +#define EMAC_TRUNC_FL 0x1B0 + +#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */ +#define RMON_T_PACKETS 0x204 /* RMON TX packet count */ +#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */ +#define RMON_T_MC_PKT 0x20c /* RMON TX multicast pkts */ +#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */ +#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */ +#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */ +#define RMON_T_FRAG 0x21c /* RMON TX pkts < 64 bytes, bad CRC */ +#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */ +#define RMON_T_COL 0x224 /* RMON TX collision count */ +#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */ +#define RMON_T_P65TO127 0x22c /* RMON TX 65 to 127 byte pkts */ +#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */ +#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */ +#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */ +#define RMON_T_P1024TO2047 0x23c /* RMON TX 1024 to 2047 byte pkts */ +#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */ +#define RMON_T_OCTETS 0x244 /* RMON TX octets */ +#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */ +#define IEEE_T_FRAME_OK 0x24c /* Frames tx'd OK */ +#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */ +#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */ +#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */ +#define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */ +#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */ +#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */ +#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */ +#define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */ +#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */ +#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */ +#define RMON_R_PACKETS 0x284 /* RMON RX packet count */ +#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */ +#define RMON_R_MC_PKT 0x28c /* RMON RX multicast pkts */ +#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */ +#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */ +#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */ +#define RMON_R_FRAG 0x29c /* RMON RX pkts < 64 bytes, bad CRC */ +#define RMON_R_JAB 0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */ +#define RMON_R_RESVD_O 0x2a4 /* Reserved */ +#define RMON_R_P64 0x2a8 /* RMON RX 64 byte pkts */ +#define RMON_R_P65TO127 0x2ac /* RMON RX 65 to 127 byte pkts */ +#define RMON_R_P128TO255 0x2b0 /* RMON RX 128 to 255 byte pkts */ +#define RMON_R_P256TO511 0x2b4 /* RMON RX 256 to 511 byte pkts */ +#define RMON_R_P512TO1023 0x2b8 /* RMON RX 512 to 1023 byte pkts */ +#define RMON_R_P1024TO2047 0x2bc /* RMON RX 1024 to 2047 byte pkts */ +#define RMON_R_P_GTE2048 0x2c0 /* RMON RX pkts > 2048 bytes */ +#define RMON_R_OCTETS 0x2c4 /* RMON RX octets */ +#define IEEE_R_DROP 0x2c8 /* Count frames not counted correctly */ +#define IEEE_R_FRAME_OK 0x2cc /* Frames rx'd OK */ +#define IEEE_R_CRC 0x2d0 /* Frames rx'd with CRC err */ +#define IEEE_R_ALIGN 0x2d4 /* Frames rx'd with alignment err */ +#define IEEE_R_MACERR 0x2d8 /* Receive FIFO overflow count */ +#define IEEE_R_FDXFC 0x2dc /* Flow control pause frames rx'd */ +#define IEEE_R_OCTETS_OK 0x2e0 /* Octet cnt for frames rx'd w/o err */ + +#define EMAC_SMAC_0_0 0x500 /*Supplemental MAC Address 0 (RW).*/ +#define EMAC_SMAC_0_1 0x504 /*Supplemental MAC Address 0 (RW).*/ + +/* GEMAC definitions and settings */ + +#define EMAC_PORT_0 0 +#define EMAC_PORT_1 1 + +/* GEMAC Bit definitions */ +#define EMAC_IEVENT_HBERR 0x80000000 +#define EMAC_IEVENT_BABR 0x40000000 +#define EMAC_IEVENT_BABT 0x20000000 +#define EMAC_IEVENT_GRA 0x10000000 +#define EMAC_IEVENT_TXF 0x08000000 +#define EMAC_IEVENT_TXB 0x04000000 +#define EMAC_IEVENT_RXF 0x02000000 +#define EMAC_IEVENT_RXB 0x01000000 +#define EMAC_IEVENT_MII 0x00800000 +#define EMAC_IEVENT_EBERR 0x00400000 +#define EMAC_IEVENT_LC 0x00200000 +#define EMAC_IEVENT_RL 0x00100000 +#define EMAC_IEVENT_UN 0x00080000 + +#define EMAC_IMASK_HBERR 0x80000000 +#define EMAC_IMASK_BABR 0x40000000 +#define EMAC_IMASKT_BABT 0x20000000 +#define EMAC_IMASK_GRA 0x10000000 +#define EMAC_IMASKT_TXF 0x08000000 +#define EMAC_IMASK_TXB 0x04000000 +#define EMAC_IMASKT_RXF 0x02000000 +#define EMAC_IMASK_RXB 0x01000000 +#define EMAC_IMASK_MII 0x00800000 +#define EMAC_IMASK_EBERR 0x00400000 +#define EMAC_IMASK_LC 0x00200000 +#define EMAC_IMASKT_RL 0x00100000 +#define EMAC_IMASK_UN 0x00080000 + +#define EMAC_RCNTRL_MAX_FL_SHIFT 16 +#define EMAC_RCNTRL_LOOP 0x00000001 +#define EMAC_RCNTRL_DRT 0x00000002 +#define EMAC_RCNTRL_MII_MODE 0x00000004 +#define EMAC_RCNTRL_PROM 0x00000008 +#define EMAC_RCNTRL_BC_REJ 0x00000010 +#define EMAC_RCNTRL_FCE 0x00000020 +#define EMAC_RCNTRL_RGMII 0x00000040 +#define EMAC_RCNTRL_SGMII 0x00000080 +#define EMAC_RCNTRL_RMII 0x00000100 +#define EMAC_RCNTRL_RMII_10T 0x00000200 +#define EMAC_RCNTRL_CRC_FWD 0x00004000 + +#define EMAC_TCNTRL_GTS 0x00000001 +#define EMAC_TCNTRL_HBC 0x00000002 +#define EMAC_TCNTRL_FDEN 0x00000004 +#define EMAC_TCNTRL_TFC_PAUSE 0x00000008 +#define EMAC_TCNTRL_RFC_PAUSE 0x00000010 + +#define EMAC_ECNTRL_RESET 0x00000001 /* reset the EMAC */ +#define EMAC_ECNTRL_ETHER_EN 0x00000002 /* enable the EMAC */ +#define EMAC_ECNTRL_MAGIC_ENA 0x00000004 +#define EMAC_ECNTRL_SLEEP 0x00000008 +#define EMAC_ECNTRL_SPEED 0x00000020 +#define EMAC_ECNTRL_DBSWAP 0x00000100 + +#define EMAC_X_WMRK_STRFWD 0x00000100 + +#define EMAC_X_DES_ACTIVE_TDAR 0x01000000 +#define EMAC_R_DES_ACTIVE_RDAR 0x01000000 + +#define EMAC_RX_SECTION_EMPTY_V 0x00010006 +/* + * The possible operating speeds of the MAC, currently supporting 10, 100 and + * 1000Mb modes. + */ +enum mac_speed {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS}; + +/* MII-related definitios */ +#define EMAC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ +#define EMAC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ +#define EMAC_MII_DATA_OP_CL45_RD 0x30000000 /* Perform a read operation */ +#define EMAC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ +#define EMAC_MII_DATA_OP_CL45_WR 0x10000000 /* Perform a write operation */ +#define EMAC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ +#define EMAC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ +#define EMAC_MII_DATA_TA 0x00020000 /* Turnaround */ +#define EMAC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ + +#define EMAC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ +#define EMAC_MII_DATA_RA_MASK 0x1F /* MII Register address mask */ +#define EMAC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ +#define EMAC_MII_DATA_PA_MASK 0x1F /* MII PHY address mask */ + +#define EMAC_MII_DATA_RA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \ + EMAC_MII_DATA_RA_SHIFT) +#define EMAC_MII_DATA_PA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \ + EMAC_MII_DATA_PA_SHIFT) +#define EMAC_MII_DATA(v) ((v) & 0xffff) + +#define EMAC_MII_SPEED_SHIFT 1 +#define EMAC_HOLDTIME_SHIFT 8 +#define EMAC_HOLDTIME_MASK 0x7 +#define EMAC_HOLDTIME(v) (((v) & EMAC_HOLDTIME_MASK) << \ + EMAC_HOLDTIME_SHIFT) + +/* + * The Address organisation for the MAC device. All addresses are split into + * two 32-bit register fields. The first one (bottom) is the lower 32-bits of + * the address and the other field are the high order bits - this may be 16-bits + * in the case of MAC addresses, or 32-bits for the hash address. + * In terms of memory storage, the first item (bottom) is assumed to be at a + * lower address location than 'top'. i.e. top should be at address location of + * 'bottom' + 4 bytes. + */ +struct pfe_mac_addr { + u32 bottom; /* Lower 32-bits of address. */ + u32 top; /* Upper 32-bits of address. */ +}; + +/* + * The following is the organisation of the address filters section of the MAC + * registers. The Cadence MAC contains four possible specific address match + * addresses, if an incoming frame corresponds to any one of these four + * addresses then the frame will be copied to memory. + * It is not necessary for all four of the address match registers to be + * programmed, this is application dependent. + */ +struct spec_addr { + struct pfe_mac_addr one; /* Specific address register 1. */ + struct pfe_mac_addr two; /* Specific address register 2. */ + struct pfe_mac_addr three; /* Specific address register 3. */ + struct pfe_mac_addr four; /* Specific address register 4. */ +}; + +struct gemac_cfg { + u32 mode; + u32 speed; + u32 duplex; +}; + +/* EMAC Hash size */ +#define EMAC_HASH_REG_BITS 64 + +#define EMAC_SPEC_ADDR_MAX 4 + +#endif /* _EMAC_H_ */ diff --git a/drivers/net/ppfe/base/cbus/gpi.h b/drivers/net/ppfe/base/cbus/gpi.h new file mode 100644 index 000000000..60d834323 --- /dev/null +++ b/drivers/net/ppfe/base/cbus/gpi.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _GPI_H_ +#define _GPI_H_ + +/* Generic Packet Interface:The generic packet interface block interfaces + * to block like ethernet, Host interfac and covert data into WSP internal + * structures + */ + +#define GPI_VERSION 0x00 +#define GPI_CTRL 0x04 +#define GPI_RX_CONFIG 0x08 +#define GPI_HDR_SIZE 0x0c +#define GPI_BUF_SIZE 0x10 +#define GPI_LMEM_ALLOC_ADDR 0x14 +#define GPI_LMEM_FREE_ADDR 0x18 +#define GPI_DDR_ALLOC_ADDR 0x1c +#define GPI_DDR_FREE_ADDR 0x20 +#define GPI_CLASS_ADDR 0x24 +#define GPI_DRX_FIFO 0x28 +#define GPI_TRX_FIFO 0x2c +#define GPI_INQ_PKTPTR 0x30 +#define GPI_DDR_DATA_OFFSET 0x34 +#define GPI_LMEM_DATA_OFFSET 0x38 +#define GPI_TMLF_TX 0x4c +#define GPI_DTX_ASEQ 0x50 +#define GPI_FIFO_STATUS 0x54 +#define GPI_FIFO_DEBUG 0x58 +#define GPI_TX_PAUSE_TIME 0x5c +#define GPI_LMEM_SEC_BUF_DATA_OFFSET 0x60 +#define GPI_DDR_SEC_BUF_DATA_OFFSET 0x64 +#define GPI_TOE_CHKSUM_EN 0x68 +#define GPI_OVERRUN_DROPCNT 0x6c +#define GPI_CSR_MTIP_PAUSE_REG 0x74 +#define GPI_CSR_MTIP_PAUSE_QUANTUM 0x78 +#define GPI_CSR_RX_CNT 0x7c +#define GPI_CSR_TX_CNT 0x80 +#define GPI_CSR_DEBUG1 0x84 +#define GPI_CSR_DEBUG2 0x88 + +struct gpi_cfg { + u32 lmem_rtry_cnt; + u32 tmlf_txthres; + u32 aseq_len; + u32 mtip_pause_reg; +}; + +/* GPI commons defines */ +#define GPI_LMEM_BUF_EN 0x1 +#define GPI_DDR_BUF_EN 0x1 + +/* EGPI 1 defines */ +#define EGPI1_LMEM_RTRY_CNT 0x40 +#define EGPI1_TMLF_TXTHRES 0xBC +#define EGPI1_ASEQ_LEN 0x50 + +/* EGPI 2 defines */ +#define EGPI2_LMEM_RTRY_CNT 0x40 +#define EGPI2_TMLF_TXTHRES 0xBC +#define EGPI2_ASEQ_LEN 0x40 + +/* EGPI 3 defines */ +#define EGPI3_LMEM_RTRY_CNT 0x40 +#define EGPI3_TMLF_TXTHRES 0xBC +#define EGPI3_ASEQ_LEN 0x40 + +/* HGPI defines */ +#define HGPI_LMEM_RTRY_CNT 0x40 +#define HGPI_TMLF_TXTHRES 0xBC +#define HGPI_ASEQ_LEN 0x40 + +#define EGPI_PAUSE_TIME 0x000007D0 +#define EGPI_PAUSE_ENABLE 0x40000000 +#endif /* _GPI_H_ */ diff --git a/drivers/net/ppfe/base/cbus/hif.h b/drivers/net/ppfe/base/cbus/hif.h new file mode 100644 index 000000000..bffd3d923 --- /dev/null +++ b/drivers/net/ppfe/base/cbus/hif.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _HIF_H_ +#define _HIF_H_ + +/* @file hif.h. + * hif - PFE hif block control and status register. + * Mapped on CBUS and accessible from all PE's and ARM. + */ +#define HIF_VERSION (HIF_BASE_ADDR + 0x00) +#define HIF_TX_CTRL (HIF_BASE_ADDR + 0x04) +#define HIF_TX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x08) +#define HIF_TX_ALLOC (HIF_BASE_ADDR + 0x0c) +#define HIF_TX_BDP_ADDR (HIF_BASE_ADDR + 0x10) +#define HIF_TX_STATUS (HIF_BASE_ADDR + 0x14) +#define HIF_RX_CTRL (HIF_BASE_ADDR + 0x20) +#define HIF_RX_BDP_ADDR (HIF_BASE_ADDR + 0x24) +#define HIF_RX_STATUS (HIF_BASE_ADDR + 0x30) +#define HIF_INT_SRC (HIF_BASE_ADDR + 0x34) +#define HIF_INT_ENABLE (HIF_BASE_ADDR + 0x38) +#define HIF_POLL_CTRL (HIF_BASE_ADDR + 0x3c) +#define HIF_RX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x40) +#define HIF_RX_ALLOC (HIF_BASE_ADDR + 0x44) +#define HIF_TX_DMA_STATUS (HIF_BASE_ADDR + 0x48) +#define HIF_RX_DMA_STATUS (HIF_BASE_ADDR + 0x4c) +#define HIF_INT_COAL (HIF_BASE_ADDR + 0x50) + +/* HIF_INT_SRC/ HIF_INT_ENABLE control bits */ +#define HIF_INT BIT(0) +#define HIF_RXBD_INT BIT(1) +#define HIF_RXPKT_INT BIT(2) +#define HIF_TXBD_INT BIT(3) +#define HIF_TXPKT_INT BIT(4) + +/* HIF_TX_CTRL bits */ +#define HIF_CTRL_DMA_EN BIT(0) +#define HIF_CTRL_BDP_POLL_CTRL_EN BIT(1) +#define HIF_CTRL_BDP_CH_START_WSTB BIT(2) + +/* HIF_RX_STATUS bits */ +#define BDP_CSR_RX_DMA_ACTV BIT(16) + +/* HIF_INT_ENABLE bits */ +#define HIF_INT_EN BIT(0) +#define HIF_RXBD_INT_EN BIT(1) +#define HIF_RXPKT_INT_EN BIT(2) +#define HIF_TXBD_INT_EN BIT(3) +#define HIF_TXPKT_INT_EN BIT(4) + +/* HIF_POLL_CTRL bits*/ +#define HIF_RX_POLL_CTRL_CYCLE 0x0400 +#define HIF_TX_POLL_CTRL_CYCLE 0x0400 + +/* HIF_INT_COAL bits*/ +#define HIF_INT_COAL_ENABLE BIT(31) + +/* Buffer descriptor control bits */ +#define BD_CTRL_BUFLEN_MASK 0x3fff +#define BD_BUF_LEN(x) ((x) & BD_CTRL_BUFLEN_MASK) +#define BD_CTRL_CBD_INT_EN BIT(16) +#define BD_CTRL_PKT_INT_EN BIT(17) +#define BD_CTRL_LIFM BIT(18) +#define BD_CTRL_LAST_BD BIT(19) +#define BD_CTRL_DIR BIT(20) +#define BD_CTRL_LMEM_CPY BIT(21) /* Valid only for HIF_NOCPY */ +#define BD_CTRL_PKT_XFER BIT(24) +#define BD_CTRL_DESC_EN BIT(31) +#define BD_CTRL_PARSE_DISABLE BIT(25) +#define BD_CTRL_BRFETCH_DISABLE BIT(26) +#define BD_CTRL_RTFETCH_DISABLE BIT(27) + +/* Buffer descriptor status bits*/ +#define BD_STATUS_CONN_ID(x) ((x) & 0xffff) +#define BD_STATUS_DIR_PROC_ID BIT(16) +#define BD_STATUS_CONN_ID_EN BIT(17) +#define BD_STATUS_PE2PROC_ID(x) (((x) & 7) << 18) +#define BD_STATUS_LE_DATA BIT(21) +#define BD_STATUS_CHKSUM_EN BIT(22) + +/* HIF Buffer descriptor status bits */ +#define DIR_PROC_ID BIT(16) +#define PROC_ID(id) ((id) << 18) + +#endif /* _HIF_H_ */ diff --git a/drivers/net/ppfe/base/cbus/hif_nocpy.h b/drivers/net/ppfe/base/cbus/hif_nocpy.h new file mode 100644 index 000000000..8c627b1c7 --- /dev/null +++ b/drivers/net/ppfe/base/cbus/hif_nocpy.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _HIF_NOCPY_H_ +#define _HIF_NOCPY_H_ + +#define HIF_NOCPY_VERSION (HIF_NOCPY_BASE_ADDR + 0x00) +#define HIF_NOCPY_TX_CTRL (HIF_NOCPY_BASE_ADDR + 0x04) +#define HIF_NOCPY_TX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x08) +#define HIF_NOCPY_TX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x0c) +#define HIF_NOCPY_TX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x10) +#define HIF_NOCPY_TX_STATUS (HIF_NOCPY_BASE_ADDR + 0x14) +#define HIF_NOCPY_RX_CTRL (HIF_NOCPY_BASE_ADDR + 0x20) +#define HIF_NOCPY_RX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x24) +#define HIF_NOCPY_RX_STATUS (HIF_NOCPY_BASE_ADDR + 0x30) +#define HIF_NOCPY_INT_SRC (HIF_NOCPY_BASE_ADDR + 0x34) +#define HIF_NOCPY_INT_ENABLE (HIF_NOCPY_BASE_ADDR + 0x38) +#define HIF_NOCPY_POLL_CTRL (HIF_NOCPY_BASE_ADDR + 0x3c) +#define HIF_NOCPY_RX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x40) +#define HIF_NOCPY_RX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x44) +#define HIF_NOCPY_TX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x48) +#define HIF_NOCPY_RX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x4c) +#define HIF_NOCPY_RX_INQ0_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x50) +#define HIF_NOCPY_RX_INQ1_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x54) +#define HIF_NOCPY_TX_PORT_NO (HIF_NOCPY_BASE_ADDR + 0x60) +#define HIF_NOCPY_LMEM_ALLOC_ADDR (HIF_NOCPY_BASE_ADDR + 0x64) +#define HIF_NOCPY_CLASS_ADDR (HIF_NOCPY_BASE_ADDR + 0x68) +#define HIF_NOCPY_TMU_PORT0_ADDR (HIF_NOCPY_BASE_ADDR + 0x70) +#define HIF_NOCPY_TMU_PORT1_ADDR (HIF_NOCPY_BASE_ADDR + 0x74) +#define HIF_NOCPY_TMU_PORT2_ADDR (HIF_NOCPY_BASE_ADDR + 0x7c) +#define HIF_NOCPY_TMU_PORT3_ADDR (HIF_NOCPY_BASE_ADDR + 0x80) +#define HIF_NOCPY_TMU_PORT4_ADDR (HIF_NOCPY_BASE_ADDR + 0x84) +#define HIF_NOCPY_INT_COAL (HIF_NOCPY_BASE_ADDR + 0x90) + +#endif /* _HIF_NOCPY_H_ */ diff --git a/drivers/net/ppfe/base/cbus/tmu_csr.h b/drivers/net/ppfe/base/cbus/tmu_csr.h new file mode 100644 index 000000000..2f4a62a76 --- /dev/null +++ b/drivers/net/ppfe/base/cbus/tmu_csr.h @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _TMU_CSR_H_ +#define _TMU_CSR_H_ + +#define TMU_VERSION (TMU_CSR_BASE_ADDR + 0x000) +#define TMU_INQ_WATERMARK (TMU_CSR_BASE_ADDR + 0x004) +#define TMU_PHY_INQ_PKTPTR (TMU_CSR_BASE_ADDR + 0x008) +#define TMU_PHY_INQ_PKTINFO (TMU_CSR_BASE_ADDR + 0x00c) +#define TMU_PHY_INQ_FIFO_CNT (TMU_CSR_BASE_ADDR + 0x010) +#define TMU_SYS_GENERIC_CONTROL (TMU_CSR_BASE_ADDR + 0x014) +#define TMU_SYS_GENERIC_STATUS (TMU_CSR_BASE_ADDR + 0x018) +#define TMU_SYS_GEN_CON0 (TMU_CSR_BASE_ADDR + 0x01c) +#define TMU_SYS_GEN_CON1 (TMU_CSR_BASE_ADDR + 0x020) +#define TMU_SYS_GEN_CON2 (TMU_CSR_BASE_ADDR + 0x024) +#define TMU_SYS_GEN_CON3 (TMU_CSR_BASE_ADDR + 0x028) +#define TMU_SYS_GEN_CON4 (TMU_CSR_BASE_ADDR + 0x02c) +#define TMU_TEQ_DISABLE_DROPCHK (TMU_CSR_BASE_ADDR + 0x030) +#define TMU_TEQ_CTRL (TMU_CSR_BASE_ADDR + 0x034) +#define TMU_TEQ_QCFG (TMU_CSR_BASE_ADDR + 0x038) +#define TMU_TEQ_DROP_STAT (TMU_CSR_BASE_ADDR + 0x03c) +#define TMU_TEQ_QAVG (TMU_CSR_BASE_ADDR + 0x040) +#define TMU_TEQ_WREG_PROB (TMU_CSR_BASE_ADDR + 0x044) +#define TMU_TEQ_TRANS_STAT (TMU_CSR_BASE_ADDR + 0x048) +#define TMU_TEQ_HW_PROB_CFG0 (TMU_CSR_BASE_ADDR + 0x04c) +#define TMU_TEQ_HW_PROB_CFG1 (TMU_CSR_BASE_ADDR + 0x050) +#define TMU_TEQ_HW_PROB_CFG2 (TMU_CSR_BASE_ADDR + 0x054) +#define TMU_TEQ_HW_PROB_CFG3 (TMU_CSR_BASE_ADDR + 0x058) +#define TMU_TEQ_HW_PROB_CFG4 (TMU_CSR_BASE_ADDR + 0x05c) +#define TMU_TEQ_HW_PROB_CFG5 (TMU_CSR_BASE_ADDR + 0x060) +#define TMU_TEQ_HW_PROB_CFG6 (TMU_CSR_BASE_ADDR + 0x064) +#define TMU_TEQ_HW_PROB_CFG7 (TMU_CSR_BASE_ADDR + 0x068) +#define TMU_TEQ_HW_PROB_CFG8 (TMU_CSR_BASE_ADDR + 0x06c) +#define TMU_TEQ_HW_PROB_CFG9 (TMU_CSR_BASE_ADDR + 0x070) +#define TMU_TEQ_HW_PROB_CFG10 (TMU_CSR_BASE_ADDR + 0x074) +#define TMU_TEQ_HW_PROB_CFG11 (TMU_CSR_BASE_ADDR + 0x078) +#define TMU_TEQ_HW_PROB_CFG12 (TMU_CSR_BASE_ADDR + 0x07c) +#define TMU_TEQ_HW_PROB_CFG13 (TMU_CSR_BASE_ADDR + 0x080) +#define TMU_TEQ_HW_PROB_CFG14 (TMU_CSR_BASE_ADDR + 0x084) +#define TMU_TEQ_HW_PROB_CFG15 (TMU_CSR_BASE_ADDR + 0x088) +#define TMU_TEQ_HW_PROB_CFG16 (TMU_CSR_BASE_ADDR + 0x08c) +#define TMU_TEQ_HW_PROB_CFG17 (TMU_CSR_BASE_ADDR + 0x090) +#define TMU_TEQ_HW_PROB_CFG18 (TMU_CSR_BASE_ADDR + 0x094) +#define TMU_TEQ_HW_PROB_CFG19 (TMU_CSR_BASE_ADDR + 0x098) +#define TMU_TEQ_HW_PROB_CFG20 (TMU_CSR_BASE_ADDR + 0x09c) +#define TMU_TEQ_HW_PROB_CFG21 (TMU_CSR_BASE_ADDR + 0x0a0) +#define TMU_TEQ_HW_PROB_CFG22 (TMU_CSR_BASE_ADDR + 0x0a4) +#define TMU_TEQ_HW_PROB_CFG23 (TMU_CSR_BASE_ADDR + 0x0a8) +#define TMU_TEQ_HW_PROB_CFG24 (TMU_CSR_BASE_ADDR + 0x0ac) +#define TMU_TEQ_HW_PROB_CFG25 (TMU_CSR_BASE_ADDR + 0x0b0) +#define TMU_TDQ_IIFG_CFG (TMU_CSR_BASE_ADDR + 0x0b4) +/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. + * This is a global Enable for all schedulers in PHY0 + */ +#define TMU_TDQ0_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x0b8) + +#define TMU_LLM_CTRL (TMU_CSR_BASE_ADDR + 0x0bc) +#define TMU_LLM_BASE_ADDR (TMU_CSR_BASE_ADDR + 0x0c0) +#define TMU_LLM_QUE_LEN (TMU_CSR_BASE_ADDR + 0x0c4) +#define TMU_LLM_QUE_HEADPTR (TMU_CSR_BASE_ADDR + 0x0c8) +#define TMU_LLM_QUE_TAILPTR (TMU_CSR_BASE_ADDR + 0x0cc) +#define TMU_LLM_QUE_DROPCNT (TMU_CSR_BASE_ADDR + 0x0d0) +#define TMU_INT_EN (TMU_CSR_BASE_ADDR + 0x0d4) +#define TMU_INT_SRC (TMU_CSR_BASE_ADDR + 0x0d8) +#define TMU_INQ_STAT (TMU_CSR_BASE_ADDR + 0x0dc) +#define TMU_CTRL (TMU_CSR_BASE_ADDR + 0x0e0) + +/* [31] Mem Access Command. 0 = Internal Memory Read, 1 = Internal memory + * Write [27:24] Byte Enables of the Internal memory access [23:0] Address of + * the internal memory. This address is used to access both the PM and DM of + * all the PE's + */ +#define TMU_MEM_ACCESS_ADDR (TMU_CSR_BASE_ADDR + 0x0e4) + +/* Internal Memory Access Write Data */ +#define TMU_MEM_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x0e8) +/* Internal Memory Access Read Data. The commands are blocked + * at the mem_access only + */ +#define TMU_MEM_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x0ec) + +/* [31:0] PHY0 in queue address (must be initialized with one of the + * xxx_INQ_PKTPTR cbus addresses) + */ +#define TMU_PHY0_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f0) +/* [31:0] PHY1 in queue address (must be initialized with one of the + * xxx_INQ_PKTPTR cbus addresses) + */ +#define TMU_PHY1_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f4) +/* [31:0] PHY2 in queue address (must be initialized with one of the + * xxx_INQ_PKTPTR cbus addresses) + */ +#define TMU_PHY2_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f8) +/* [31:0] PHY3 in queue address (must be initialized with one of the + * xxx_INQ_PKTPTR cbus addresses) + */ +#define TMU_PHY3_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0fc) +#define TMU_BMU_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x100) +#define TMU_TX_CTRL (TMU_CSR_BASE_ADDR + 0x104) + +#define TMU_BUS_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x108) +#define TMU_BUS_ACCESS (TMU_CSR_BASE_ADDR + 0x10c) +#define TMU_BUS_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x110) + +#define TMU_PE_SYS_CLK_RATIO (TMU_CSR_BASE_ADDR + 0x114) +#define TMU_PE_STATUS (TMU_CSR_BASE_ADDR + 0x118) +#define TMU_TEQ_MAX_THRESHOLD (TMU_CSR_BASE_ADDR + 0x11c) +/* [31:0] PHY4 in queue address (must be initialized with one of the + * xxx_INQ_PKTPTR cbus addresses) + */ +#define TMU_PHY4_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x134) +/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. + * This is a global Enable for all schedulers in PHY1 + */ +#define TMU_TDQ1_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x138) +/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. + * This is a global Enable for all schedulers in PHY2 + */ +#define TMU_TDQ2_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x13c) +/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. + * This is a global Enable for all schedulers in PHY3 + */ +#define TMU_TDQ3_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x140) +#define TMU_BMU_BUF_SIZE (TMU_CSR_BASE_ADDR + 0x144) +/* [31:0] PHY5 in queue address (must be initialized with one of the + * xxx_INQ_PKTPTR cbus addresses) + */ +#define TMU_PHY5_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x148) + +#define SW_RESET BIT(0) /* Global software reset */ +#define INQ_RESET BIT(2) +#define TEQ_RESET BIT(3) +#define TDQ_RESET BIT(4) +#define PE_RESET BIT(5) +#define MEM_INIT BIT(6) +#define MEM_INIT_DONE BIT(7) +#define LLM_INIT BIT(8) +#define LLM_INIT_DONE BIT(9) +#define ECC_MEM_INIT_DONE BIT(10) + +struct tmu_cfg { + u32 pe_sys_clk_ratio; + unsigned long llm_base_addr; + u32 llm_queue_len; +}; + +/* Not HW related for pfe_ctrl / pfe common defines */ +#define DEFAULT_MAX_QDEPTH 80 +#define DEFAULT_Q0_QDEPTH 511 /*We keep one large queue for host tx qos */ +#define DEFAULT_TMU3_QDEPTH 127 + +#endif /* _TMU_CSR_H_ */ diff --git a/drivers/net/ppfe/base/cbus/util_csr.h b/drivers/net/ppfe/base/cbus/util_csr.h new file mode 100644 index 000000000..8b37b6fac --- /dev/null +++ b/drivers/net/ppfe/base/cbus/util_csr.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _UTIL_CSR_H_ +#define _UTIL_CSR_H_ + +#define UTIL_VERSION (UTIL_CSR_BASE_ADDR + 0x000) +#define UTIL_TX_CTRL (UTIL_CSR_BASE_ADDR + 0x004) +#define UTIL_INQ_PKTPTR (UTIL_CSR_BASE_ADDR + 0x010) + +#define UTIL_HDR_SIZE (UTIL_CSR_BASE_ADDR + 0x014) + +#define UTIL_PE0_QB_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x020) +#define UTIL_PE0_QB_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x024) +#define UTIL_PE0_RO_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x060) +#define UTIL_PE0_RO_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x064) + +#define UTIL_MEM_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x100) +#define UTIL_MEM_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x104) +#define UTIL_MEM_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x108) + +#define UTIL_TM_INQ_ADDR (UTIL_CSR_BASE_ADDR + 0x114) +#define UTIL_PE_STATUS (UTIL_CSR_BASE_ADDR + 0x118) + +#define UTIL_PE_SYS_CLK_RATIO (UTIL_CSR_BASE_ADDR + 0x200) +#define UTIL_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x204) +#define UTIL_GAP_BETWEEN_READS (UTIL_CSR_BASE_ADDR + 0x208) +#define UTIL_MAX_BUF_CNT (UTIL_CSR_BASE_ADDR + 0x20c) +#define UTIL_TSQ_FIFO_THRES (UTIL_CSR_BASE_ADDR + 0x210) +#define UTIL_TSQ_MAX_CNT (UTIL_CSR_BASE_ADDR + 0x214) +#define UTIL_IRAM_DATA_0 (UTIL_CSR_BASE_ADDR + 0x218) +#define UTIL_IRAM_DATA_1 (UTIL_CSR_BASE_ADDR + 0x21c) +#define UTIL_IRAM_DATA_2 (UTIL_CSR_BASE_ADDR + 0x220) +#define UTIL_IRAM_DATA_3 (UTIL_CSR_BASE_ADDR + 0x224) + +#define UTIL_BUS_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x228) +#define UTIL_BUS_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x22c) +#define UTIL_BUS_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x230) + +#define UTIL_INQ_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x234) + +struct util_cfg { + u32 pe_sys_clk_ratio; +}; + +#endif /* _UTIL_CSR_H_ */ diff --git a/drivers/net/ppfe/base/pfe.h b/drivers/net/ppfe/base/pfe.h new file mode 100644 index 000000000..c1fe71a3a --- /dev/null +++ b/drivers/net/ppfe/base/pfe.h @@ -0,0 +1,339 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_H_ +#define _PFE_H_ + +#include "cbus.h" + +/* + * WARNING: non atomic version. + */ +static inline void +set_bit(unsigned long nr, void *addr) +{ + int *m = ((int *)addr) + (nr >> 5); + *m |= 1 << (nr & 31); +} + +static inline int +test_bit(int nr, const void *addr) +{ + return (1UL & (((const int *)addr)[nr >> 5] >> (nr & 31))) != 0UL; +} + +/* + * WARNING: non atomic version. + */ +static inline void +clear_bit(unsigned long nr, void *addr) +{ + int *m = ((int *)addr) + (nr >> 5); + *m &= ~(1 << (nr & 31)); +} + +/* + * WARNING: non atomic version. + */ +static inline int +test_and_clear_bit(unsigned long nr, void *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + int *m = ((int *)addr) + (nr >> 5); + int old = *m; + + *m = old & ~mask; + return (old & mask) != 0; +} + +/* + * WARNING: non atomic version. + */ +static inline int +test_and_set_bit(unsigned long nr, void *addr) +{ + unsigned long mask = 1 << (nr & 0x1f); + int *m = ((int *)addr) + (nr >> 5); + int old = *m; + + *m = old | mask; + return (old & mask) != 0; +} + +#ifndef BIT +#define BIT(nr) (1UL << (nr)) +#endif +#define CLASS_DMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) +/* + * Only valid for mem access register interface + */ +#define CLASS_IMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) +#define CLASS_DMEM_SIZE 0x00002000 +#define CLASS_IMEM_SIZE 0x00008000 + +#define TMU_DMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20)) +/* + * Only valid for mem access register interface + */ +#define TMU_IMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20)) +#define TMU_DMEM_SIZE 0x00000800 +#define TMU_IMEM_SIZE 0x00002000 + +#define UTIL_DMEM_BASE_ADDR 0x00000000 +#define UTIL_DMEM_SIZE 0x00002000 + +#define PE_LMEM_BASE_ADDR 0xc3010000 +#define PE_LMEM_SIZE 0x8000 +#define PE_LMEM_END (PE_LMEM_BASE_ADDR + PE_LMEM_SIZE) + +#define DMEM_BASE_ADDR 0x00000000 +#define DMEM_SIZE 0x2000 /* TMU has less... */ +#define DMEM_END (DMEM_BASE_ADDR + DMEM_SIZE) + +#define PMEM_BASE_ADDR 0x00010000 +#define PMEM_SIZE 0x8000 /* TMU has less... */ +#define PMEM_END (PMEM_BASE_ADDR + PMEM_SIZE) + +#define writel(v, p) ({*(volatile unsigned int *)(p) = (v); }) +#define readl(p) (*(const volatile unsigned int *)(p)) + +/* These check memory ranges from PE point of view/memory map */ +#define IS_DMEM(addr, len) \ + ({ typeof(addr) addr_ = (addr); \ + ((unsigned long)(addr_) >= DMEM_BASE_ADDR) && \ + (((unsigned long)(addr_) + (len)) <= DMEM_END); }) + +#define IS_PMEM(addr, len) \ + ({ typeof(addr) addr_ = (addr); \ + ((unsigned long)(addr_) >= PMEM_BASE_ADDR) && \ + (((unsigned long)(addr_) + (len)) <= PMEM_END); }) + +#define IS_PE_LMEM(addr, len) \ + ({ typeof(addr) addr_ = (addr); \ + ((unsigned long)(addr_) >= \ + PE_LMEM_BASE_ADDR) && \ + (((unsigned long)(addr_) + \ + (len)) <= PE_LMEM_END); }) + +#define IS_PFE_LMEM(addr, len) \ + ({ typeof(addr) addr_ = (addr); \ + ((unsigned long)(addr_) >= \ + CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR)) && \ + (((unsigned long)(addr_) + (len)) <= \ + CBUS_VIRT_TO_PFE(LMEM_END)); }) + +#define __IS_PHYS_DDR(addr, len) \ + ({ typeof(addr) addr_ = (addr); \ + ((unsigned long)(addr_) >= \ + DDR_PHYS_BASE_ADDR) && \ + (((unsigned long)(addr_) + (len)) <= \ + DDR_PHYS_END); }) + +#define IS_PHYS_DDR(addr, len) __IS_PHYS_DDR(DDR_PFE_TO_PHYS(addr), len) + +/* + * If using a run-time virtual address for the cbus base address use this code + */ +extern void *cbus_base_addr; +extern void *ddr_base_addr; +extern unsigned long ddr_phys_base_addr; +extern unsigned int ddr_size; + +#define CBUS_BASE_ADDR cbus_base_addr +#define DDR_PHYS_BASE_ADDR ddr_phys_base_addr +#define DDR_BASE_ADDR ddr_base_addr +#define DDR_SIZE ddr_size + +#define DDR_PHYS_END (DDR_PHYS_BASE_ADDR + DDR_SIZE) + +#define LS1012A_PFE_RESET_WA /* + * PFE doesn't have global reset and re-init + * should takecare few things to make PFE + * functional after reset + */ +#define PFE_CBUS_PHYS_BASE_ADDR 0xc0000000 /* CBUS physical base address + * as seen by PE's. + */ +/* CBUS physical base address as seen by PE's. */ +#define PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE 0xc0000000 + +#define DDR_PHYS_TO_PFE(p) (((unsigned long)(p)) & 0x7FFFFFFF) +#define DDR_PFE_TO_PHYS(p) (((unsigned long)(p)) | 0x80000000) +#define CBUS_PHYS_TO_PFE(p) (((p) - PFE_CBUS_PHYS_BASE_ADDR) + \ + PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE) +/* Translates to PFE address map */ + +#define DDR_PHYS_TO_VIRT(p) (((p) - DDR_PHYS_BASE_ADDR) + DDR_BASE_ADDR) +#define DDR_VIRT_TO_PHYS(v) (((v) - DDR_BASE_ADDR) + DDR_PHYS_BASE_ADDR) +#define DDR_VIRT_TO_PFE(p) (DDR_PHYS_TO_PFE(DDR_VIRT_TO_PHYS(p))) + +#define CBUS_VIRT_TO_PFE(v) (((v) - CBUS_BASE_ADDR) + \ + PFE_CBUS_PHYS_BASE_ADDR) +#define CBUS_PFE_TO_VIRT(p) (((unsigned long)(p) - \ + PFE_CBUS_PHYS_BASE_ADDR) + CBUS_BASE_ADDR) + +/* The below part of the code is used in QOS control driver from host */ +#define TMU_APB_BASE_ADDR 0xc1000000 /* TMU base address seen by + * pe's + */ + +enum { + CLASS0_ID = 0, + CLASS1_ID, + CLASS2_ID, + CLASS3_ID, + CLASS4_ID, + CLASS5_ID, + TMU0_ID, + TMU1_ID, + TMU2_ID, + TMU3_ID, +#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) + UTIL_ID, +#endif + MAX_PE +}; + +#define CLASS_MASK (BIT(CLASS0_ID) | BIT(CLASS1_ID) |\ + BIT(CLASS2_ID) | BIT(CLASS3_ID) |\ + BIT(CLASS4_ID) | BIT(CLASS5_ID)) +#define CLASS_MAX_ID CLASS5_ID + +#define TMU_MASK (BIT(TMU0_ID) | BIT(TMU1_ID) |\ + BIT(TMU3_ID)) + +#define TMU_MAX_ID TMU3_ID + +#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) +#define UTIL_MASK BIT(UTIL_ID) +#endif + +struct pe_status { + u32 cpu_state; + u32 activity_counter; + u32 rx; + union { + u32 tx; + u32 tmu_qstatus; + }; + u32 drop; +#if defined(CFG_PE_DEBUG) + u32 debug_indicator; + u32 debug[16]; +#endif +} __rte_aligned(16); + +struct pe_sync_mailbox { + u32 stop; + u32 stopped; +}; + +/* Drop counter definitions */ + +#define CLASS_NUM_DROP_COUNTERS 13 +#define UTIL_NUM_DROP_COUNTERS 8 + +/* PE information. + * Structure containing PE's specific information. It is used to create + * generic C functions common to all PE's. + * Before using the library functions this structure needs to be initialized + * with the different registers virtual addresses + * (according to the ARM MMU mmaping). The default initialization supports a + * virtual == physical mapping. + */ +struct pe_info { + u32 dmem_base_addr; /* PE's dmem base address */ + u32 pmem_base_addr; /* PE's pmem base address */ + u32 pmem_size; /* PE's pmem size */ + + void *mem_access_wdata; /* PE's _MEM_ACCESS_WDATA register + * address + */ + void *mem_access_addr; /* PE's _MEM_ACCESS_ADDR register + * address + */ + void *mem_access_rdata; /* PE's _MEM_ACCESS_RDATA register + * address + */ +}; + +void pe_lmem_read(u32 *dst, u32 len, u32 offset); +void pe_lmem_write(u32 *src, u32 len, u32 offset); + +void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len); +void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len); + +u32 pe_pmem_read(int id, u32 addr, u8 size); + +void pe_dmem_write(int id, u32 val, u32 addr, u8 size); +u32 pe_dmem_read(int id, u32 addr, u8 size); +void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len); +void class_pe_lmem_memset(u32 dst, int val, unsigned int len); +void class_bus_write(u32 val, u32 addr, u8 size); +u32 class_bus_read(u32 addr, u8 size); + +#define class_bus_readl(addr) class_bus_read(addr, 4) +#define class_bus_readw(addr) class_bus_read(addr, 2) +#define class_bus_readb(addr) class_bus_read(addr, 1) + +#define class_bus_writel(val, addr) class_bus_write(val, addr, 4) +#define class_bus_writew(val, addr) class_bus_write(val, addr, 2) +#define class_bus_writeb(val, addr) class_bus_write(val, addr, 1) + +#define pe_dmem_readl(id, addr) pe_dmem_read(id, addr, 4) +#define pe_dmem_readw(id, addr) pe_dmem_read(id, addr, 2) +#define pe_dmem_readb(id, addr) pe_dmem_read(id, addr, 1) + +#define pe_dmem_writel(id, val, addr) pe_dmem_write(id, val, addr, 4) +#define pe_dmem_writew(id, val, addr) pe_dmem_write(id, val, addr, 2) +#define pe_dmem_writeb(id, val, addr) pe_dmem_write(id, val, addr, 1) + +/*int pe_load_elf_section(int id, const void *data, elf32_shdr *shdr); */ +//int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr, +// struct device *dev); + +void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, + unsigned int ddr_size); +void bmu_init(void *base, struct BMU_CFG *cfg); +void bmu_reset(void *base); +void bmu_enable(void *base); +void bmu_disable(void *base); +void bmu_set_config(void *base, struct BMU_CFG *cfg); + +/* + * An enumerated type for loopback values. This can be one of three values, no + * loopback -normal operation, local loopback with internal loopback module of + * MAC or PHY loopback which is through the external PHY. + */ +#ifndef __MAC_LOOP_ENUM__ +#define __MAC_LOOP_ENUM__ +enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL}; +#endif + +/* Get Chip Revision level + * + */ +static inline unsigned int CHIP_REVISION(void) +{ + /*For LS1012A return always 1 */ + return 1; +} + +/* Start HIF rx DMA + * + */ +static inline void hif_rx_dma_start(void) +{ + writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_RX_CTRL); +} + +/* Start HIF tx DMA + * + */ +static inline void hif_tx_dma_start(void) +{ + writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL); +} + +#endif /* _PFE_H_ */ From patchwork Tue Oct 1 11:02:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60317 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 73CEA1BE9A; Tue, 1 Oct 2019 13:17:39 +0200 (CEST) Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) by dpdk.org (Postfix) with ESMTP id EBBE31B994 for ; Tue, 1 Oct 2019 13:17:32 +0200 (CEST) Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id C4364200540; Tue, 1 Oct 2019 13:17:32 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 9686E2001C2; Tue, 1 Oct 2019 13:17:29 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 8D59E402C7; Tue, 1 Oct 2019 19:17:25 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh , Akhil Goyal Date: Tue, 1 Oct 2019 16:32:01 +0530 Message-Id: <20191001110209.6047-7-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 06/14] net/ppfe: add MAC and host interface initialisation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" HIF or host interface is responsible for transmit and receive packets between physical ethernet interfaces and HIF library defined logical interfaces. This patch initialise that host interface and MAC. Signed-off-by: Gagandeep Singh Signed-off-by: Akhil Goyal Acked-by: Nipun Gupta --- drivers/net/ppfe/Makefile | 10 + drivers/net/ppfe/base/pfe.h | 83 +++++ drivers/net/ppfe/meson.build | 12 +- drivers/net/ppfe/pfe_hal.c | 635 +++++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.c | 256 +++++++++++++ drivers/net/ppfe/pfe_hif.h | 106 ++++++ drivers/net/ppfe/pfe_hif_lib.c | 20 ++ drivers/net/ppfe/pfe_hif_lib.h | 162 +++++++++ drivers/net/ppfe/pfe_mod.h | 5 + drivers/net/ppfe/ppfe_ethdev.c | 153 +++++++- 10 files changed, 1439 insertions(+), 3 deletions(-) create mode 100644 drivers/net/ppfe/pfe_hal.c create mode 100644 drivers/net/ppfe/pfe_hif.c create mode 100644 drivers/net/ppfe/pfe_hif.h create mode 100644 drivers/net/ppfe/pfe_hif_lib.c create mode 100644 drivers/net/ppfe/pfe_hif_lib.h diff --git a/drivers/net/ppfe/Makefile b/drivers/net/ppfe/Makefile index b9e894ffd..0f1dba188 100644 --- a/drivers/net/ppfe/Makefile +++ b/drivers/net/ppfe/Makefile @@ -10,14 +10,24 @@ include $(RTE_SDK)/mk/rte.vars.mk LIB = librte_pmd_ppfe.a CFLAGS += -O3 $(WERROR_FLAGS) +CFLAGS += -Wno-pointer-arith CFLAGS += -I$(RTE_SDK)/drivers/bus/dpaa/include/ +CFLAGS += -I$(RTE_SDK)/drivers/net/ppfe/base/ CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax EXPORT_MAP := rte_pmd_ppfe_version.map LIBABIVER := 1 +# Driver uses below experimental APIs +# rte_mem_iova2virt +# rte_mem_virt2memseg +CFLAGS += -DALLOW_EXPERIMENTAL_API + # Interfaces with DPDK SRCS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += ppfe_ethdev.c +SRCS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += pfe_hal.c +SRCS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += pfe_hif_lib.c +SRCS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += pfe_hif.c LDLIBS += -lrte_bus_vdev LDLIBS += -lrte_bus_dpaa diff --git a/drivers/net/ppfe/base/pfe.h b/drivers/net/ppfe/base/pfe.h index c1fe71a3a..e59d3aa04 100644 --- a/drivers/net/ppfe/base/pfe.h +++ b/drivers/net/ppfe/base/pfe.h @@ -311,6 +311,70 @@ void bmu_set_config(void *base, struct BMU_CFG *cfg); enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL}; #endif +void gemac_init(void *base, void *config); +void gemac_disable_rx_checksum_offload(void *base); +void gemac_enable_rx_checksum_offload(void *base); +void gemac_set_mdc_div(void *base, int mdc_div); +void gemac_set_speed(void *base, enum mac_speed gem_speed); +void gemac_set_duplex(void *base, int duplex); +void gemac_set_mode(void *base, int mode); +void gemac_enable(void *base); +void gemac_tx_disable(void *base); +void gemac_tx_enable(void *base); +void gemac_disable(void *base); +void gemac_reset(void *base); +void gemac_set_address(void *base, struct spec_addr *addr); +struct spec_addr gemac_get_address(void *base); +void gemac_set_loop(void *base, enum mac_loop gem_loop); +void gemac_set_laddr1(void *base, struct pfe_mac_addr *address); +void gemac_set_laddr2(void *base, struct pfe_mac_addr *address); +void gemac_set_laddr3(void *base, struct pfe_mac_addr *address); +void gemac_set_laddr4(void *base, struct pfe_mac_addr *address); +void gemac_set_laddrN(void *base, struct pfe_mac_addr *address, + unsigned int entry_index); +void gemac_clear_laddr1(void *base); +void gemac_clear_laddr2(void *base); +void gemac_clear_laddr3(void *base); +void gemac_clear_laddr4(void *base); +void gemac_clear_laddrN(void *base, unsigned int entry_index); +struct pfe_mac_addr gemac_get_hash(void *base); +void gemac_set_hash(void *base, struct pfe_mac_addr *hash); +struct pfe_mac_addr gem_get_laddr1(void *base); +struct pfe_mac_addr gem_get_laddr2(void *base); +struct pfe_mac_addr gem_get_laddr3(void *base); +struct pfe_mac_addr gem_get_laddr4(void *base); +struct pfe_mac_addr gem_get_laddrN(void *base, unsigned int entry_index); +void gemac_set_config(void *base, struct gemac_cfg *cfg); +void gemac_allow_broadcast(void *base); +void gemac_no_broadcast(void *base); +void gemac_enable_1536_rx(void *base); +void gemac_disable_1536_rx(void *base); +int gemac_set_rx(void *base, int mtu); +void gemac_enable_rx_jmb(void *base); +void gemac_disable_rx_jmb(void *base); +void gemac_enable_stacked_vlan(void *base); +void gemac_disable_stacked_vlan(void *base); +void gemac_enable_pause_rx(void *base); +void gemac_disable_pause_rx(void *base); +void gemac_enable_pause_tx(void *base); +void gemac_disable_pause_tx(void *base); +void gemac_enable_copy_all(void *base); +void gemac_disable_copy_all(void *base); +void gemac_set_bus_width(void *base, int width); +void gemac_set_wol(void *base, u32 wol_conf); + +void gpi_init(void *base, struct gpi_cfg *cfg); +void gpi_reset(void *base); +void gpi_enable(void *base); +void gpi_disable(void *base); +void gpi_set_config(void *base, struct gpi_cfg *cfg); + +void hif_init(void); +void hif_tx_enable(void); +void hif_tx_disable(void); +void hif_rx_enable(void); +void hif_rx_disable(void); + /* Get Chip Revision level * */ @@ -336,4 +400,23 @@ static inline void hif_tx_dma_start(void) writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL); } + +static inline void *pfe_mem_ptov(phys_addr_t paddr) +{ + return rte_mem_iova2virt(paddr); +} + +static phys_addr_t pfe_mem_vtop(uint64_t vaddr) __attribute__((unused)); + +static inline phys_addr_t pfe_mem_vtop(uint64_t vaddr) +{ + const struct rte_memseg *memseg; + + memseg = rte_mem_virt2memseg((void *)(uintptr_t)vaddr, NULL); + if (memseg) + return memseg->phys_addr + RTE_PTR_DIFF(vaddr, memseg->addr); + + return (size_t)NULL; +} + #endif /* _PFE_H_ */ diff --git a/drivers/net/ppfe/meson.build b/drivers/net/ppfe/meson.build index 8ca2cb87d..5d8f4f2e9 100644 --- a/drivers/net/ppfe/meson.build +++ b/drivers/net/ppfe/meson.build @@ -6,6 +6,14 @@ if host_machine.system() != 'linux' endif deps += ['bus_dpaa'] -sources = files('ppfe_ethdev.c') +sources = files('ppfe_ethdev.c', + 'pfe_hal.c', + 'pfe_hif_lib.c', + 'pfe_hif.c') -includes += include_directories('../../bus/dpaa/include/') +# Driver uses below experimental APIs +# rte_mem_iova2virt +# rte_mem_virt2memseg +allow_experimental_apis = true + +includes += include_directories('base','../../bus/dpaa/include/') diff --git a/drivers/net/ppfe/pfe_hal.c b/drivers/net/ppfe/pfe_hal.c new file mode 100644 index 000000000..247634559 --- /dev/null +++ b/drivers/net/ppfe/pfe_hal.c @@ -0,0 +1,635 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include "pfe_logs.h" +#include "pfe_mod.h" + +#define PFE_MTU_RESET_MASK 0xC000FFFF +/* TODO update + * MAX MTU on VLAN support + * EMAC_TRUNC_FL value in gemac_set_config + * ERR print in set_rx + */ +#define MAX_MTU_ON_REV1 (1878 + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN) + +void *cbus_base_addr; +void *ddr_base_addr; +unsigned long ddr_phys_base_addr; +unsigned int ddr_size; +static struct pe_info pe[MAX_PE]; + +/* Initializes the PFE library. + * Must be called before using any of the library functions. + * + * @param[in] cbus_base CBUS virtual base address (as mapped in + * the host CPU address space) + * @param[in] ddr_base PFE DDR range virtual base address (as + * mapped in the host CPU address space) + * @param[in] ddr_phys_base PFE DDR range physical base address (as + * mapped in platform) + * @param[in] size PFE DDR range size (as defined by the host + * software) + */ +void +pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, + unsigned int size) +{ + cbus_base_addr = cbus_base; + ddr_base_addr = ddr_base; + ddr_phys_base_addr = ddr_phys_base; + ddr_size = size; + + pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0); + pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0); + pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE; + pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; + pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; + pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; + + pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1); + pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1); + pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE; + pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; + pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; + pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; + + pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2); + pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2); + pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE; + pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; + pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; + pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; + + pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3); + pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3); + pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE; + pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; + pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; + pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; + + pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4); + pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4); + pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE; + pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; + pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; + pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; + + pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5); + pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5); + pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE; + pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; + pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; + pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; + + pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0); + pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0); + pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE; + pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; + pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; + pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; + + pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1); + pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1); + pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE; + pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; + pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; + pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; + + pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3); + pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3); + pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE; + pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; + pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; + pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; + +#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) + pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR; + pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA; + pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR; + pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA; +#endif +} + +/**************************** MTIP GEMAC ***************************/ + +/* Enable Rx Checksum Engine. With this enabled, Frame with bad IP, + * TCP or UDP checksums are discarded + * + * @param[in] base GEMAC base address. + */ +void +gemac_enable_rx_checksum_offload(__rte_unused void *base) +{ + /*Do not find configuration to do this */ +} + +/* Disable Rx Checksum Engine. + * + * @param[in] base GEMAC base address. + */ +void +gemac_disable_rx_checksum_offload(__rte_unused void *base) +{ + /*Do not find configuration to do this */ +} + +/* GEMAC set speed. + * @param[in] base GEMAC base address + * @param[in] speed GEMAC speed (10, 100 or 1000 Mbps) + */ +void +gemac_set_speed(void *base, enum mac_speed gem_speed) +{ + u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED; + u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T; + + switch (gem_speed) { + case SPEED_10M: + rcr |= EMAC_RCNTRL_RMII_10T; + break; + + case SPEED_1000M: + ecr |= EMAC_ECNTRL_SPEED; + break; + + case SPEED_100M: + default: + /*It is in 100M mode */ + break; + } + writel(ecr, (base + EMAC_ECNTRL_REG)); + writel(rcr, (base + EMAC_RCNTRL_REG)); +} + +/* GEMAC set duplex. + * @param[in] base GEMAC base address + * @param[in] duplex GEMAC duplex mode (Full, Half) + */ +void +gemac_set_duplex(void *base, int duplex) +{ + if (duplex == DUPLEX_HALF) { + writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base + + EMAC_TCNTRL_REG); + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base + + EMAC_RCNTRL_REG)); + } else { + writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base + + EMAC_TCNTRL_REG); + writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base + + EMAC_RCNTRL_REG)); + } +} + +/* GEMAC set mode. + * @param[in] base GEMAC base address + * @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII) + */ +void +gemac_set_mode(void *base, __rte_unused int mode) +{ + u32 val = readl(base + EMAC_RCNTRL_REG); + + /*Remove loopbank*/ + val &= ~EMAC_RCNTRL_LOOP; + + /*Enable flow control and MII mode*/ + val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE | EMAC_RCNTRL_CRC_FWD); + + writel(val, base + EMAC_RCNTRL_REG); +} + +/* GEMAC enable function. + * @param[in] base GEMAC base address + */ +void +gemac_enable(void *base) +{ + writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base + + EMAC_ECNTRL_REG); +} + +/* GEMAC disable function. + * @param[in] base GEMAC base address + */ +void +gemac_disable(void *base) +{ + writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base + + EMAC_ECNTRL_REG); +} + +/* GEMAC TX disable function. + * @param[in] base GEMAC base address + */ +void +gemac_tx_disable(void *base) +{ + writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base + + EMAC_TCNTRL_REG); +} + +void +gemac_tx_enable(void *base) +{ + writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_GTS, base + + EMAC_TCNTRL_REG); +} + +/* Sets the hash register of the MAC. + * This register is used for matching unicast and multicast frames. + * + * @param[in] base GEMAC base address. + * @param[in] hash 64-bit hash to be configured. + */ +void +gemac_set_hash(void *base, struct pfe_mac_addr *hash) +{ + writel(hash->bottom, base + EMAC_GALR); + writel(hash->top, base + EMAC_GAUR); +} + +void +gemac_set_laddrN(void *base, struct pfe_mac_addr *address, + unsigned int entry_index) +{ + if (entry_index < 1 || entry_index > EMAC_SPEC_ADDR_MAX) + return; + + entry_index = entry_index - 1; + if (entry_index < 1) { + writel(htonl(address->bottom), base + EMAC_PHY_ADDR_LOW); + writel((htonl(address->top) | 0x8808), base + + EMAC_PHY_ADDR_HIGH); + } else { + writel(htonl(address->bottom), base + ((entry_index - 1) * 8) + + EMAC_SMAC_0_0); + writel((htonl(address->top) | 0x8808), base + ((entry_index - + 1) * 8) + EMAC_SMAC_0_1); + } +} + +void +gemac_clear_laddrN(void *base, unsigned int entry_index) +{ + if (entry_index < 1 || entry_index > EMAC_SPEC_ADDR_MAX) + return; + + entry_index = entry_index - 1; + if (entry_index < 1) { + writel(0, base + EMAC_PHY_ADDR_LOW); + writel(0, base + EMAC_PHY_ADDR_HIGH); + } else { + writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0); + writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1); + } +} + +/* Set the loopback mode of the MAC. This can be either no loopback for + * normal operation, local loopback through MAC internal loopback module or PHY + * loopback for external loopback through a PHY. This asserts the external + * loop pin. + * + * @param[in] base GEMAC base address. + * @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC + * Loopback, + * LB_EXT - PHY Loopback. + */ +void +gemac_set_loop(void *base, __rte_unused enum mac_loop gem_loop) +{ + pr_info("%s()\n", __func__); + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base + + EMAC_RCNTRL_REG)); +} + +/* GEMAC allow frames + * @param[in] base GEMAC base address + */ +void +gemac_enable_copy_all(void *base) +{ + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base + + EMAC_RCNTRL_REG)); +} + +/* GEMAC do not allow frames + * @param[in] base GEMAC base address + */ +void +gemac_disable_copy_all(void *base) +{ + writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base + + EMAC_RCNTRL_REG)); +} + +/* GEMAC allow broadcast function. + * @param[in] base GEMAC base address + */ +void +gemac_allow_broadcast(void *base) +{ + writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base + + EMAC_RCNTRL_REG); +} + +/* GEMAC no broadcast function. + * @param[in] base GEMAC base address + */ +void +gemac_no_broadcast(void *base) +{ + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base + + EMAC_RCNTRL_REG); +} + +/* GEMAC enable 1536 rx function. + * @param[in] base GEMAC base address + */ +void +gemac_enable_1536_rx(void *base) +{ + /* Set 1536 as Maximum frame length */ + writel((readl(base + EMAC_RCNTRL_REG) & PFE_MTU_RESET_MASK) + | (1536 << 16), + base + EMAC_RCNTRL_REG); +} + +/* GEMAC set Max rx function. + * @param[in] base GEMAC base address + */ +int +gemac_set_rx(void *base, int mtu) +{ + if (mtu < HIF_RX_PKT_MIN_SIZE || mtu > JUMBO_FRAME_SIZE) { + PFE_PMD_ERR("Invalid or not support MTU size"); + return -1; + } + + if (pfe_svr == SVR_LS1012A_REV1 && mtu > MAX_MTU_ON_REV1) { + PFE_PMD_ERR("Max supported MTU on Rev1 is %d", MAX_MTU_ON_REV1 - + (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN)); + return -1; + } + + writel((readl(base + EMAC_RCNTRL_REG) & PFE_MTU_RESET_MASK) + | (mtu << 16), + base + EMAC_RCNTRL_REG); + return 0; +} + +/* GEMAC enable jumbo function. + * @param[in] base GEMAC base address + */ +void +gemac_enable_rx_jmb(void *base) +{ + if (pfe_svr == SVR_LS1012A_REV1) { + PFE_PMD_ERR("Jumbo not supported on Rev1"); + return; + } + + writel((readl(base + EMAC_RCNTRL_REG) & PFE_MTU_RESET_MASK) | + (JUMBO_FRAME_SIZE << 16), base + EMAC_RCNTRL_REG); +} + +/* GEMAC enable stacked vlan function. + * @param[in] base GEMAC base address + */ +void +gemac_enable_stacked_vlan(__rte_unused void *base) +{ + /* MTIP doesn't support stacked vlan */ +} + +/* GEMAC enable pause rx function. + * @param[in] base GEMAC base address + */ +void +gemac_enable_pause_rx(void *base) +{ + writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE, + base + EMAC_RCNTRL_REG); +} + +/* GEMAC disable pause rx function. + * @param[in] base GEMAC base address + */ +void +gemac_disable_pause_rx(void *base) +{ + writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE, + base + EMAC_RCNTRL_REG); +} + +/* GEMAC enable pause tx function. + * @param[in] base GEMAC base address + */ +void +gemac_enable_pause_tx(void *base) +{ + writel(EMAC_RX_SECTION_EMPTY_V, base + EMAC_RX_SECTION_EMPTY); +} + +/* GEMAC disable pause tx function. + * @param[in] base GEMAC base address + */ +void +gemac_disable_pause_tx(void *base) +{ + writel(0x0, base + EMAC_RX_SECTION_EMPTY); +} + +/* GEMAC wol configuration + * @param[in] base GEMAC base address + * @param[in] wol_conf WoL register configuration + */ +void +gemac_set_wol(void *base, u32 wol_conf) +{ + u32 val = readl(base + EMAC_ECNTRL_REG); + + if (wol_conf) + val |= (EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP); + else + val &= ~(EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP); + writel(val, base + EMAC_ECNTRL_REG); +} + +/* Sets Gemac bus width to 64bit + * @param[in] base GEMAC base address + * @param[in] width gemac bus width to be set possible values are 32/64/128 + */ +void +gemac_set_bus_width(__rte_unused void *base, __rte_unused int width) +{ +} + +/* Sets Gemac configuration. + * @param[in] base GEMAC base address + * @param[in] cfg GEMAC configuration + */ +void +gemac_set_config(void *base, struct gemac_cfg *cfg) +{ + /*GEMAC config taken from VLSI */ + writel(0x00000004, base + EMAC_TFWR_STR_FWD); + writel(0x00000005, base + EMAC_RX_SECTION_FULL); + + if (pfe_svr == SVR_LS1012A_REV1) + writel(0x00000768, base + EMAC_TRUNC_FL); + else + writel(0x00003fff, base + EMAC_TRUNC_FL); + + writel(0x00000030, base + EMAC_TX_SECTION_EMPTY); + writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG); + + gemac_set_mode(base, cfg->mode); + + gemac_set_speed(base, cfg->speed); + + gemac_set_duplex(base, cfg->duplex); +} + +/**************************** GPI ***************************/ + +/* Initializes a GPI block. + * @param[in] base GPI base address + * @param[in] cfg GPI configuration + */ +void +gpi_init(void *base, struct gpi_cfg *cfg) +{ + gpi_reset(base); + + gpi_disable(base); + + gpi_set_config(base, cfg); +} + +/* Resets a GPI block. + * @param[in] base GPI base address + */ +void +gpi_reset(void *base) +{ + writel(CORE_SW_RESET, base + GPI_CTRL); +} + +/* Enables a GPI block. + * @param[in] base GPI base address + */ +void +gpi_enable(void *base) +{ + writel(CORE_ENABLE, base + GPI_CTRL); +} + +/* Disables a GPI block. + * @param[in] base GPI base address + */ +void +gpi_disable(void *base) +{ + writel(CORE_DISABLE, base + GPI_CTRL); +} + +/* Sets the configuration of a GPI block. + * @param[in] base GPI base address + * @param[in] cfg GPI configuration + */ +void +gpi_set_config(void *base, struct gpi_cfg *cfg) +{ + writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base + + GPI_LMEM_ALLOC_ADDR); + writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base + + GPI_LMEM_FREE_ADDR); + writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base + + GPI_DDR_ALLOC_ADDR); + writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base + + GPI_DDR_FREE_ADDR); + writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR); + writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET); + writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET); + writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET); + writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET); + writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE); + writel((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE); + + writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) | + GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG); + writel(cfg->tmlf_txthres, base + GPI_TMLF_TX); + writel(cfg->aseq_len, base + GPI_DTX_ASEQ); + writel(1, base + GPI_TOE_CHKSUM_EN); + + if (cfg->mtip_pause_reg) { + writel(cfg->mtip_pause_reg, base + GPI_CSR_MTIP_PAUSE_REG); + writel(EGPI_PAUSE_TIME, base + GPI_TX_PAUSE_TIME); + } +} + +/**************************** HIF ***************************/ +/* Initializes HIF copy block. + * + */ +void +hif_init(void) +{ + /*Initialize HIF registers*/ + writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE, + HIF_POLL_CTRL); +} + +/* Enable hif tx DMA and interrupt + * + */ +void +hif_tx_enable(void) +{ + writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL); + writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN), + HIF_INT_ENABLE); +} + +/* Disable hif tx DMA and interrupt + * + */ +void +hif_tx_disable(void) +{ + u32 hif_int; + + writel(0, HIF_TX_CTRL); + + hif_int = readl(HIF_INT_ENABLE); + hif_int &= HIF_TXPKT_INT_EN; + writel(hif_int, HIF_INT_ENABLE); +} + +/* Enable hif rx DMA and interrupt + * + */ +void +hif_rx_enable(void) +{ + hif_rx_dma_start(); + writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN), + HIF_INT_ENABLE); +} + +/* Disable hif rx DMA and interrupt + * + */ +void +hif_rx_disable(void) +{ + u32 hif_int; + + writel(0, HIF_RX_CTRL); + + hif_int = readl(HIF_INT_ENABLE); + hif_int &= HIF_RXPKT_INT_EN; + writel(hif_int, HIF_INT_ENABLE); +} diff --git a/drivers/net/ppfe/pfe_hif.c b/drivers/net/ppfe/pfe_hif.c new file mode 100644 index 000000000..3a861b420 --- /dev/null +++ b/drivers/net/ppfe/pfe_hif.c @@ -0,0 +1,256 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include "pfe_logs.h" +#include "pfe_mod.h" +#include +#include +#include + +static int +pfe_hif_alloc_descr(struct pfe_hif *hif) +{ + void *addr; + int err = 0; + + PMD_INIT_FUNC_TRACE(); + + addr = rte_zmalloc(NULL, HIF_RX_DESC_NT * sizeof(struct hif_desc) + + HIF_TX_DESC_NT * sizeof(struct hif_desc), RTE_CACHE_LINE_SIZE); + if (!addr) { + PFE_PMD_ERR("Could not allocate buffer descriptors!"); + err = -ENOMEM; + goto err0; + } + + hif->descr_baseaddr_p = pfe_mem_vtop((uintptr_t)addr); + hif->descr_baseaddr_v = addr; + hif->rx_ring_size = HIF_RX_DESC_NT; + hif->tx_ring_size = HIF_TX_DESC_NT; + + return 0; + +err0: + return err; +} + +static void +pfe_hif_free_descr(struct pfe_hif *hif) +{ + PMD_INIT_FUNC_TRACE(); + + rte_free(hif->descr_baseaddr_v); +} + +#if defined(LS1012A_PFE_RESET_WA) +static void +pfe_hif_disable_rx_desc(struct pfe_hif *hif) +{ + u32 ii; + struct hif_desc *desc = hif->rx_base; + + /*Mark all descriptors as LAST_BD */ + for (ii = 0; ii < hif->rx_ring_size; ii++) { + desc->ctrl |= BD_CTRL_LAST_BD; + desc++; + } +} + +struct class_rx_hdr_t { + u32 next_ptr; /* ptr to the start of the first DDR buffer */ + u16 length; /* total packet length */ + u16 phyno; /* input physical port number */ + u32 status; /* gemac status bits */ + u32 status2; /* reserved for software usage */ +}; + +/* STATUS_BAD_FRAME_ERR is set for all errors (including checksums if enabled) + * except overflow + */ +#define STATUS_BAD_FRAME_ERR BIT(16) +#define STATUS_LENGTH_ERR BIT(17) +#define STATUS_CRC_ERR BIT(18) +#define STATUS_TOO_SHORT_ERR BIT(19) +#define STATUS_TOO_LONG_ERR BIT(20) +#define STATUS_CODE_ERR BIT(21) +#define STATUS_MC_HASH_MATCH BIT(22) +#define STATUS_CUMULATIVE_ARC_HIT BIT(23) +#define STATUS_UNICAST_HASH_MATCH BIT(24) +#define STATUS_IP_CHECKSUM_CORRECT BIT(25) +#define STATUS_TCP_CHECKSUM_CORRECT BIT(26) +#define STATUS_UDP_CHECKSUM_CORRECT BIT(27) +#define STATUS_OVERFLOW_ERR BIT(28) /* GPI error */ +#define MIN_PKT_SIZE 64 +#define DUMMY_PKT_COUNT 128 + +static inline void +copy_to_lmem(u32 *dst, u32 *src, int len) +{ + int i; + + for (i = 0; i < len; i += sizeof(u32)) { + *dst = htonl(*src); + dst++; src++; + } +} +#if defined(RTE_TOOLCHAIN_GCC) +__attribute__ ((optimize(1))) +#endif +static void +send_dummy_pkt_to_hif(void) +{ + void *lmem_ptr, *ddr_ptr, *lmem_virt_addr; + u64 physaddr; + struct class_rx_hdr_t local_hdr; + static u32 dummy_pkt[] = { + 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608, + 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0, + 0x33221100, 0xa8c05544, 0x00000301, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f }; + + ddr_ptr = (void *)(size_t)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL); + if (!ddr_ptr) + return; + + lmem_ptr = (void *)(size_t)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL); + if (!lmem_ptr) + return; + + PFE_PMD_INFO("Sending a dummy pkt to HIF %p %p", ddr_ptr, lmem_ptr); + physaddr = DDR_VIRT_TO_PFE(ddr_ptr); + + lmem_virt_addr = (void *)CBUS_PFE_TO_VIRT((unsigned long)lmem_ptr); + + local_hdr.phyno = htons(0); /* RX_PHY_0 */ + local_hdr.length = htons(MIN_PKT_SIZE); + + local_hdr.next_ptr = htonl((u32)physaddr); + /*Mark checksum is correct */ + local_hdr.status = htonl((STATUS_IP_CHECKSUM_CORRECT | + STATUS_UDP_CHECKSUM_CORRECT | + STATUS_TCP_CHECKSUM_CORRECT | + STATUS_UNICAST_HASH_MATCH | + STATUS_CUMULATIVE_ARC_HIT)); + copy_to_lmem((u32 *)lmem_virt_addr, (u32 *)&local_hdr, + sizeof(local_hdr)); + + copy_to_lmem((u32 *)(lmem_virt_addr + LMEM_HDR_SIZE), (u32 *)dummy_pkt, + 0x40); + + writel((unsigned long)lmem_ptr, CLASS_INQ_PKTPTR); +} + +void +pfe_hif_rx_idle(struct pfe_hif *hif) +{ + int hif_stop_loop = DUMMY_PKT_COUNT; + u32 rx_status; + + pfe_hif_disable_rx_desc(hif); + PFE_PMD_INFO("Bringing hif to idle state..."); + writel(0, HIF_INT_ENABLE); + /*If HIF Rx BDP is busy send a dummy packet */ + do { + rx_status = readl(HIF_RX_STATUS); + if (rx_status & BDP_CSR_RX_DMA_ACTV) + send_dummy_pkt_to_hif(); + + sleep(1); + } while (--hif_stop_loop); + + if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV) + PFE_PMD_ERR("Failed\n"); + else + PFE_PMD_INFO("Done\n"); +} +#endif + +/* + * pfe_hif_init + * This function initializes the baseaddresses and irq, etc. + */ +int +pfe_hif_init(struct pfe *pfe) +{ + struct pfe_hif *hif = &pfe->hif; + int err; + + PMD_INIT_FUNC_TRACE(); + +#if defined(LS1012A_PFE_RESET_WA) + pfe_hif_rx_idle(hif); +#endif + + err = pfe_hif_alloc_descr(hif); + if (err) + goto err0; + + rte_spinlock_init(&hif->tx_lock); + rte_spinlock_init(&hif->lock); + + gpi_enable(HGPI_BASE_ADDR); + if (getenv("PPFE_INTR_SUPPORT")) { + struct epoll_event epoll_ev; + int event_fd = -1, epoll_fd, pfe_cdev_fd; + + pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDWR); + if (pfe_cdev_fd < 0) { + PFE_PMD_WARN("Unable to open PFE device file (%s).\n", + PFE_CDEV_PATH); + pfe->cdev_fd = PFE_CDEV_INVALID_FD; + return -1; + } + pfe->cdev_fd = pfe_cdev_fd; + + event_fd = eventfd(0, EFD_NONBLOCK); + /* hif interrupt enable */ + err = ioctl(pfe->cdev_fd, PFE_CDEV_HIF_INTR_EN, &event_fd); + if (err) { + PFE_PMD_ERR("\nioctl failed for intr enable err: %d\n", + errno); + goto err0; + } + epoll_fd = epoll_create(1); + epoll_ev.events = EPOLLIN | EPOLLPRI | EPOLLET; + epoll_ev.data.fd = event_fd; + err = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event_fd, &epoll_ev); + if (err < 0) { + PFE_PMD_ERR("epoll_ctl failed with err = %d\n", errno); + goto err0; + } + pfe->hif.epoll_fd = epoll_fd; + } + return 0; +err0: + return err; +} + +/* pfe_hif_exit- */ +void +pfe_hif_exit(struct pfe *pfe) +{ + struct pfe_hif *hif = &pfe->hif; + + PMD_INIT_FUNC_TRACE(); + + rte_spinlock_lock(&hif->lock); + hif->shm->g_client_status[0] = 0; + /* Make sure all clients are disabled*/ + hif->shm->g_client_status[1] = 0; + + rte_spinlock_unlock(&hif->lock); + + if (hif->setuped) { +#if defined(LS1012A_PFE_RESET_WA) + pfe_hif_rx_idle(hif); +#endif + /*Disable Rx/Tx */ + hif_rx_disable(); + hif_tx_disable(); + + pfe_hif_free_descr(hif); + pfe->hif.setuped = 0; + } + gpi_disable(HGPI_BASE_ADDR); +} diff --git a/drivers/net/ppfe/pfe_hif.h b/drivers/net/ppfe/pfe_hif.h new file mode 100644 index 000000000..fa3c08cc7 --- /dev/null +++ b/drivers/net/ppfe/pfe_hif.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_HIF_H_ +#define _PFE_HIF_H_ + +#define HIF_CLIENT_QUEUES_MAX 16 +#define HIF_RX_PKT_MIN_SIZE RTE_CACHE_LINE_SIZE +/* + * HIF_TX_DESC_NT value should be always greter than 4, + * Otherwise HIF_TX_POLL_MARK will become zero. + */ +#define HIF_RX_DESC_NT 64 +#define HIF_TX_DESC_NT 2048 + +enum { + PFE_CL_GEM0 = 0, + PFE_CL_GEM1, + HIF_CLIENTS_MAX +}; + +/*structure to store client queue info */ +struct hif_rx_queue { + struct rx_queue_desc *base; + u32 size; + u32 write_idx; +}; + +struct hif_tx_queue { + struct tx_queue_desc *base; + u32 size; + u32 ack_idx; +}; + +/*Structure to store the client info */ +struct hif_client { + unsigned int rx_qn; + struct hif_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX]; + unsigned int tx_qn; + struct hif_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX]; +}; + +/*HIF hardware buffer descriptor */ +struct hif_desc { + u32 ctrl; + u32 status; + u32 data; + u32 next; +}; + +struct __hif_desc { + u32 ctrl; + u32 status; + u32 data; +}; + +struct hif_desc_sw { + dma_addr_t data; + u16 len; + u8 client_id; + u8 q_no; + u16 flags; +}; + +struct pfe_hif { + /* To store registered clients in hif layer */ + struct hif_client client[HIF_CLIENTS_MAX]; + struct hif_shm *shm; + + void *descr_baseaddr_v; + unsigned long descr_baseaddr_p; + + struct hif_desc *rx_base; + u32 rx_ring_size; + u32 rxtoclean_index; + void *rx_buf_addr[HIF_RX_DESC_NT]; + void *rx_buf_vaddr[HIF_RX_DESC_NT]; + int rx_buf_len[HIF_RX_DESC_NT]; + unsigned int qno; + unsigned int client_id; + unsigned int client_ctrl; + unsigned int started; + unsigned int setuped; + + struct hif_desc *tx_base; + u32 tx_ring_size; + u32 txtosend; + u32 txtoclean; + u32 txavail; + u32 txtoflush; + struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT]; + int32_t epoll_fd; /**< File descriptor created for interrupt polling */ + +/* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */ + rte_spinlock_t tx_lock; +/* lock synchronizes hif rx queue processing */ + rte_spinlock_t lock; + struct rte_device *dev; +}; + +int pfe_hif_init(struct pfe *pfe); +void pfe_hif_exit(struct pfe *pfe); +void pfe_hif_rx_idle(struct pfe_hif *hif); + +#endif /* _PFE_HIF_H_ */ diff --git a/drivers/net/ppfe/pfe_hif_lib.c b/drivers/net/ppfe/pfe_hif_lib.c new file mode 100644 index 000000000..8f8121be1 --- /dev/null +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include "pfe_logs.h" +#include "pfe_mod.h" + +int +pfe_hif_lib_init(__rte_unused struct pfe *pfe) +{ + PMD_INIT_FUNC_TRACE(); + + return 0; +} + +void +pfe_hif_lib_exit(__rte_unused struct pfe *pfe) +{ + PMD_INIT_FUNC_TRACE(); +} diff --git a/drivers/net/ppfe/pfe_hif_lib.h b/drivers/net/ppfe/pfe_hif_lib.h new file mode 100644 index 000000000..2db7338c2 --- /dev/null +++ b/drivers/net/ppfe/pfe_hif_lib.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_HIF_LIB_H_ +#define _PFE_HIF_LIB_H_ + +#define HIF_CL_REQ_TIMEOUT 10 +#define GFP_DMA_PFE 0 + +enum { + REQUEST_CL_REGISTER = 0, + REQUEST_CL_UNREGISTER, + HIF_REQUEST_MAX +}; + +enum { + /* Event to indicate that client rx queue is reached water mark level */ + EVENT_HIGH_RX_WM = 0, + /* Event to indicate that, packet received for client */ + EVENT_RX_PKT_IND, + /* Event to indicate that, packet tx done for client */ + EVENT_TXDONE_IND, + HIF_EVENT_MAX +}; + +/*structure to store client queue info */ + +/*structure to store client queue info */ +struct hif_client_rx_queue { + struct rx_queue_desc *base; + u32 size; + u32 read_idx; + u32 write_idx; + u16 queue_id; + u16 port_id; + void *priv; +}; + +struct hif_client_tx_queue { + struct tx_queue_desc *base; + u32 size; + u32 read_idx; + u32 write_idx; + u32 tx_pending; + unsigned long jiffies_last_packet; + u32 nocpy_flag; + u32 prev_tmu_tx_pkts; + u32 done_tmu_tx_pkts; + u16 queue_id; + u16 port_id; + void *priv; +}; + +struct hif_client_s { + int id; + unsigned int tx_qn; + unsigned int rx_qn; + void *rx_qbase; + void *tx_qbase; + int tx_qsize; + int rx_qsize; + int cpu_id; + int port_id; + struct hif_client_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX]; + struct hif_client_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX]; + int (*event_handler)(void *data, int event, int qno); + unsigned long queue_mask[HIF_EVENT_MAX]; + struct pfe *pfe; + void *priv; +}; + +/* + * Client specific shared memory + * It contains number of Rx/Tx queues, base addresses and queue sizes + */ +struct hif_client_shm { + u32 ctrl; /*0-7: number of Rx queues, 8-15: number of tx queues */ + unsigned long rx_qbase; /*Rx queue base address */ + u32 rx_qsize; /*each Rx queue size, all Rx queues are of same size */ + unsigned long tx_qbase; /* Tx queue base address */ + u32 tx_qsize; /*each Tx queue size, all Tx queues are of same size */ +}; + +/*Client shared memory ctrl bit description */ +#define CLIENT_CTRL_RX_Q_CNT_OFST 0 +#define CLIENT_CTRL_TX_Q_CNT_OFST 8 +#define CLIENT_CTRL_RX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_RX_Q_CNT_OFST) \ + & 0xFF) +#define CLIENT_CTRL_TX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_TX_Q_CNT_OFST) \ + & 0xFF) + +/* + * Shared memory used to communicate between HIF driver and host/client drivers + * Before starting the hif driver rx_buf_pool ans rx_buf_pool_cnt should be + * initialized with host buffers and buffers count in the pool. + * rx_buf_pool_cnt should be >= HIF_RX_DESC_NT. + * + */ +struct hif_shm { + u32 rx_buf_pool_cnt; /*Number of rx buffers available*/ + /*Rx buffers required to initialize HIF rx descriptors */ + struct rte_mempool *pool; + void *rx_buf_pool[HIF_RX_DESC_NT]; + unsigned long g_client_status[2]; /*Global client status bit mask */ + /* Client specific shared memory */ + struct hif_client_shm client[HIF_CLIENTS_MAX]; +}; + +#define CL_DESC_OWN BIT(31) +/* This sets owner ship to HIF driver */ +#define CL_DESC_LAST BIT(30) +/* This indicates last packet for multi buffers handling */ +#define CL_DESC_FIRST BIT(29) +/* This indicates first packet for multi buffers handling */ + +#define CL_DESC_BUF_LEN(x) ((x) & 0xFFFF) +#define CL_DESC_FLAGS(x) (((x) & 0xF) << 16) +#define CL_DESC_GET_FLAGS(x) (((x) >> 16) & 0xF) + +struct rx_queue_desc { + void *data; + u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/ + u32 client_ctrl; +}; + +struct tx_queue_desc { + void *data; + u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/ +}; + +/* HIF Rx is not working properly for 2-byte aligned buffers and + * ip_header should be 4byte aligned for better iperformance. + * "ip_header = 64 + 6(hif_header) + 14 (MAC Header)" will be 4byte aligned. + * In case HW parse support: + * "ip_header = 64 + 6(hif_header) + 16 (parse) + 14 (MAC Header)" will be + * 4byte aligned. + */ +#define PFE_HIF_SIZE sizeof(struct hif_hdr) + +#ifdef RTE_LIBRTE_PPFE_SW_PARSE +#define PFE_PKT_HEADER_SZ PFE_HIF_SIZE +#else +#define PFE_PKT_HEADER_SZ (PFE_HIF_SIZE + sizeof(struct ppfe_parse)) +#endif + +#define MAX_L2_HDR_SIZE 14 /* Not correct for VLAN/PPPoE */ +#define MAX_L3_HDR_SIZE 20 /* Not correct for IPv6 */ +#define MAX_L4_HDR_SIZE 60 /* TCP with maximum options */ +#define MAX_HDR_SIZE (MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE \ + + MAX_L4_HDR_SIZE) +/* Used in page mode to clamp packet size to the maximum supported by the hif + *hw interface (<16KiB) + */ +#define MAX_PFE_PKT_SIZE 16380UL + +extern unsigned int emac_txq_cnt; + +int pfe_hif_lib_init(struct pfe *pfe); +void pfe_hif_lib_exit(struct pfe *pfe); + +#endif /* _PFE_HIF_LIB_H_ */ diff --git a/drivers/net/ppfe/pfe_mod.h b/drivers/net/ppfe/pfe_mod.h index e971547a9..f3382f3a7 100644 --- a/drivers/net/ppfe/pfe_mod.h +++ b/drivers/net/ppfe/pfe_mod.h @@ -7,6 +7,9 @@ struct pfe; +#include "pfe.h" +#include "pfe_hif.h" +#include "pfe_hif_lib.h" #include "pfe_eth.h" #define PHYID_MAX_VAL 32 @@ -42,6 +45,8 @@ struct pfe { uint64_t ddr_size; void *cbus_baseaddr; uint64_t cbus_size; + struct ls1012a_pfe_platform_data platform_data; + struct pfe_hif hif; struct pfe_eth eth; int mdio_muxval[PHYID_MAX_VAL]; uint8_t nb_devs; diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 77e3e5c30..6e8db20b8 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -23,9 +23,32 @@ static struct pfe *g_pfe; * information from HW. */ unsigned int pfe_svr = SVR_LS1012A_REV1; +static void *cbus_emac_base[3]; +static void *cbus_gpi_base[3]; int ppfe_logtype_pmd; +/* pfe_gemac_init + */ +static int +pfe_gemac_init(struct pfe_eth_priv_s *priv) +{ + struct gemac_cfg cfg; + + cfg.speed = SPEED_1000M; + cfg.duplex = DUPLEX_FULL; + + gemac_set_config(priv->EMAC_baseaddr, &cfg); + gemac_allow_broadcast(priv->EMAC_baseaddr); + gemac_enable_1536_rx(priv->EMAC_baseaddr); + gemac_enable_stacked_vlan(priv->EMAC_baseaddr); + gemac_enable_pause_rx(priv->EMAC_baseaddr); + gemac_set_bus_width(priv->EMAC_baseaddr, 64); + gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); + + return 0; +} + static void pfe_soc_version_get(void) { @@ -100,18 +123,44 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) { struct rte_eth_dev *eth_dev = NULL; struct pfe_eth_priv_s *priv = NULL; + struct ls1012a_eth_platform_data *einfo; + struct ls1012a_pfe_platform_data *pfe_info; int err; eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); if (eth_dev == NULL) return -ENOMEM; + /* Extract pltform data */ + pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data; + if (!pfe_info) { + PFE_PMD_ERR("pfe missing additional platform data"); + err = -ENODEV; + goto err0; + } + + einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata; + + /* einfo never be NULL, but no harm in having this check */ + if (!einfo) { + PFE_PMD_ERR("pfe missing additional gemacs platform data"); + err = -ENODEV; + goto err0; + } + priv = eth_dev->data->dev_private; priv->ndev = eth_dev; + priv->id = einfo[id].gem_id; priv->pfe = pfe; pfe->eth.eth_priv[id] = priv; + /* Set the info in the priv to the current info */ + priv->einfo = &einfo[id]; + priv->EMAC_baseaddr = cbus_emac_base[id]; + priv->PHY_baseaddr = cbus_emac_base[id]; + priv->GPI_baseaddr = cbus_gpi_base[id]; + #define HIF_GEMAC_TMUQ_BASE 6 priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); priv->high_tmu_q = priv->low_tmu_q + 1; @@ -129,6 +178,7 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) } eth_dev->data->mtu = 1500; + pfe_gemac_init(priv); eth_dev->data->nb_rx_queues = 1; eth_dev->data->nb_tx_queues = 1; @@ -146,6 +196,58 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) return err; } +static int +pfe_get_gemac_if_proprties(struct pfe *pfe, + __rte_unused const struct device_node *parent, + unsigned int port, unsigned int if_cnt, + struct ls1012a_pfe_platform_data *pdata) +{ + const struct device_node *gem = NULL; + size_t size; + unsigned int ii = 0, phy_id = 0; + const u32 *addr; + const void *mac_addr; + + for (ii = 0; ii < if_cnt; ii++) { + gem = of_get_next_child(parent, gem); + if (!gem) + goto err; + addr = of_get_property(gem, "reg", &size); + if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port)) + break; + } + + if (ii >= if_cnt) { + PFE_PMD_ERR("Failed to find interface = %d", if_cnt); + goto err; + } + + pdata->ls1012a_eth_pdata[port].gem_id = port; + + mac_addr = of_get_mac_address(gem); + + if (mac_addr) { + memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr, + ETH_ALEN); + } + + addr = of_get_property(gem, "fsl,mdio-mux-val", &size); + if (!addr) { + PFE_PMD_ERR("Invalid mdio-mux-val...."); + } else { + phy_id = rte_be_to_cpu_32((unsigned int)*addr); + pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; + } + if (pdata->ls1012a_eth_pdata[port].phy_id < 32) + pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = + pdata->ls1012a_eth_pdata[port].mdio_muxval; + + return 0; + +err: + return -1; +} + /* Parse integer from integer argument */ static int parse_integer_arg(const char *key __rte_unused, @@ -204,7 +306,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) const uint32_t *addr; uint64_t cbus_addr, ddr_size, cbus_size; int rc = -1, fd = -1, gem_id; - unsigned int interface_count = 0; + unsigned int ii, interface_count = 0; size_t size = 0; struct pfe_vdev_init_params init_params = { .gem_id = -1 @@ -268,6 +370,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) goto err; } + g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr); g_pfe->ddr_size = ddr_size; g_pfe->cbus_size = cbus_size; @@ -299,6 +402,42 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) PFE_PMD_INFO("num interfaces = %d ", interface_count); g_pfe->max_intf = interface_count; + g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; + + for (ii = 0; ii < interface_count; ii++) { + pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count, + &g_pfe->platform_data); + } + + pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr, + g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size); + + PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION)); + PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION)); + + PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION)); + PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION)); + + PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION)); + PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION)); + PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION)); + + PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION)); + PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION)); + + cbus_emac_base[0] = EMAC1_BASE_ADDR; + cbus_emac_base[1] = EMAC2_BASE_ADDR; + + cbus_gpi_base[0] = EGPI1_BASE_ADDR; + cbus_gpi_base[1] = EGPI2_BASE_ADDR; + + rc = pfe_hif_lib_init(g_pfe); + if (rc < 0) + goto err_hif_lib; + + rc = pfe_hif_init(g_pfe); + if (rc < 0) + goto err_hif; pfe_soc_version_get(); eth_init: if (init_params.gem_id < 0) @@ -318,6 +457,12 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) return 0; err_eth: + pfe_hif_exit(g_pfe); + +err_hif: + pfe_hif_lib_exit(g_pfe); + +err_hif_lib: err_prop: munmap(g_pfe->cbus_baseaddr, cbus_size); err: @@ -347,6 +492,12 @@ pmd_pfe_remove(struct rte_vdev_device *vdev) pfe_eth_exit(eth_dev, g_pfe); munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size); + if (g_pfe->nb_devs == 0) { + pfe_hif_exit(g_pfe); + pfe_hif_lib_exit(g_pfe); + rte_free(g_pfe); + g_pfe = NULL; + } return 0; } From patchwork Tue Oct 1 11:02:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60318 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5EB241BEAA; Tue, 1 Oct 2019 13:17:41 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 1E8C98F96 for ; Tue, 1 Oct 2019 13:17:34 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id D44EF1A053F; Tue, 1 Oct 2019 13:17:33 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id DB85B1A02BC; Tue, 1 Oct 2019 13:17:30 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id D840F402DA; Tue, 1 Oct 2019 19:17:26 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh , Akhil Goyal Date: Tue, 1 Oct 2019 16:32:02 +0530 Message-Id: <20191001110209.6047-8-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch adds device start, stop and close operations. Signed-off-by: Gagandeep Singh Signed-off-by: Akhil Goyal Acked-by: Nipun Gupta --- drivers/net/ppfe/Makefile | 2 +- drivers/net/ppfe/pfe_eth.h | 1 + drivers/net/ppfe/pfe_hif.c | 139 +++++++++++++ drivers/net/ppfe/pfe_hif.h | 41 ++++ drivers/net/ppfe/pfe_hif_lib.c | 362 ++++++++++++++++++++++++++++++++- drivers/net/ppfe/pfe_hif_lib.h | 11 + drivers/net/ppfe/pfe_mod.h | 1 + drivers/net/ppfe/ppfe_ethdev.c | 181 +++++++++++++++++ 8 files changed, 736 insertions(+), 2 deletions(-) diff --git a/drivers/net/ppfe/Makefile b/drivers/net/ppfe/Makefile index 0f1dba188..151d24dc7 100644 --- a/drivers/net/ppfe/Makefile +++ b/drivers/net/ppfe/Makefile @@ -32,7 +32,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PPFE_PMD) += pfe_hif.c LDLIBS += -lrte_bus_vdev LDLIBS += -lrte_bus_dpaa LDLIBS += -lrte_common_dpaax -LDLIBS += -lrte_eal +LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool LDLIBS += -lrte_ethdev -lrte_kvargs include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/net/ppfe/pfe_eth.h b/drivers/net/ppfe/pfe_eth.h index 5811b54eb..5dedc9eb9 100644 --- a/drivers/net/ppfe/pfe_eth.h +++ b/drivers/net/ppfe/pfe_eth.h @@ -53,6 +53,7 @@ struct ls1012a_pfe_platform_data { struct pfe_eth_priv_s { struct pfe *pfe; + struct hif_client_s client; int low_tmu_q; int high_tmu_q; struct rte_eth_dev *ndev; diff --git a/drivers/net/ppfe/pfe_hif.c b/drivers/net/ppfe/pfe_hif.c index 3a861b420..940f7419f 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -43,6 +43,145 @@ pfe_hif_free_descr(struct pfe_hif *hif) rte_free(hif->descr_baseaddr_v); } +/* + * pfe_hif_client_register + * + * This function used to register a client driver with the HIF driver. + * + * Return value: + * 0 - on Successful registration + */ +static int +pfe_hif_client_register(struct pfe_hif *hif, u32 client_id, + struct hif_client_shm *client_shm) +{ + struct hif_client *client = &hif->client[client_id]; + u32 i, cnt; + struct rx_queue_desc *rx_qbase; + struct tx_queue_desc *tx_qbase; + struct hif_rx_queue *rx_queue; + struct hif_tx_queue *tx_queue; + int err = 0; + + PMD_INIT_FUNC_TRACE(); + + rte_spinlock_lock(&hif->tx_lock); + + if (test_bit(client_id, &hif->shm->g_client_status[0])) { + PFE_PMD_ERR("client %d already registered", client_id); + err = -1; + goto unlock; + } + + memset(client, 0, sizeof(struct hif_client)); + + /* Initialize client Rx queues baseaddr, size */ + + cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl); + /* Check if client is requesting for more queues than supported */ + if (cnt > HIF_CLIENT_QUEUES_MAX) + cnt = HIF_CLIENT_QUEUES_MAX; + + client->rx_qn = cnt; + rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase; + for (i = 0; i < cnt; i++) { + rx_queue = &client->rx_q[i]; + rx_queue->base = rx_qbase + i * client_shm->rx_qsize; + rx_queue->size = client_shm->rx_qsize; + rx_queue->write_idx = 0; + } + + /* Initialize client Tx queues baseaddr, size */ + cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl); + + /* Check if client is requesting for more queues than supported */ + if (cnt > HIF_CLIENT_QUEUES_MAX) + cnt = HIF_CLIENT_QUEUES_MAX; + + client->tx_qn = cnt; + tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase; + for (i = 0; i < cnt; i++) { + tx_queue = &client->tx_q[i]; + tx_queue->base = tx_qbase + i * client_shm->tx_qsize; + tx_queue->size = client_shm->tx_qsize; + tx_queue->ack_idx = 0; + } + + set_bit(client_id, &hif->shm->g_client_status[0]); + +unlock: + rte_spinlock_unlock(&hif->tx_lock); + + return err; +} + +/* + * pfe_hif_client_unregister + * + * This function used to unregister a client from the HIF driver. + * + */ +static void +pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id) +{ + PMD_INIT_FUNC_TRACE(); + + /* + * Mark client as no longer available (which prevents further packet + * receive for this client) + */ + rte_spinlock_lock(&hif->tx_lock); + + if (!test_bit(client_id, &hif->shm->g_client_status[0])) { + PFE_PMD_ERR("client %d not registered", client_id); + + rte_spinlock_unlock(&hif->tx_lock); + return; + } + + clear_bit(client_id, &hif->shm->g_client_status[0]); + + rte_spinlock_unlock(&hif->tx_lock); +} + +void +hif_process_client_req(struct pfe_hif *hif, int req, + int data1, __rte_unused int data2) +{ + unsigned int client_id = data1; + + if (client_id >= HIF_CLIENTS_MAX) { + PFE_PMD_ERR("client id %d out of bounds", client_id); + return; + } + + switch (req) { + case REQUEST_CL_REGISTER: + /* Request for register a client */ + PFE_PMD_INFO("register client_id %d", client_id); + pfe_hif_client_register(hif, client_id, (struct + hif_client_shm *)&hif->shm->client[client_id]); + break; + + case REQUEST_CL_UNREGISTER: + PFE_PMD_INFO("unregister client_id %d", client_id); + + /* Request for unregister a client */ + pfe_hif_client_unregister(hif, client_id); + + break; + + default: + PFE_PMD_ERR("unsupported request %d", req); + break; + } + + /* + * Process client Tx queues + * Currently we don't have checking for tx pending + */ +} + #if defined(LS1012A_PFE_RESET_WA) static void pfe_hif_disable_rx_desc(struct pfe_hif *hif) diff --git a/drivers/net/ppfe/pfe_hif.h b/drivers/net/ppfe/pfe_hif.h index fa3c08cc7..483db75da 100644 --- a/drivers/net/ppfe/pfe_hif.h +++ b/drivers/net/ppfe/pfe_hif.h @@ -14,6 +14,12 @@ #define HIF_RX_DESC_NT 64 #define HIF_TX_DESC_NT 2048 +#define HIF_FIRST_BUFFER BIT(0) +#define HIF_LAST_BUFFER BIT(1) +#define HIF_DONT_DMA_MAP BIT(2) +#define HIF_DATA_VALID BIT(3) +#define HIF_TSO BIT(4) + enum { PFE_CL_GEM0 = 0, PFE_CL_GEM1, @@ -63,6 +69,39 @@ struct hif_desc_sw { u16 flags; }; +struct hif_hdr { + u8 client_id; + u8 q_num; + u16 client_ctrl; + u16 client_ctrl1; +}; + +struct __hif_hdr { + union { + struct hif_hdr hdr; + u32 word[2]; + }; +}; + +struct hif_ipsec_hdr { + u16 sa_handle[2]; +} __packed; + +struct ppfe_parse { + unsigned int packet_type; + uint16_t hash; + uint16_t parse_incomplete; + unsigned long long ol_flags; +}; + +/* HIF_CTRL_TX... defines */ +#define HIF_CTRL_TX_CHECKSUM BIT(2) + +/* HIF_CTRL_RX... defines */ +#define HIF_CTRL_RX_OFFSET_OFST (24) +#define HIF_CTRL_RX_CHECKSUMMED BIT(2) +#define HIF_CTRL_RX_CONTINUED BIT(1) + struct pfe_hif { /* To store registered clients in hif layer */ struct hif_client client[HIF_CLIENTS_MAX]; @@ -99,6 +138,8 @@ struct pfe_hif { struct rte_device *dev; }; +void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int + data2); int pfe_hif_init(struct pfe *pfe); void pfe_hif_exit(struct pfe *pfe); void pfe_hif_rx_idle(struct pfe_hif *hif); diff --git a/drivers/net/ppfe/pfe_hif_lib.c b/drivers/net/ppfe/pfe_hif_lib.c index 8f8121be1..2012d896a 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -5,11 +5,371 @@ #include "pfe_logs.h" #include "pfe_mod.h" +unsigned int emac_txq_cnt; + +/* + * @pfe_hal_lib.c + * Common functions used by HIF client drivers + */ + +/*HIF shared memory Global variable */ +struct hif_shm ghif_shm; + +/*This function sends indication to HIF driver + * + * @param[in] hif hif context + */ +static void +hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int + data2) +{ + hif_process_client_req(hif, req, data1, data2); +} + +void +hif_lib_indicate_client(struct hif_client_s *client, int event_type, + int qno) +{ + if (!client || event_type >= HIF_EVENT_MAX || + qno >= HIF_CLIENT_QUEUES_MAX) + return; + + if (!test_and_set_bit(qno, &client->queue_mask[event_type])) + client->event_handler(client->priv, event_type, qno); +} + +/*This function releases Rx queue descriptors memory and pre-filled buffers + * + * @param[in] client hif_client context + */ +static void +hif_lib_client_release_rx_buffers(struct hif_client_s *client) +{ + struct rte_mempool *pool; + struct rte_pktmbuf_pool_private *mb_priv; + struct rx_queue_desc *desc; + unsigned int qno, ii; + void *buf; + + pool = client->pfe->hif.shm->pool; + mb_priv = rte_mempool_get_priv(pool); + for (qno = 0; qno < client->rx_qn; qno++) { + desc = client->rx_q[qno].base; + + for (ii = 0; ii < client->rx_q[qno].size; ii++) { + buf = (void *)desc->data; + if (buf) { + /* Data pointor to mbuf pointor calculation: + * "Data - User private data - headroom - mbufsize" + * Actual data pointor given to HIF BDs was + * "mbuf->data_offset - PFE_PKT_HEADER_SZ" + */ + buf = buf + PFE_PKT_HEADER_SZ + - sizeof(struct rte_mbuf) + - RTE_PKTMBUF_HEADROOM + - mb_priv->mbuf_priv_size; + rte_pktmbuf_free((struct rte_mbuf *)buf); + desc->ctrl = 0; + } + desc++; + } + } + rte_free(client->rx_qbase); +} + +/*This function allocates memory for the rxq descriptors and pre-fill rx queues + * with buffers. + * @param[in] client client context + * @param[in] q_size size of the rxQ, all queues are of same size + */ +static int +hif_lib_client_init_rx_buffers(struct hif_client_s *client, + int q_size) +{ + struct rx_queue_desc *desc; + struct hif_client_rx_queue *queue; + unsigned int ii, qno; + + /*Allocate memory for the client queues */ + client->rx_qbase = rte_malloc(NULL, client->rx_qn * q_size * + sizeof(struct rx_queue_desc), RTE_CACHE_LINE_SIZE); + if (!client->rx_qbase) + goto err; + + for (qno = 0; qno < client->rx_qn; qno++) { + queue = &client->rx_q[qno]; + + queue->base = client->rx_qbase + qno * q_size * sizeof(struct + rx_queue_desc); + queue->size = q_size; + queue->read_idx = 0; + queue->write_idx = 0; + queue->queue_id = 0; + queue->port_id = client->port_id; + queue->priv = client->priv; + PFE_PMD_DEBUG("rx queue: %d, base: %p, size: %d\n", qno, + queue->base, queue->size); + } + + for (qno = 0; qno < client->rx_qn; qno++) { + queue = &client->rx_q[qno]; + desc = queue->base; + + for (ii = 0; ii < queue->size; ii++) { + desc->ctrl = CL_DESC_OWN; + desc++; + } + } + + return 0; + +err: + return 1; +} + + +static void +hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue) +{ + /* + * Check if there are any pending packets. Client must flush the tx + * queues before unregistering, by calling by calling + * hif_lib_tx_get_next_complete() + * + * Hif no longer calls since we are no longer registered + */ + if (queue->tx_pending) + PFE_PMD_ERR("pending transmit packet"); +} + +static void +hif_lib_client_release_tx_buffers(struct hif_client_s *client) +{ + unsigned int qno; + + for (qno = 0; qno < client->tx_qn; qno++) + hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]); + + rte_free(client->tx_qbase); +} + +static int +hif_lib_client_init_tx_buffers(struct hif_client_s *client, int + q_size) +{ + struct hif_client_tx_queue *queue; + unsigned int qno; + + client->tx_qbase = rte_malloc(NULL, client->tx_qn * q_size * + sizeof(struct tx_queue_desc), RTE_CACHE_LINE_SIZE); + if (!client->tx_qbase) + return 1; + + for (qno = 0; qno < client->tx_qn; qno++) { + queue = &client->tx_q[qno]; + + queue->base = client->tx_qbase + qno * q_size * sizeof(struct + tx_queue_desc); + queue->size = q_size; + queue->read_idx = 0; + queue->write_idx = 0; + queue->tx_pending = 0; + queue->nocpy_flag = 0; + queue->prev_tmu_tx_pkts = 0; + queue->done_tmu_tx_pkts = 0; + queue->priv = client->priv; + queue->queue_id = 0; + queue->port_id = client->port_id; + + PFE_PMD_DEBUG("tx queue: %d, base: %p, size: %d", qno, + queue->base, queue->size); + } + + return 0; +} + +static int +hif_lib_event_dummy(__rte_unused void *priv, + __rte_unused int event_type, __rte_unused int qno) +{ + return 0; +} + int -pfe_hif_lib_init(__rte_unused struct pfe *pfe) +hif_lib_client_register(struct hif_client_s *client) { + struct hif_shm *hif_shm; + struct hif_client_shm *client_shm; + int err, i; + PMD_INIT_FUNC_TRACE(); + /*Allocate memory before spin_lock*/ + if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) { + err = -ENOMEM; + goto err_rx; + } + + if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) { + err = -ENOMEM; + goto err_tx; + } + + rte_spinlock_lock(&client->pfe->hif.lock); + if (!(client->pfe) || client->id >= HIF_CLIENTS_MAX || + client->pfe->hif_client[client->id]) { + err = -EINVAL; + goto err; + } + + hif_shm = client->pfe->hif.shm; + + if (!client->event_handler) + client->event_handler = hif_lib_event_dummy; + + /*Initialize client specific shared memory */ + client_shm = (struct hif_client_shm *)&hif_shm->client[client->id]; + client_shm->rx_qbase = (unsigned long)client->rx_qbase; + client_shm->rx_qsize = client->rx_qsize; + client_shm->tx_qbase = (unsigned long)client->tx_qbase; + client_shm->tx_qsize = client->tx_qsize; + client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) | + (client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST); + + for (i = 0; i < HIF_EVENT_MAX; i++) { + client->queue_mask[i] = 0; /* + * By default all events are + * unmasked + */ + } + + /*Indicate to HIF driver*/ + hif_lib_indicate_hif(&client->pfe->hif, REQUEST_CL_REGISTER, + client->id, 0); + + PFE_PMD_DEBUG("client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d", + client, client->id, client->tx_qsize, client->rx_qsize); + + client->cpu_id = -1; + + client->pfe->hif_client[client->id] = client; + rte_spinlock_unlock(&client->pfe->hif.lock); + + return 0; + +err: + rte_spinlock_unlock(&client->pfe->hif.lock); + hif_lib_client_release_tx_buffers(client); + +err_tx: + hif_lib_client_release_rx_buffers(client); + +err_rx: + return err; +} + +int +hif_lib_client_unregister(struct hif_client_s *client) +{ + struct pfe *pfe = client->pfe; + u32 client_id = client->id; + + PFE_PMD_INFO("client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d", + client, client->id, client->tx_qsize, client->rx_qsize); + + rte_spinlock_lock(&pfe->hif.lock); + hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0); + + hif_lib_client_release_tx_buffers(client); + hif_lib_client_release_rx_buffers(client); + pfe->hif_client[client_id] = NULL; + rte_spinlock_unlock(&pfe->hif.lock); + + return 0; +} + +int +hif_lib_event_handler_start(struct hif_client_s *client, int event, + int qno) +{ + struct hif_client_rx_queue *queue = &client->rx_q[qno]; + struct rx_queue_desc *desc = queue->base + queue->read_idx; + + if (event >= HIF_EVENT_MAX || qno >= HIF_CLIENT_QUEUES_MAX) { + PFE_PMD_WARN("Unsupported event : %d queue number : %d", + event, qno); + return -1; + } + + test_and_clear_bit(qno, &client->queue_mask[event]); + + switch (event) { + case EVENT_RX_PKT_IND: + if (!(desc->ctrl & CL_DESC_OWN)) + hif_lib_indicate_client(client, + EVENT_RX_PKT_IND, qno); + break; + + case EVENT_HIGH_RX_WM: + case EVENT_TXDONE_IND: + default: + break; + } + + return 0; +} + +void * +hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, + unsigned int *flags, __rte_unused int count) +{ + struct hif_client_tx_queue *queue = &client->tx_q[qno]; + struct tx_queue_desc *desc = queue->base + queue->read_idx; + + PFE_DP_LOG(DEBUG, "qno : %d rd_indx: %d pending:%d", + qno, queue->read_idx, queue->tx_pending); + + if (!queue->tx_pending) + return NULL; + + if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) { + u32 tmu_tx_pkts = 0; + + if (queue->prev_tmu_tx_pkts > tmu_tx_pkts) + queue->done_tmu_tx_pkts = UINT_MAX - + queue->prev_tmu_tx_pkts + tmu_tx_pkts; + else + queue->done_tmu_tx_pkts = tmu_tx_pkts - + queue->prev_tmu_tx_pkts; + + queue->prev_tmu_tx_pkts = tmu_tx_pkts; + + if (!queue->done_tmu_tx_pkts) + return NULL; + } + + if (desc->ctrl & CL_DESC_OWN) + return NULL; + + queue->read_idx = (queue->read_idx + 1) & (queue->size - 1); + queue->tx_pending--; + + *flags = CL_DESC_GET_FLAGS(desc->ctrl); + + if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER)) + queue->done_tmu_tx_pkts--; + + return desc->data; +} + +int +pfe_hif_lib_init(struct pfe *pfe) +{ + PMD_INIT_FUNC_TRACE(); + + emac_txq_cnt = EMAC_TXQ_CNT; + pfe->hif.shm = &ghif_shm; + return 0; } diff --git a/drivers/net/ppfe/pfe_hif_lib.h b/drivers/net/ppfe/pfe_hif_lib.h index 2db7338c2..03e492559 100644 --- a/drivers/net/ppfe/pfe_hif_lib.h +++ b/drivers/net/ppfe/pfe_hif_lib.h @@ -5,6 +5,8 @@ #ifndef _PFE_HIF_LIB_H_ #define _PFE_HIF_LIB_H_ +#include "pfe_hif.h" + #define HIF_CL_REQ_TIMEOUT 10 #define GFP_DMA_PFE 0 @@ -158,5 +160,14 @@ extern unsigned int emac_txq_cnt; int pfe_hif_lib_init(struct pfe *pfe); void pfe_hif_lib_exit(struct pfe *pfe); +int hif_lib_client_register(struct hif_client_s *client); +int hif_lib_client_unregister(struct hif_client_s *client); +void hif_lib_indicate_client(struct hif_client_s *client, int event, int data); +int hif_lib_event_handler_start(struct hif_client_s *client, int event, int + data); +void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, + unsigned int *flags, int count); +int pfe_hif_shm_init(struct hif_shm *hif_shm, struct rte_mempool *mb_pool); +void pfe_hif_shm_clean(struct hif_shm *hif_shm); #endif /* _PFE_HIF_LIB_H_ */ diff --git a/drivers/net/ppfe/pfe_mod.h b/drivers/net/ppfe/pfe_mod.h index f3382f3a7..24b9ebd1e 100644 --- a/drivers/net/ppfe/pfe_mod.h +++ b/drivers/net/ppfe/pfe_mod.h @@ -48,6 +48,7 @@ struct pfe { struct ls1012a_pfe_platform_data platform_data; struct pfe_hif hif; struct pfe_eth eth; + struct hif_client_s *hif_client[HIF_CLIENTS_MAX]; int mdio_muxval[PHYID_MAX_VAL]; uint8_t nb_devs; uint8_t max_intf; diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 6e8db20b8..19467b90d 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -71,6 +71,126 @@ pfe_soc_version_get(void) fclose(svr_file); } +static int pfe_eth_start(struct pfe_eth_priv_s *priv) +{ + gpi_enable(priv->GPI_baseaddr); + gemac_enable(priv->EMAC_baseaddr); + + return 0; +} + +static void +pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int + __rte_unused from_tx, __rte_unused int n_desc) +{ + struct rte_mbuf *mbuf; + unsigned int flags; + + /* Clean HIF and client queue */ + while ((mbuf = hif_lib_tx_get_next_complete(&priv->client, + tx_q_num, &flags, + HIF_TX_DESC_NT))) { + if (mbuf) { + mbuf->next = NULL; + mbuf->nb_segs = 1; + rte_pktmbuf_free(mbuf); + } + } +} + + +static void +pfe_eth_flush_tx(struct pfe_eth_priv_s *priv) +{ + unsigned int ii; + + for (ii = 0; ii < emac_txq_cnt; ii++) + pfe_eth_flush_txQ(priv, ii, 0, 0); +} + +static int +pfe_eth_event_handler(void *data, int event, __rte_unused int qno) +{ + struct pfe_eth_priv_s *priv = data; + + switch (event) { + case EVENT_TXDONE_IND: + pfe_eth_flush_tx(priv); + hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0); + break; + case EVENT_HIGH_RX_WM: + default: + break; + } + + return 0; +} + +static int +pfe_eth_open(struct rte_eth_dev *dev) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + struct hif_client_s *client; + struct hif_shm *hif_shm; + int rc; + + /* Register client driver with HIF */ + client = &priv->client; + + if (client->pfe) { + hif_shm = client->pfe->hif.shm; + /* TODO please remove the below code of if block, once we add + * the proper cleanup in eth_close + */ + if (!test_bit(PFE_CL_GEM0 + priv->id, + &hif_shm->g_client_status[0])) { + /* Register client driver with HIF */ + memset(client, 0, sizeof(*client)); + client->id = PFE_CL_GEM0 + priv->id; + client->tx_qn = emac_txq_cnt; + client->rx_qn = EMAC_RXQ_CNT; + client->priv = priv; + client->pfe = priv->pfe; + client->port_id = dev->data->port_id; + client->event_handler = pfe_eth_event_handler; + + client->tx_qsize = EMAC_TXQ_DEPTH; + client->rx_qsize = EMAC_RXQ_DEPTH; + + rc = hif_lib_client_register(client); + if (rc) { + PFE_PMD_ERR("hif_lib_client_register(%d)" + " failed", client->id); + goto err0; + } + } + } else { + /* Register client driver with HIF */ + memset(client, 0, sizeof(*client)); + client->id = PFE_CL_GEM0 + priv->id; + client->tx_qn = emac_txq_cnt; + client->rx_qn = EMAC_RXQ_CNT; + client->priv = priv; + client->pfe = priv->pfe; + client->port_id = dev->data->port_id; + client->event_handler = pfe_eth_event_handler; + + client->tx_qsize = EMAC_TXQ_DEPTH; + client->rx_qsize = EMAC_RXQ_DEPTH; + + rc = hif_lib_client_register(client); + if (rc) { + PFE_PMD_ERR("hif_lib_client_register(%d) failed", + client->id); + goto err0; + } + } + rc = pfe_eth_start(priv); + +err0: + return rc; +} + static int pfe_eth_open_cdev(struct pfe_eth_priv_s *priv) { @@ -105,11 +225,21 @@ pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) } } +static void +pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + + gemac_disable(priv->EMAC_baseaddr); + gpi_disable(priv->GPI_baseaddr); +} + static void pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) { PMD_INIT_FUNC_TRACE(); + pfe_eth_stop(dev); /* Close the device file for link status */ pfe_eth_close_cdev(dev->data->dev_private); @@ -118,6 +248,55 @@ pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) pfe->nb_devs--; } +static void +pfe_eth_close(struct rte_eth_dev *dev) +{ + if (!dev) + return; + + if (!g_pfe) + return; + + pfe_eth_exit(dev, g_pfe); + + if (g_pfe->nb_devs == 0) { + pfe_hif_exit(g_pfe); + pfe_hif_lib_exit(g_pfe); + rte_free(g_pfe); + g_pfe = NULL; + } +} + +static int +pfe_eth_configure(struct rte_eth_dev *dev __rte_unused) +{ + return 0; +} + +static int +pfe_eth_info(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info) +{ + struct pfe_eth_priv_s *internals = dev->data->dev_private; + + dev_info->if_index = internals->id; + dev_info->max_mac_addrs = PPFE_MAX_MACS; + dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE; + dev_info->max_rx_queues = dev->data->nb_rx_queues; + dev_info->max_tx_queues = dev->data->nb_tx_queues; + dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE; + + return 0; +} + +static const struct eth_dev_ops ops = { + .dev_start = pfe_eth_open, + .dev_stop = pfe_eth_stop, + .dev_close = pfe_eth_close, + .dev_configure = pfe_eth_configure, + .dev_infos_get = pfe_eth_info, +}; + static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) { @@ -178,6 +357,8 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) } eth_dev->data->mtu = 1500; + eth_dev->dev_ops = &ops; + pfe_eth_stop(eth_dev); pfe_gemac_init(priv); eth_dev->data->nb_rx_queues = 1; From patchwork Tue Oct 1 11:02:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60319 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4FA261BEB0; Tue, 1 Oct 2019 13:17:43 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 33E581BE3D for ; Tue, 1 Oct 2019 13:17:34 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 0E0C91A02BC; Tue, 1 Oct 2019 13:17:34 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id A61471A0096; Tue, 1 Oct 2019 13:17:31 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 2878C4029A; Tue, 1 Oct 2019 19:17:28 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:32:03 +0530 Message-Id: <20191001110209.6047-9-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 08/14] net/ppfe: add queue setup and release operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add RX/TX queue setup operations and supported checksum offloads. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- doc/guides/nics/features/ppfe.ini | 2 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/pfe_hif.c | 115 ++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.h | 1 + drivers/net/ppfe/pfe_hif_lib.c | 50 +++++++++++++ drivers/net/ppfe/ppfe_ethdev.c | 93 ++++++++++++++++++++++++ 6 files changed, 262 insertions(+) diff --git a/doc/guides/nics/features/ppfe.ini b/doc/guides/nics/features/ppfe.ini index cd5f836a3..4e38ffd24 100644 --- a/doc/guides/nics/features/ppfe.ini +++ b/doc/guides/nics/features/ppfe.ini @@ -4,6 +4,8 @@ ; Refer to default.ini for the full list of available PMD features. ; [Features] +L3 checksum offload = Y +L4 checksum offload = Y Linux VFIO = Y ARMv8 = Y Usage doc = Y diff --git a/doc/guides/nics/ppfe.rst b/doc/guides/nics/ppfe.rst index 29b02957f..c95525e5b 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -93,6 +93,7 @@ the kernel layer for link status. PPFE Features ~~~~~~~~~~~~~~ +- L3/L4 checksum offload - ARMv8 Supported PPFE SoCs diff --git a/drivers/net/ppfe/pfe_hif.c b/drivers/net/ppfe/pfe_hif.c index 940f7419f..024ca3d77 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -43,6 +43,121 @@ pfe_hif_free_descr(struct pfe_hif *hif) rte_free(hif->descr_baseaddr_v); } +/* + * pfe_hif_init_buffers + * This function initializes the HIF Rx/Tx ring descriptors and + * initialize Rx queue with buffers. + */ +int +pfe_hif_init_buffers(struct pfe_hif *hif) +{ + struct hif_desc *desc, *first_desc_p; + uint32_t i = 0; + + PMD_INIT_FUNC_TRACE(); + + /* Check enough Rx buffers available in the shared memory */ + if (hif->shm->rx_buf_pool_cnt < hif->rx_ring_size) + return -ENOMEM; + + hif->rx_base = hif->descr_baseaddr_v; + memset(hif->rx_base, 0, hif->rx_ring_size * sizeof(struct hif_desc)); + + /*Initialize Rx descriptors */ + desc = hif->rx_base; + first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p; + + for (i = 0; i < hif->rx_ring_size; i++) { + /* Initialize Rx buffers from the shared memory */ + struct rte_mbuf *mbuf = + (struct rte_mbuf *)hif->shm->rx_buf_pool[i]; + + /* PPFE mbuf structure is as follow: + * ----------------------------------------------------------+ + * | mbuf | priv | headroom (annotation + PPFE data) | data | + * ----------------------------------------------------------+ + * + * As we are expecting additional information like parse + * results, eth id, queue id from PPFE block along with data. + * so we have to provide additional memory for each packet to + * HIF rx rings so that PPFE block can write its headers. + * so, we are giving the data pointor to HIF rings whose + * calculation is as below: + * mbuf->data_pointor - Required_header_size + * + * We are utilizing the HEADROOM area to receive the PPFE + * block headers. On packet reception, HIF driver will use + * PPFE headers information based on which it will decide + * the clients and fill the parse results. + * after that application can use/overwrite the HEADROOM area. + */ + hif->rx_buf_vaddr[i] = + (void *)((size_t)mbuf->buf_addr + mbuf->data_off - + PFE_PKT_HEADER_SZ); + hif->rx_buf_addr[i] = + (void *)(size_t)(rte_pktmbuf_iova(mbuf) - + PFE_PKT_HEADER_SZ); + hif->rx_buf_len[i] = mbuf->buf_len - RTE_PKTMBUF_HEADROOM; + + hif->shm->rx_buf_pool[i] = NULL; + + writel(DDR_PHYS_TO_PFE(hif->rx_buf_addr[i]), + &desc->data); + writel(0, &desc->status); + + /* + * Ensure everything else is written to DDR before + * writing bd->ctrl + */ + rte_wmb(); + + writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM + | BD_CTRL_DIR | BD_CTRL_DESC_EN + | BD_BUF_LEN(hif->rx_buf_len[i])), &desc->ctrl); + + /* Chain descriptors */ + writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next); + desc++; + } + + /* Overwrite last descriptor to chain it to first one*/ + desc--; + writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next); + + hif->rxtoclean_index = 0; + + /*Initialize Rx buffer descriptor ring base address */ + writel(DDR_PHYS_TO_PFE(hif->descr_baseaddr_p), HIF_RX_BDP_ADDR); + + hif->tx_base = hif->rx_base + hif->rx_ring_size; + first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p + + hif->rx_ring_size; + memset(hif->tx_base, 0, hif->tx_ring_size * sizeof(struct hif_desc)); + + /*Initialize tx descriptors */ + desc = hif->tx_base; + + for (i = 0; i < hif->tx_ring_size; i++) { + /* Chain descriptors */ + writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next); + writel(0, &desc->ctrl); + desc++; + } + + /* Overwrite last descriptor to chain it to first one */ + desc--; + writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next); + hif->txavail = hif->tx_ring_size; + hif->txtosend = 0; + hif->txtoclean = 0; + hif->txtoflush = 0; + + /*Initialize Tx buffer descriptor ring base address */ + writel((u32)DDR_PHYS_TO_PFE(first_desc_p), HIF_TX_BDP_ADDR); + + return 0; +} + /* * pfe_hif_client_register * diff --git a/drivers/net/ppfe/pfe_hif.h b/drivers/net/ppfe/pfe_hif.h index 483db75da..80f78551c 100644 --- a/drivers/net/ppfe/pfe_hif.h +++ b/drivers/net/ppfe/pfe_hif.h @@ -143,5 +143,6 @@ void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int int pfe_hif_init(struct pfe *pfe); void pfe_hif_exit(struct pfe *pfe); void pfe_hif_rx_idle(struct pfe_hif *hif); +int pfe_hif_init_buffers(struct pfe_hif *hif); #endif /* _PFE_HIF_H_ */ diff --git a/drivers/net/ppfe/pfe_hif_lib.c b/drivers/net/ppfe/pfe_hif_lib.c index 2012d896a..f5e290f27 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -15,6 +15,56 @@ unsigned int emac_txq_cnt; /*HIF shared memory Global variable */ struct hif_shm ghif_shm; +/* Cleanup the HIF shared memory, release HIF rx_buffer_pool. + * This function should be called after pfe_hif_exit + * + * @param[in] hif_shm Shared memory address location in DDR + */ +void +pfe_hif_shm_clean(struct hif_shm *hif_shm) +{ + unsigned int i; + void *pkt; + + for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { + pkt = hif_shm->rx_buf_pool[i]; + if (pkt) + rte_pktmbuf_free((struct rte_mbuf *)pkt); + } +} + +/* Initialize shared memory used between HIF driver and clients, + * allocate rx_buffer_pool required for HIF Rx descriptors. + * This function should be called before initializing HIF driver. + * + * @param[in] hif_shm Shared memory address location in DDR + * @rerurn 0 - on succes, <0 on fail to initialize + */ +int +pfe_hif_shm_init(struct hif_shm *hif_shm, struct rte_mempool *mb_pool) +{ + unsigned int i; + struct rte_mbuf *mbuf; + + memset(hif_shm, 0, sizeof(struct hif_shm)); + hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT; + + for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { + mbuf = rte_cpu_to_le_64(rte_pktmbuf_alloc(mb_pool)); + if (mbuf) + hif_shm->rx_buf_pool[i] = mbuf; + else + goto err0; + } + + return 0; + +err0: + PFE_PMD_ERR("Low memory"); + pfe_hif_shm_clean(hif_shm); + return -ENOMEM; +} + /*This function sends indication to HIF driver * * @param[in] hif hif context diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 19467b90d..4619a9d28 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -17,6 +17,17 @@ struct pfe_vdev_init_params { int8_t gem_id; }; static struct pfe *g_pfe; +/* Supported Rx offloads */ +static uint64_t dev_rx_offloads_sup = + DEV_RX_OFFLOAD_IPV4_CKSUM | + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM; + +/* Supported Tx offloads */ +static uint64_t dev_tx_offloads_sup = + DEV_TX_OFFLOAD_IPV4_CKSUM | + DEV_TX_OFFLOAD_UDP_CKSUM | + DEV_TX_OFFLOAD_TCP_CKSUM; /* TODO: make pfe_svr a runtime option. * Driver should be able to get the SVR @@ -285,16 +296,98 @@ pfe_eth_info(struct rte_eth_dev *dev, dev_info->max_rx_queues = dev->data->nb_rx_queues; dev_info->max_tx_queues = dev->data->nb_tx_queues; dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE; + dev_info->rx_offload_capa = dev_rx_offloads_sup; + dev_info->tx_offload_capa = dev_tx_offloads_sup; return 0; } +/* Only first mb_pool given on first call of this API will be used + * in whole system, also nb_rx_desc and rx_conf are unused params + */ +static int +pfe_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, + __rte_unused uint16_t nb_rx_desc, + __rte_unused unsigned int socket_id, + __rte_unused const struct rte_eth_rxconf *rx_conf, + struct rte_mempool *mb_pool) +{ + int rc = 0; + struct pfe *pfe; + struct pfe_eth_priv_s *priv = dev->data->dev_private; + + pfe = priv->pfe; + + if (queue_idx >= EMAC_RXQ_CNT) { + PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", + queue_idx, EMAC_RXQ_CNT); + return -1; + } + + if (!pfe->hif.setuped) { + rc = pfe_hif_shm_init(pfe->hif.shm, mb_pool); + if (rc) { + PFE_PMD_ERR("Could not allocate buffer descriptors"); + return -1; + } + + pfe->hif.shm->pool = mb_pool; + if (pfe_hif_init_buffers(&pfe->hif)) { + PFE_PMD_ERR("Could not initialize buffer descriptors"); + return -1; + } + hif_init(); + hif_rx_enable(); + hif_tx_enable(); + pfe->hif.setuped = 1; + } + dev->data->rx_queues[queue_idx] = &priv->client.rx_q[queue_idx]; + priv->client.rx_q[queue_idx].queue_id = queue_idx; + + return 0; +} + +static void +pfe_rx_queue_release(void *q __rte_unused) +{ + PMD_INIT_FUNC_TRACE(); +} + +static void +pfe_tx_queue_release(void *q __rte_unused) +{ + PMD_INIT_FUNC_TRACE(); +} + +static int +pfe_tx_queue_setup(struct rte_eth_dev *dev, + uint16_t queue_idx, + __rte_unused uint16_t nb_desc, + __rte_unused unsigned int socket_id, + __rte_unused const struct rte_eth_txconf *tx_conf) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + + if (queue_idx >= emac_txq_cnt) { + PFE_PMD_ERR("Invalid queue idx = %d, Max queues = %d", + queue_idx, emac_txq_cnt); + return -1; + } + dev->data->tx_queues[queue_idx] = &priv->client.tx_q[queue_idx]; + priv->client.tx_q[queue_idx].queue_id = queue_idx; + return 0; +} + static const struct eth_dev_ops ops = { .dev_start = pfe_eth_open, .dev_stop = pfe_eth_stop, .dev_close = pfe_eth_close, .dev_configure = pfe_eth_configure, .dev_infos_get = pfe_eth_info, + .rx_queue_setup = pfe_rx_queue_setup, + .rx_queue_release = pfe_rx_queue_release, + .tx_queue_setup = pfe_tx_queue_setup, + .tx_queue_release = pfe_tx_queue_release, }; static int From patchwork Tue Oct 1 11:02:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60320 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A45231BEC1; Tue, 1 Oct 2019 13:17:45 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id EE86E1B94D for ; Tue, 1 Oct 2019 13:17:35 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id B4BD71A01DE; Tue, 1 Oct 2019 13:17:35 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 2719D1A0543; Tue, 1 Oct 2019 13:17:33 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 9B7E4402C1; Tue, 1 Oct 2019 19:17:29 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:32:04 +0530 Message-Id: <20191001110209.6047-10-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 09/14] net/ppfe: add burst enqueue and dequeue operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add burst enqueue and dequeue operations to the ppfe PMD. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- drivers/net/ppfe/pfe_hif.c | 360 ++++++++++++++++++++++++++++++++- drivers/net/ppfe/pfe_hif.h | 8 + drivers/net/ppfe/pfe_hif_lib.c | 146 +++++++++++++ drivers/net/ppfe/pfe_hif_lib.h | 8 + drivers/net/ppfe/pfe_mod.h | 2 + drivers/net/ppfe/ppfe_ethdev.c | 140 +++++++++++++ 6 files changed, 663 insertions(+), 1 deletion(-) diff --git a/drivers/net/ppfe/pfe_hif.c b/drivers/net/ppfe/pfe_hif.c index 024ca3d77..d7d22329c 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -43,6 +43,38 @@ pfe_hif_free_descr(struct pfe_hif *hif) rte_free(hif->descr_baseaddr_v); } +/* pfe_hif_release_buffers */ +static void +pfe_hif_release_buffers(struct pfe_hif *hif) +{ + struct hif_desc *desc; + uint32_t i = 0; + struct rte_mbuf *mbuf; + struct rte_pktmbuf_pool_private *mb_priv; + + hif->rx_base = hif->descr_baseaddr_v; + + /*Free Rx buffers */ + desc = hif->rx_base; + mb_priv = rte_mempool_get_priv(hif->shm->pool); + for (i = 0; i < hif->rx_ring_size; i++) { + if (readl(&desc->data)) { + if (i < hif->shm->rx_buf_pool_cnt && + !hif->shm->rx_buf_pool[i]) { + mbuf = hif->rx_buf_vaddr[i] + PFE_PKT_HEADER_SZ + - sizeof(struct rte_mbuf) + - RTE_PKTMBUF_HEADROOM + - mb_priv->mbuf_priv_size; + hif->shm->rx_buf_pool[i] = mbuf; + } + } + writel(0, &desc->data); + writel(0, &desc->status); + writel(0, &desc->ctrl); + desc++; + } +} + /* * pfe_hif_init_buffers * This function initializes the HIF Rx/Tx ring descriptors and @@ -259,9 +291,332 @@ pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id) rte_spinlock_unlock(&hif->tx_lock); } +/* + * client_put_rxpacket- + */ +static struct rte_mbuf * +client_put_rxpacket(struct hif_rx_queue *queue, + void *pkt, u32 len, + u32 flags, u32 client_ctrl, + struct rte_mempool *pool, + u32 *rem_len) +{ + struct rx_queue_desc *desc = queue->base + queue->write_idx; + struct rte_mbuf *mbuf = NULL; + + + if (readl(&desc->ctrl) & CL_DESC_OWN) { + mbuf = rte_cpu_to_le_64(rte_pktmbuf_alloc(pool)); + if (unlikely(!mbuf)) { + PFE_PMD_WARN("Buffer allocation failure\n"); + return NULL; + } + + desc->data = pkt; + desc->client_ctrl = client_ctrl; + /* + * Ensure everything else is written to DDR before + * writing bd->ctrl + */ + rte_wmb(); + writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl); + queue->write_idx = (queue->write_idx + 1) + & (queue->size - 1); + + *rem_len = mbuf->buf_len; + } + + return mbuf; +} + +/* + * pfe_hif_rx_process- + * This function does pfe hif rx queue processing. + * Dequeue packet from Rx queue and send it to corresponding client queue + */ +int +pfe_hif_rx_process(struct pfe *pfe, int budget) +{ + struct hif_desc *desc; + struct hif_hdr *pkt_hdr; + struct __hif_hdr hif_hdr; + void *free_buf; + int rtc, len, rx_processed = 0; + struct __hif_desc local_desc; + int flags = 0, wait_for_last = 0, retry = 0; + unsigned int buf_size = 0; + struct rte_mbuf *mbuf = NULL; + struct pfe_hif *hif = &pfe->hif; + + rte_spinlock_lock(&hif->lock); + + rtc = hif->rxtoclean_index; + + while (rx_processed < budget) { + desc = hif->rx_base + rtc; + + __memcpy12(&local_desc, desc); + + /* ACK pending Rx interrupt */ + if (local_desc.ctrl & BD_CTRL_DESC_EN) { + if (unlikely(wait_for_last)) + continue; + else + break; + } + + len = BD_BUF_LEN(local_desc.ctrl); + pkt_hdr = (struct hif_hdr *)hif->rx_buf_vaddr[rtc]; + + /* Track last HIF header received */ + if (!hif->started) { + hif->started = 1; + + __memcpy8(&hif_hdr, pkt_hdr); + + hif->qno = hif_hdr.hdr.q_num; + hif->client_id = hif_hdr.hdr.client_id; + hif->client_ctrl = (hif_hdr.hdr.client_ctrl1 << 16) | + hif_hdr.hdr.client_ctrl; + flags = CL_DESC_FIRST; + + } else { + flags = 0; + } + + if (local_desc.ctrl & BD_CTRL_LIFM) { + flags |= CL_DESC_LAST; + wait_for_last = 0; + } else { + wait_for_last = 1; + } + + /* Check for valid client id and still registered */ + if (hif->client_id >= HIF_CLIENTS_MAX || + !(test_bit(hif->client_id, + &hif->shm->g_client_status[0]))) { + PFE_PMD_INFO("packet with invalid client id %d qnum %d", + hif->client_id, hif->qno); + + free_buf = hif->rx_buf_addr[rtc]; + + goto pkt_drop; + } + + /* Check to valid queue number */ + if (hif->client[hif->client_id].rx_qn <= hif->qno) { + PFE_DP_LOG(DEBUG, "packet with invalid queue: %d", + hif->qno); + hif->qno = 0; + } + +retry: + mbuf = + client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno], + (void *)pkt_hdr, len, flags, + hif->client_ctrl, hif->shm->pool, + &buf_size); + + if (unlikely(!mbuf)) { + if (!retry) { + pfe_tx_do_cleanup(pfe); + retry = 1; + goto retry; + } + rx_processed = budget; + + if (flags & CL_DESC_FIRST) + hif->started = 0; + + PFE_DP_LOG(DEBUG, "No buffers"); + break; + } + + retry = 0; + + free_buf = (void *)(size_t)rte_pktmbuf_iova(mbuf); + free_buf = free_buf - PFE_PKT_HEADER_SZ; + + /*Fill free buffer in the descriptor */ + hif->rx_buf_addr[rtc] = free_buf; + hif->rx_buf_vaddr[rtc] = (void *)((size_t)mbuf->buf_addr + + mbuf->data_off - PFE_PKT_HEADER_SZ); + hif->rx_buf_len[rtc] = buf_size - RTE_PKTMBUF_HEADROOM; + +pkt_drop: + writel(DDR_PHYS_TO_PFE(free_buf), &desc->data); + /* + * Ensure everything else is written to DDR before + * writing bd->ctrl + */ + rte_wmb(); + writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR | + BD_CTRL_DESC_EN | BD_BUF_LEN(hif->rx_buf_len[rtc])), + &desc->ctrl); + + rtc = (rtc + 1) & (hif->rx_ring_size - 1); + + if (local_desc.ctrl & BD_CTRL_LIFM) { + if (!(hif->client_ctrl & HIF_CTRL_RX_CONTINUED)) + rx_processed++; + + hif->started = 0; + } + } + + + hif->rxtoclean_index = rtc; + rte_spinlock_unlock(&hif->lock); + + /* we made some progress, re-start rx dma in case it stopped */ + hif_rx_dma_start(); + + return rx_processed; +} + +/* + * client_ack_txpacket- + * This function ack the Tx packet in the give client Tx queue by resetting + * ownership bit in the descriptor. + */ +static int +client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id, + unsigned int q_no) +{ + struct hif_tx_queue *queue = &hif->client[client_id].tx_q[q_no]; + struct tx_queue_desc *desc = queue->base + queue->ack_idx; + + if (readl(&desc->ctrl) & CL_DESC_OWN) { + writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl); + queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1); + + return 0; + + } else { + /*This should not happen */ + PFE_PMD_ERR("%d %d %d %d %d %p %d", + hif->txtosend, hif->txtoclean, hif->txavail, + client_id, q_no, queue, queue->ack_idx); + return 1; + } +} + +static void +__hif_tx_done_process(struct pfe *pfe, int count) +{ + struct hif_desc *desc; + struct hif_desc_sw *desc_sw; + unsigned int ttc, tx_avl; + int pkts_done[HIF_CLIENTS_MAX] = {0, 0}; + struct pfe_hif *hif = &pfe->hif; + + ttc = hif->txtoclean; + tx_avl = hif->txavail; + + while ((tx_avl < hif->tx_ring_size) && count--) { + desc = hif->tx_base + ttc; + + if (readl(&desc->ctrl) & BD_CTRL_DESC_EN) + break; + + desc_sw = &hif->tx_sw_queue[ttc]; + + if (desc_sw->client_id > HIF_CLIENTS_MAX) + PFE_PMD_ERR("Invalid cl id %d", desc_sw->client_id); + + pkts_done[desc_sw->client_id]++; + + client_ack_txpacket(hif, desc_sw->client_id, desc_sw->q_no); + + ttc = (ttc + 1) & (hif->tx_ring_size - 1); + tx_avl++; + } + + if (pkts_done[0]) + hif_lib_indicate_client(pfe->hif_client[0], EVENT_TXDONE_IND, + 0); + if (pkts_done[1]) + hif_lib_indicate_client(pfe->hif_client[1], EVENT_TXDONE_IND, + 0); + hif->txtoclean = ttc; + hif->txavail = tx_avl; +} + +static inline void +hif_tx_done_process(struct pfe *pfe, int count) +{ + struct pfe_hif *hif = &pfe->hif; + rte_spinlock_lock(&hif->tx_lock); + __hif_tx_done_process(pfe, count); + rte_spinlock_unlock(&hif->tx_lock); +} + +void +pfe_tx_do_cleanup(struct pfe *pfe) +{ + hif_tx_done_process(pfe, HIF_TX_DESC_NT); +} + +/* + * __hif_xmit_pkt - + * This function puts one packet in the HIF Tx queue + */ +void +hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int + q_no, void *data, u32 len, unsigned int flags) +{ + struct hif_desc *desc; + struct hif_desc_sw *desc_sw; + + desc = hif->tx_base + hif->txtosend; + desc_sw = &hif->tx_sw_queue[hif->txtosend]; + + desc_sw->len = len; + desc_sw->client_id = client_id; + desc_sw->q_no = q_no; + desc_sw->flags = flags; + + writel((u32)DDR_PHYS_TO_PFE(data), &desc->data); + + hif->txtosend = (hif->txtosend + 1) & (hif->tx_ring_size - 1); + hif->txavail--; + + if ((!((flags & HIF_DATA_VALID) && (flags & + HIF_LAST_BUFFER)))) + goto skip_tx; + + /* + * Ensure everything else is written to DDR before + * writing bd->ctrl + */ + rte_wmb(); + + do { + desc_sw = &hif->tx_sw_queue[hif->txtoflush]; + desc = hif->tx_base + hif->txtoflush; + + if (desc_sw->flags & HIF_LAST_BUFFER) { + writel((BD_CTRL_LIFM | + BD_CTRL_BRFETCH_DISABLE | BD_CTRL_RTFETCH_DISABLE + | BD_CTRL_PARSE_DISABLE | BD_CTRL_DESC_EN | + BD_BUF_LEN(desc_sw->len)), + &desc->ctrl); + } else { + writel((BD_CTRL_DESC_EN | + BD_BUF_LEN(desc_sw->len)), &desc->ctrl); + } + hif->txtoflush = (hif->txtoflush + 1) & (hif->tx_ring_size - 1); + } + while (hif->txtoflush != hif->txtosend) + ; + +skip_tx: + return; +} + void hif_process_client_req(struct pfe_hif *hif, int req, - int data1, __rte_unused int data2) + int data1, __rte_unused int data2) { unsigned int client_id = data1; @@ -503,6 +858,9 @@ pfe_hif_exit(struct pfe *pfe) hif_rx_disable(); hif_tx_disable(); + pfe_hif_release_buffers(hif); + pfe_hif_shm_clean(hif->shm); + pfe_hif_free_descr(hif); pfe->hif.setuped = 0; } diff --git a/drivers/net/ppfe/pfe_hif.h b/drivers/net/ppfe/pfe_hif.h index 80f78551c..5c9cdf0be 100644 --- a/drivers/net/ppfe/pfe_hif.h +++ b/drivers/net/ppfe/pfe_hif.h @@ -138,11 +138,19 @@ struct pfe_hif { struct rte_device *dev; }; +void hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int + q_no, void *data, u32 len, unsigned int flags); void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2); int pfe_hif_init(struct pfe *pfe); void pfe_hif_exit(struct pfe *pfe); void pfe_hif_rx_idle(struct pfe_hif *hif); +int pfe_hif_rx_process(struct pfe *pfe, int budget); int pfe_hif_init_buffers(struct pfe_hif *hif); +void pfe_tx_do_cleanup(struct pfe *pfe); + +#define __memcpy8(dst, src) memcpy(dst, src, 8) +#define __memcpy12(dst, src) memcpy(dst, src, 12) +#define __memcpy(dst, src, len) memcpy(dst, src, len) #endif /* _PFE_HIF_H_ */ diff --git a/drivers/net/ppfe/pfe_hif_lib.c b/drivers/net/ppfe/pfe_hif_lib.c index f5e290f27..bac9728b9 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -369,6 +369,152 @@ hif_lib_event_handler_start(struct hif_client_s *client, int event, return 0; } +#ifdef RTE_LIBRTE_PPFE_SW_PARSE +static inline void +pfe_sw_parse_pkt(struct rte_mbuf *mbuf) +{ + struct rte_net_hdr_lens hdr_lens; + + mbuf->packet_type = rte_net_get_ptype(mbuf, &hdr_lens, + RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK + | RTE_PTYPE_L4_MASK); + mbuf->l2_len = hdr_lens.l2_len; + mbuf->l3_len = hdr_lens.l3_len; +} +#endif + +/* + * This function gets one packet from the specified client queue + * It also refill the rx buffer + */ +int +hif_lib_receive_pkt(struct hif_client_rx_queue *queue, + struct rte_mempool *pool, struct rte_mbuf **rx_pkts, + uint16_t nb_pkts) +{ + struct rx_queue_desc *desc; + struct pfe_eth_priv_s *priv = queue->priv; + struct rte_pktmbuf_pool_private *mb_priv; + struct rte_mbuf *mbuf, *p_mbuf = NULL, *first_mbuf = NULL; + struct rte_eth_stats *stats = &priv->stats; + int i, wait_for_last = 0; +#ifndef RTE_LIBRTE_PPFE_SW_PARSE + struct ppfe_parse *parse_res; +#endif + + for (i = 0; i < nb_pkts;) { + do { + desc = queue->base + queue->read_idx; + if ((desc->ctrl & CL_DESC_OWN)) { + stats->ipackets += i; + return i; + } + + mb_priv = rte_mempool_get_priv(pool); + + mbuf = desc->data + PFE_PKT_HEADER_SZ + - sizeof(struct rte_mbuf) + - RTE_PKTMBUF_HEADROOM + - mb_priv->mbuf_priv_size; + mbuf->next = NULL; + if (desc->ctrl & CL_DESC_FIRST) { + /* TODO size of priv data if present in + * descriptor + */ + u16 size = 0; + mbuf->pkt_len = CL_DESC_BUF_LEN(desc->ctrl) + - PFE_PKT_HEADER_SZ - size; + mbuf->data_len = mbuf->pkt_len; + mbuf->port = queue->port_id; +#ifdef RTE_LIBRTE_PPFE_SW_PARSE + pfe_sw_parse_pkt(mbuf); +#else + parse_res = (struct ppfe_parse *)(desc->data + + PFE_HIF_SIZE); + mbuf->packet_type = parse_res->packet_type; +#endif + mbuf->nb_segs = 1; + first_mbuf = mbuf; + rx_pkts[i++] = first_mbuf; + } else { + mbuf->data_len = CL_DESC_BUF_LEN(desc->ctrl); + mbuf->data_off = mbuf->data_off - + PFE_PKT_HEADER_SZ; + first_mbuf->pkt_len += mbuf->data_len; + first_mbuf->nb_segs++; + p_mbuf->next = mbuf; + } + stats->ibytes += mbuf->data_len; + p_mbuf = mbuf; + + if (desc->ctrl & CL_DESC_LAST) + wait_for_last = 0; + else + wait_for_last = 1; + /* + * Needed so we don't free a buffer/page + * twice on module_exit + */ + desc->data = NULL; + + /* + * Ensure everything else is written to DDR before + * writing bd->ctrl + */ + rte_wmb(); + + desc->ctrl = CL_DESC_OWN; + queue->read_idx = (queue->read_idx + 1) & + (queue->size - 1); + } while (wait_for_last); + } + stats->ipackets += i; + return i; +} + +static inline void +hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int + client_id, unsigned int qno, + u32 client_ctrl) +{ + /* Optimize the write since the destinaton may be non-cacheable */ + if (!((unsigned long)pkt_hdr & 0x3)) { + ((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) | + client_id; + } else { + ((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF); + ((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF); + } +} + +/*This function puts the given packet in the specific client queue */ +void +hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, + void *data, void *data1, unsigned int len, + u32 client_ctrl, unsigned int flags, void *client_data) +{ + struct hif_client_tx_queue *queue = &client->tx_q[qno]; + struct tx_queue_desc *desc = queue->base + queue->write_idx; + + /* First buffer */ + if (flags & HIF_FIRST_BUFFER) { + data1 -= PFE_HIF_SIZE; + data -= PFE_HIF_SIZE; + len += PFE_HIF_SIZE; + + hif_hdr_write(data1, client->id, qno, client_ctrl); + } + + desc->data = client_data; + desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags); + + hif_xmit_pkt(&client->pfe->hif, client->id, qno, data, len, flags); + + queue->write_idx = (queue->write_idx + 1) & (queue->size - 1); + + queue->tx_pending++; +} + void * hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, unsigned int *flags, __rte_unused int count) diff --git a/drivers/net/ppfe/pfe_hif_lib.h b/drivers/net/ppfe/pfe_hif_lib.h index 03e492559..7c3cdaaa5 100644 --- a/drivers/net/ppfe/pfe_hif_lib.h +++ b/drivers/net/ppfe/pfe_hif_lib.h @@ -162,6 +162,9 @@ int pfe_hif_lib_init(struct pfe *pfe); void pfe_hif_lib_exit(struct pfe *pfe); int hif_lib_client_register(struct hif_client_s *client); int hif_lib_client_unregister(struct hif_client_s *client); +void hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, + void *data, void *data1, unsigned int len, + u32 client_ctrl, unsigned int flags, void *client_data); void hif_lib_indicate_client(struct hif_client_s *client, int event, int data); int hif_lib_event_handler_start(struct hif_client_s *client, int event, int data); @@ -170,4 +173,9 @@ void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, int pfe_hif_shm_init(struct hif_shm *hif_shm, struct rte_mempool *mb_pool); void pfe_hif_shm_clean(struct hif_shm *hif_shm); +int hif_lib_receive_pkt(struct hif_client_rx_queue *queue, + struct rte_mempool *pool, + struct rte_mbuf **rx_pkts, + uint16_t nb_pkts); + #endif /* _PFE_HIF_LIB_H_ */ diff --git a/drivers/net/ppfe/pfe_mod.h b/drivers/net/ppfe/pfe_mod.h index 24b9ebd1e..475c0566c 100644 --- a/drivers/net/ppfe/pfe_mod.h +++ b/drivers/net/ppfe/pfe_mod.h @@ -7,6 +7,8 @@ struct pfe; +#include + #include "pfe.h" #include "pfe_hif.h" #include "pfe_hif_lib.h" diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 4619a9d28..8ed40c261 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -2,6 +2,7 @@ * Copyright 2019 NXP */ +#include #include #include #include @@ -137,6 +138,119 @@ pfe_eth_event_handler(void *data, int event, __rte_unused int qno) return 0; } +static uint16_t +pfe_recv_pkts_on_intr(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +{ + struct hif_client_rx_queue *queue = rxq; + struct pfe_eth_priv_s *priv = queue->priv; + struct epoll_event epoll_ev; + uint64_t ticks = 1; /* 1 msec */ + int ret; + int have_something, work_done; + +#define RESET_STATUS (HIF_INT | HIF_RXPKT_INT) + + /*TODO can we remove this cleanup from here?*/ + pfe_tx_do_cleanup(priv->pfe); + have_something = pfe_hif_rx_process(priv->pfe, nb_pkts); + work_done = hif_lib_receive_pkt(rxq, priv->pfe->hif.shm->pool, + rx_pkts, nb_pkts); + + if (!have_something || !work_done) { + writel(RESET_STATUS, HIF_INT_SRC); + writel(readl(HIF_INT_ENABLE) | HIF_RXPKT_INT, HIF_INT_ENABLE); + ret = epoll_wait(priv->pfe->hif.epoll_fd, &epoll_ev, 1, ticks); + if (ret < 0 && errno != EINTR) + PFE_PMD_ERR("epoll_wait fails with %d\n", errno); + } + + return work_done; +} + +static uint16_t +pfe_recv_pkts(void *rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) +{ + struct hif_client_rx_queue *queue = rxq; + struct pfe_eth_priv_s *priv = queue->priv; + struct rte_mempool *pool; + + /*TODO can we remove this cleanup from here?*/ + pfe_tx_do_cleanup(priv->pfe); + pfe_hif_rx_process(priv->pfe, nb_pkts); + pool = priv->pfe->hif.shm->pool; + + return hif_lib_receive_pkt(rxq, pool, rx_pkts, nb_pkts); +} + +static uint16_t +pfe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) +{ + struct hif_client_tx_queue *queue = tx_queue; + struct pfe_eth_priv_s *priv = queue->priv; + struct rte_eth_stats *stats = &priv->stats; + int i; + + for (i = 0; i < nb_pkts; i++) { + if (tx_pkts[i]->nb_segs > 1) { + struct rte_mbuf *mbuf; + int j; + + hif_lib_xmit_pkt(&priv->client, queue->queue_id, + (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), + tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, + tx_pkts[i]->data_len, 0x0, HIF_FIRST_BUFFER, + tx_pkts[i]); + + mbuf = tx_pkts[i]->next; + for (j = 0; j < (tx_pkts[i]->nb_segs - 2); j++) { + hif_lib_xmit_pkt(&priv->client, queue->queue_id, + (void *)(size_t)rte_pktmbuf_iova(mbuf), + mbuf->buf_addr + mbuf->data_off, + mbuf->data_len, + 0x0, 0x0, mbuf); + mbuf = mbuf->next; + } + + hif_lib_xmit_pkt(&priv->client, queue->queue_id, + (void *)(size_t)rte_pktmbuf_iova(mbuf), + mbuf->buf_addr + mbuf->data_off, + mbuf->data_len, + 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID, + mbuf); + } else { + hif_lib_xmit_pkt(&priv->client, queue->queue_id, + (void *)(size_t)rte_pktmbuf_iova(tx_pkts[i]), + tx_pkts[i]->buf_addr + tx_pkts[i]->data_off, + tx_pkts[i]->pkt_len, 0 /*ctrl*/, + HIF_FIRST_BUFFER | HIF_LAST_BUFFER | + HIF_DATA_VALID, + tx_pkts[i]); + } + stats->obytes += tx_pkts[i]->pkt_len; + hif_tx_dma_start(); + } + stats->opackets += nb_pkts; + pfe_tx_do_cleanup(priv->pfe); + + return nb_pkts; +} + +static uint16_t +pfe_dummy_xmit_pkts(__rte_unused void *tx_queue, + __rte_unused struct rte_mbuf **tx_pkts, + __rte_unused uint16_t nb_pkts) +{ + return 0; +} + +static uint16_t +pfe_dummy_recv_pkts(__rte_unused void *rxq, + __rte_unused struct rte_mbuf **rx_pkts, + __rte_unused uint16_t nb_pkts) +{ + return 0; +} + static int pfe_eth_open(struct rte_eth_dev *dev) { @@ -174,6 +288,21 @@ pfe_eth_open(struct rte_eth_dev *dev) " failed", client->id); goto err0; } + } else { + /* Freeing the packets if already exists */ + int ret = 0; + struct rte_mbuf *rx_pkts[32]; + /* TODO multiqueue support */ + ret = hif_lib_receive_pkt(&client->rx_q[0], + hif_shm->pool, rx_pkts, 32); + while (ret) { + int i; + for (i = 0; i < ret; i++) + rte_pktmbuf_free(rx_pkts[i]); + ret = hif_lib_receive_pkt(&client->rx_q[0], + hif_shm->pool, + rx_pkts, 32); + } } } else { /* Register client driver with HIF */ @@ -197,6 +326,14 @@ pfe_eth_open(struct rte_eth_dev *dev) } } rc = pfe_eth_start(priv); + dev->rx_pkt_burst = &pfe_recv_pkts; + dev->tx_pkt_burst = &pfe_xmit_pkts; + /* If no prefetch is configured. */ + if (getenv("PPFE_INTR_SUPPORT")) { + dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; + PFE_PMD_INFO("PPFE INTERRUPT Mode enabled"); + } + err0: return rc; @@ -243,6 +380,9 @@ pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/) gemac_disable(priv->EMAC_baseaddr); gpi_disable(priv->GPI_baseaddr); + + dev->rx_pkt_burst = &pfe_dummy_recv_pkts; + dev->tx_pkt_burst = &pfe_dummy_xmit_pkts; } static void From patchwork Tue Oct 1 11:02:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60321 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 51D931BEC6; Tue, 1 Oct 2019 13:17:47 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 9C1D21BE84 for ; Tue, 1 Oct 2019 13:17:36 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 7D5491A02BC; Tue, 1 Oct 2019 13:17:36 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 510801A0096; Tue, 1 Oct 2019 13:17:34 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id C6E9E4030D; Tue, 1 Oct 2019 19:17:30 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:32:05 +0530 Message-Id: <20191001110209.6047-11-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 10/14] net/ppfe: add supported packet types and basic statistics X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add support for supported packet types by the platform andbasic statistics like numbers of packets/bytes receive and transmit. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- doc/guides/nics/features/ppfe.ini | 2 ++ doc/guides/nics/ppfe.rst | 2 ++ drivers/net/ppfe/ppfe_ethdev.c | 43 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/doc/guides/nics/features/ppfe.ini b/doc/guides/nics/features/ppfe.ini index 4e38ffd24..9184539c1 100644 --- a/doc/guides/nics/features/ppfe.ini +++ b/doc/guides/nics/features/ppfe.ini @@ -6,6 +6,8 @@ [Features] L3 checksum offload = Y L4 checksum offload = Y +Packet type parsing = Y +Basic stats = Y Linux VFIO = Y ARMv8 = Y Usage doc = Y diff --git a/doc/guides/nics/ppfe.rst b/doc/guides/nics/ppfe.rst index c95525e5b..a91585112 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -94,6 +94,8 @@ PPFE Features ~~~~~~~~~~~~~~ - L3/L4 checksum offload +- Packet type parsing +- Basic stats - ARMv8 Supported PPFE SoCs diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 8ed40c261..bf40ee402 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -518,6 +518,47 @@ pfe_tx_queue_setup(struct rte_eth_dev *dev, return 0; } +static const uint32_t * +pfe_supported_ptypes_get(struct rte_eth_dev *dev) +{ + static const uint32_t ptypes[] = { + /*todo -= add more types */ + RTE_PTYPE_L2_ETHER, + RTE_PTYPE_L3_IPV4, + RTE_PTYPE_L3_IPV4_EXT, + RTE_PTYPE_L3_IPV6, + RTE_PTYPE_L3_IPV6_EXT, + RTE_PTYPE_L4_TCP, + RTE_PTYPE_L4_UDP, + RTE_PTYPE_L4_SCTP + }; + + if (dev->rx_pkt_burst == pfe_recv_pkts || + dev->rx_pkt_burst == pfe_recv_pkts_on_intr) + return ptypes; + return NULL; +} + +static int +pfe_stats_get(struct rte_eth_dev *dev, + struct rte_eth_stats *stats) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + struct rte_eth_stats *eth_stats = &priv->stats; + + if (stats == NULL) + return -1; + + memset(stats, 0, sizeof(struct rte_eth_stats)); + + stats->ipackets = eth_stats->ipackets; + stats->ibytes = eth_stats->ibytes; + stats->opackets = eth_stats->opackets; + stats->obytes = eth_stats->obytes; + + return 0; +} + static const struct eth_dev_ops ops = { .dev_start = pfe_eth_open, .dev_stop = pfe_eth_stop, @@ -528,6 +569,8 @@ static const struct eth_dev_ops ops = { .rx_queue_release = pfe_rx_queue_release, .tx_queue_setup = pfe_tx_queue_setup, .tx_queue_release = pfe_tx_queue_release, + .dev_supported_ptypes_get = pfe_supported_ptypes_get, + .stats_get = pfe_stats_get, }; static int From patchwork Tue Oct 1 11:02:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60322 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 11C0D1BECE; Tue, 1 Oct 2019 13:17:49 +0200 (CEST) Received: from inva021.nxp.com (inva021.nxp.com [92.121.34.21]) by dpdk.org (Postfix) with ESMTP id 124031BE8B for ; Tue, 1 Oct 2019 13:17:38 +0200 (CEST) Received: from inva021.nxp.com (localhost [127.0.0.1]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id E141C200540; Tue, 1 Oct 2019 13:17:37 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva021.eu-rdc02.nxp.com (Postfix) with ESMTP id 7B2FA2001C2; Tue, 1 Oct 2019 13:17:35 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id EFBE540313; Tue, 1 Oct 2019 19:17:31 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:32:06 +0530 Message-Id: <20191001110209.6047-12-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 11/14] net/ppfe: add MTU and MAC address set operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" To update MAC address or MTU, operations are added to the driver. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/ppfe_ethdev.c | 63 +++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/doc/guides/nics/features/ppfe.ini b/doc/guides/nics/features/ppfe.ini index 9184539c1..e0406a97f 100644 --- a/doc/guides/nics/features/ppfe.ini +++ b/doc/guides/nics/features/ppfe.ini @@ -8,6 +8,7 @@ L3 checksum offload = Y L4 checksum offload = Y Packet type parsing = Y Basic stats = Y +MTU update = Y Linux VFIO = Y ARMv8 = Y Usage doc = Y diff --git a/doc/guides/nics/ppfe.rst b/doc/guides/nics/ppfe.rst index a91585112..1ab0a5859 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -96,6 +96,7 @@ PPFE Features - L3/L4 checksum offload - Packet type parsing - Basic stats +- MTU update - ARMv8 Supported PPFE SoCs diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index bf40ee402..0097454c9 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "pfe_logs.h" @@ -539,6 +540,59 @@ pfe_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } +static int +pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) +{ + int ret; + struct pfe_eth_priv_s *priv = dev->data->dev_private; + uint16_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; + + /*TODO Support VLAN*/ + ret = gemac_set_rx(priv->EMAC_baseaddr, frame_size); + if (!ret) + dev->data->mtu = mtu; + + return ret; +} + +/* pfe_eth_enet_addr_byte_mac + */ +static int +pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, + struct pfe_mac_addr *enet_addr) +{ + if (!enet_byte_addr || !enet_addr) { + return -1; + + } else { + enet_addr->bottom = enet_byte_addr[0] | + (enet_byte_addr[1] << 8) | + (enet_byte_addr[2] << 16) | + (enet_byte_addr[3] << 24); + enet_addr->top = enet_byte_addr[4] | + (enet_byte_addr[5] << 8); + return 0; + } +} + +static int +pfe_dev_set_mac_addr(struct rte_eth_dev *dev, + struct rte_ether_addr *addr) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + struct pfe_mac_addr spec_addr; + int ret; + + ret = pfe_eth_enet_addr_byte_mac(addr->addr_bytes, &spec_addr); + if (ret) + return ret; + + gemac_set_laddrN(priv->EMAC_baseaddr, + (struct pfe_mac_addr *)&spec_addr, 1); + rte_ether_addr_copy(addr, &dev->data->mac_addrs[0]); + return 0; +} + static int pfe_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) @@ -570,6 +624,8 @@ static const struct eth_dev_ops ops = { .tx_queue_setup = pfe_tx_queue_setup, .tx_queue_release = pfe_tx_queue_release, .dev_supported_ptypes_get = pfe_supported_ptypes_get, + .mtu_set = pfe_mtu_set, + .mac_addr_set = pfe_dev_set_mac_addr, .stats_get = pfe_stats_get, }; @@ -580,6 +636,7 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) struct pfe_eth_priv_s *priv = NULL; struct ls1012a_eth_platform_data *einfo; struct ls1012a_pfe_platform_data *pfe_info; + struct rte_ether_addr addr; int err; eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); @@ -632,6 +689,12 @@ pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) goto err0; } + memcpy(addr.addr_bytes, priv->einfo->mac_addr, + ETH_ALEN); + + pfe_dev_set_mac_addr(eth_dev, &addr); + rte_ether_addr_copy(&addr, ð_dev->data->mac_addrs[0]); + eth_dev->data->mtu = 1500; eth_dev->dev_ops = &ops; pfe_eth_stop(eth_dev); From patchwork Tue Oct 1 11:02:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60323 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C79B41BED7; Tue, 1 Oct 2019 13:17:50 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id DB9211BE8B for ; Tue, 1 Oct 2019 13:17:38 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id BD91A1A01DE; Tue, 1 Oct 2019 13:17:38 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 91CFF1A0096; Tue, 1 Oct 2019 13:17:36 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 2280C402C7; Tue, 1 Oct 2019 19:17:33 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:32:07 +0530 Message-Id: <20191001110209.6047-13-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 12/14] net/ppfe: add allmulticast and promiscuous X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch adds support to enable multicast and promiscuous mode. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- doc/guides/nics/features/ppfe.ini | 2 ++ doc/guides/nics/ppfe.rst | 2 ++ drivers/net/ppfe/ppfe_ethdev.c | 42 +++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/doc/guides/nics/features/ppfe.ini b/doc/guides/nics/features/ppfe.ini index e0406a97f..562c5548f 100644 --- a/doc/guides/nics/features/ppfe.ini +++ b/doc/guides/nics/features/ppfe.ini @@ -9,6 +9,8 @@ L4 checksum offload = Y Packet type parsing = Y Basic stats = Y MTU update = Y +Promiscuous mode = Y +Allmulticast mode = Y Linux VFIO = Y ARMv8 = Y Usage doc = Y diff --git a/doc/guides/nics/ppfe.rst b/doc/guides/nics/ppfe.rst index 1ab0a5859..5b37bb8c3 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -97,6 +97,8 @@ PPFE Features - Packet type parsing - Basic stats - MTU update +- Promiscuous mode +- Allmulticast mode - ARMv8 Supported PPFE SoCs diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 0097454c9..2b24b895a 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -540,6 +540,45 @@ pfe_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } +static int +pfe_promiscuous_enable(struct rte_eth_dev *dev) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + + priv->promisc = 1; + dev->data->promiscuous = 1; + gemac_enable_copy_all(priv->EMAC_baseaddr); + + return 0; +} + +static int +pfe_promiscuous_disable(struct rte_eth_dev *dev) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + + priv->promisc = 0; + dev->data->promiscuous = 0; + gemac_disable_copy_all(priv->EMAC_baseaddr); + + return 0; +} + +static int +pfe_allmulticast_enable(struct rte_eth_dev *dev) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + struct pfe_mac_addr hash_addr; /* hash register structure */ + + /* Set the hash to rx all multicast frames */ + hash_addr.bottom = 0xFFFFFFFF; + hash_addr.top = 0xFFFFFFFF; + gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); + dev->data->all_multicast = 1; + + return 0; +} + static int pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { @@ -624,6 +663,9 @@ static const struct eth_dev_ops ops = { .tx_queue_setup = pfe_tx_queue_setup, .tx_queue_release = pfe_tx_queue_release, .dev_supported_ptypes_get = pfe_supported_ptypes_get, + .promiscuous_enable = pfe_promiscuous_enable, + .promiscuous_disable = pfe_promiscuous_disable, + .allmulticast_enable = pfe_allmulticast_enable, .mtu_set = pfe_mtu_set, .mac_addr_set = pfe_dev_set_mac_addr, .stats_get = pfe_stats_get, From patchwork Tue Oct 1 11:02:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60324 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D3E051BEE0; Tue, 1 Oct 2019 13:17:52 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 379E71BEA1 for ; Tue, 1 Oct 2019 13:17:40 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 18EE71A02BC; Tue, 1 Oct 2019 13:17:40 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id B1F4B1A053F; Tue, 1 Oct 2019 13:17:37 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 3F3254029A; Tue, 1 Oct 2019 19:17:34 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:32:08 +0530 Message-Id: <20191001110209.6047-14-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add link related operations like link update, up and down. Signed-off-by: Gagandeep Singh Acked-by: Nipun Gupta Acked-by: Akhil Goyal --- doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/ppfe_ethdev.c | 106 ++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/doc/guides/nics/features/ppfe.ini b/doc/guides/nics/features/ppfe.ini index 562c5548f..4f1836633 100644 --- a/doc/guides/nics/features/ppfe.ini +++ b/doc/guides/nics/features/ppfe.ini @@ -4,6 +4,7 @@ ; Refer to default.ini for the full list of available PMD features. ; [Features] +Link status = Y L3 checksum offload = Y L4 checksum offload = Y Packet type parsing = Y diff --git a/doc/guides/nics/ppfe.rst b/doc/guides/nics/ppfe.rst index 5b37bb8c3..d6c86d84d 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -99,6 +99,7 @@ PPFE Features - MTU update - Promiscuous mode - Allmulticast mode +- Link status - ARMv8 Supported PPFE SoCs diff --git a/drivers/net/ppfe/ppfe_ethdev.c b/drivers/net/ppfe/ppfe_ethdev.c index 2b24b895a..d636cae53 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -2,6 +2,8 @@ * Copyright 2019 NXP */ +#include +#include #include #include #include @@ -540,6 +542,91 @@ pfe_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } +static inline int +pfe_eth_atomic_read_link_status(struct rte_eth_dev *dev, + struct rte_eth_link *link) +{ + struct rte_eth_link *dst = link; + struct rte_eth_link *src = &dev->data->dev_link; + + if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, + *(uint64_t *)src) == 0) + return -1; + + return 0; +} + +static inline int +pfe_eth_atomic_write_link_status(struct rte_eth_dev *dev, + struct rte_eth_link *link) +{ + struct rte_eth_link *dst = &dev->data->dev_link; + struct rte_eth_link *src = link; + + if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst, + *(uint64_t *)src) == 0) + return -1; + + return 0; +} + +static int +pfe_eth_link_update(struct rte_eth_dev *dev, + int wait_to_complete __rte_unused) +{ + int ret, ioctl_cmd = 0; + struct pfe_eth_priv_s *priv = dev->data->dev_private; + struct rte_eth_link link, old; + unsigned int lstatus = 1; + + if (dev == NULL) { + PFE_PMD_ERR("Invalid device in link_update.\n"); + return 0; + } + + memset(&old, 0, sizeof(old)); + memset(&link, 0, sizeof(struct rte_eth_link)); + + pfe_eth_atomic_read_link_status(dev, &old); + + /* Read from PFE CDEV, status of link, if file was successfully + * opened. + */ + if (priv->link_fd != PFE_CDEV_INVALID_FD) { + if (priv->id == 0) + ioctl_cmd = PFE_CDEV_ETH0_STATE_GET; + if (priv->id == 1) + ioctl_cmd = PFE_CDEV_ETH1_STATE_GET; + + ret = ioctl(priv->link_fd, ioctl_cmd, &lstatus); + if (ret != 0) { + PFE_PMD_ERR("Unable to fetch link status (ioctl)\n"); + /* use dummy link value */ + link.link_status = 1; + } + PFE_PMD_DEBUG("Fetched link state (%d) for dev %d.\n", + lstatus, priv->id); + } + + if (old.link_status == lstatus) { + /* no change in status */ + PFE_PMD_DEBUG("No change in link status; Not updating.\n"); + return -1; + } + + link.link_status = lstatus; + link.link_speed = ETH_LINK_SPEED_1G; + link.link_duplex = ETH_LINK_FULL_DUPLEX; + link.link_autoneg = ETH_LINK_AUTONEG; + + pfe_eth_atomic_write_link_status(dev, &link); + + PFE_PMD_INFO("Port (%d) link is %s\n", dev->data->port_id, + link.link_status ? "up" : "down"); + + return 0; +} + static int pfe_promiscuous_enable(struct rte_eth_dev *dev) { @@ -579,6 +666,22 @@ pfe_allmulticast_enable(struct rte_eth_dev *dev) return 0; } +static int +pfe_link_down(struct rte_eth_dev *dev) +{ + pfe_eth_stop(dev); + return 0; +} + +static int +pfe_link_up(struct rte_eth_dev *dev) +{ + struct pfe_eth_priv_s *priv = dev->data->dev_private; + + pfe_eth_start(priv); + return 0; +} + static int pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { @@ -663,9 +766,12 @@ static const struct eth_dev_ops ops = { .tx_queue_setup = pfe_tx_queue_setup, .tx_queue_release = pfe_tx_queue_release, .dev_supported_ptypes_get = pfe_supported_ptypes_get, + .link_update = pfe_eth_link_update, .promiscuous_enable = pfe_promiscuous_enable, .promiscuous_disable = pfe_promiscuous_disable, .allmulticast_enable = pfe_allmulticast_enable, + .dev_set_link_down = pfe_link_down, + .dev_set_link_up = pfe_link_up, .mtu_set = pfe_mtu_set, .mac_addr_set = pfe_dev_set_mac_addr, .stats_get = pfe_stats_get, From patchwork Tue Oct 1 11:02:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gagandeep Singh X-Patchwork-Id: 60325 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 1FAE71BEE7; Tue, 1 Oct 2019 13:17:54 +0200 (CEST) Received: from inva020.nxp.com (inva020.nxp.com [92.121.34.13]) by dpdk.org (Postfix) with ESMTP id 3A7361BEA7 for ; Tue, 1 Oct 2019 13:17:41 +0200 (CEST) Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 1C3271A01DE; Tue, 1 Oct 2019 13:17:41 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id E47AC1A0096; Tue, 1 Oct 2019 13:17:38 +0200 (CEST) Received: from GDB1.ap.freescale.net (GDB1.ap.freescale.net [10.232.132.179]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 5FA21402DA; Tue, 1 Oct 2019 19:17:35 +0800 (SGT) From: Gagandeep Singh To: dev@dpdk.org, ferruh.yigit@intel.com Cc: thomas@monjalon.net, Gagandeep Singh Date: Tue, 1 Oct 2019 16:32:09 +0530 Message-Id: <20191001110209.6047-15-g.singh@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191001110209.6047-1-g.singh@nxp.com> References: <20190826130246.30485-1-g.singh@nxp.com> <20191001110209.6047-1-g.singh@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Subject: [dpdk-dev] [PATCH v3 14/14] doc: add NXP PPFE PMD in release notes X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Update release notes for NXP PPFE driver supported for 19.11. Signed-off-by: Gagandeep Singh --- doc/guides/rel_notes/release_19_11.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index cd4e35061..9ec268e90 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -88,6 +88,11 @@ New Features Added support for the ``RTE_ETH_DEV_CLOSE_REMOVE`` flag. +* **Added NXP PPFE PMD.** + + Added the new PPFE driver for the NXP LS1012A platform. See the + :doc:`../nics/ppfe` NIC driver guide for more details on this new driver. + Removed Items -------------