* [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD @ 2019-08-26 13:02 Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh ` (15 more replies) 0 siblings, 16 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This series introduces ppfe (programmable packet forwarding engine) network poll mode driver for NXP SoC ls1012a. First patch of this series move OF library code from dpaa bus to a common folder as PPFE also uses the same library for getting information from the device tree. This patch is included in this series so that compilation by CI don't break. Gagandeep Singh (12): net/ppfe: introduce ppfe net poll mode driver doc: add guide for ppfe net PMD net/ppfe: support dynamic logging net/ppfe: add HW specific macros and operations net/ppfe: add MAC and host interface initialisation net/ppfe: add device start stop operations net/ppfe: add queue setup and release operations net/ppfe: add burst enqueue and dequeue operations net/ppfe: add supported packet types and basic statistics net/ppfe: add MTU and MAC address set operations net/ppfe: add allmulticast and promiscuous net/ppfe: add link status update Hemant Agrawal (1): common/dpaax: moving OF lib code from dpaa bus MAINTAINERS | 7 + config/common_base | 5 + config/common_linux | 5 + doc/guides/nics/features/ppfe.ini | 17 + doc/guides/nics/index.rst | 1 + doc/guides/nics/ppfe.rst | 175 +++ drivers/bus/dpaa/Makefile | 2 +- drivers/bus/dpaa/base/qbman/dpaa_sys.h | 1 + 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 drivers/common/dpaax/dpaax_logs.h | 10 + drivers/common/dpaax/meson.build | 5 +- .../{bus/dpaa/base/fman => common/dpaax}/of.c | 61 +- .../{bus/dpaa/include => common/dpaax}/of.h | 27 +- .../common/dpaax/rte_common_dpaax_version.map | 18 + drivers/crypto/caam_jr/Makefile | 2 + drivers/crypto/dpaa2_sec/Makefile | 2 +- drivers/crypto/dpaa_sec/Makefile | 1 + drivers/event/dpaa/Makefile | 1 + drivers/event/dpaa2/Makefile | 1 + drivers/mempool/dpaa/Makefile | 1 + drivers/mempool/dpaa2/Makefile | 1 + drivers/net/Makefile | 1 + drivers/net/dpaa/Makefile | 1 + drivers/net/dpaa2/Makefile | 1 + drivers/net/meson.build | 1 + drivers/net/ppfe/Makefile | 36 + 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 | 422 ++++++ drivers/net/ppfe/meson.build | 16 + drivers/net/ppfe/pfe_eth.h | 78 ++ drivers/net/ppfe/pfe_hal.c | 597 +++++++++ drivers/net/ppfe/pfe_hif.c | 857 ++++++++++++ drivers/net/ppfe/pfe_hif.h | 156 +++ drivers/net/ppfe/pfe_hif_lib.c | 557 ++++++++ drivers/net/ppfe/pfe_hif_lib.h | 181 +++ drivers/net/ppfe/pfe_logs.h | 30 + drivers/net/ppfe/pfe_mod.h | 59 + drivers/net/ppfe/ppfe_ethdev.c | 1182 +++++++++++++++++ drivers/net/ppfe/rte_pmd_ppfe_version.map | 4 + drivers/raw/dpaa2_cmdif/Makefile | 1 + drivers/raw/dpaa2_qdma/Makefile | 1 + mk/rte.app.mk | 1 + 58 files changed, 5513 insertions(+), 46 deletions(-) create mode 100644 doc/guides/nics/features/ppfe.ini create mode 100644 doc/guides/nics/ppfe.rst rename drivers/{bus/dpaa/include => common/dpaax}/dpaa_list.h (100%) rename drivers/{bus/dpaa/base/fman => common/dpaax}/of.c (88%) rename drivers/{bus/dpaa/include => common/dpaax}/of.h (86%) create mode 100644 drivers/net/ppfe/Makefile 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 create mode 100644 drivers/net/ppfe/meson.build create mode 100644 drivers/net/ppfe/pfe_eth.h 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 create mode 100644 drivers/net/ppfe/pfe_logs.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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 01/13] common/dpaax: moving OF lib code from dpaa bus 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh ` (14 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Hemant Agrawal From: Hemant Agrawal <hemant.agrawal@nxp.com> This code is being shared by more than 1 type of driver. Common is most appropriate place for it. Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com> --- drivers/bus/dpaa/Makefile | 2 +- drivers/bus/dpaa/base/qbman/dpaa_sys.h | 1 + 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 drivers/common/dpaax/dpaax_logs.h | 10 +++ drivers/common/dpaax/meson.build | 5 +- .../{bus/dpaa/base/fman => common/dpaax}/of.c | 61 ++++++++++--------- .../{bus/dpaa/include => common/dpaax}/of.h | 27 ++++++-- .../common/dpaax/rte_common_dpaax_version.map | 18 ++++++ drivers/crypto/caam_jr/Makefile | 2 + drivers/crypto/dpaa2_sec/Makefile | 2 +- drivers/crypto/dpaa_sec/Makefile | 1 + 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/dpaa2/Makefile | 1 + drivers/raw/dpaa2_cmdif/Makefile | 1 + drivers/raw/dpaa2_qdma/Makefile | 1 + 27 files changed, 110 insertions(+), 46 deletions(-) rename drivers/{bus/dpaa/include => common/dpaax}/dpaa_list.h (100%) rename drivers/{bus/dpaa/base/fman => common/dpaax}/of.c (88%) rename drivers/{bus/dpaa/include => common/dpaax}/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/qbman/dpaa_sys.h b/drivers/bus/dpaa/base/qbman/dpaa_sys.h index 034991ba1..e86a480b7 100644 --- a/drivers/bus/dpaa/base/qbman/dpaa_sys.h +++ b/drivers/bus/dpaa/base/qbman/dpaa_sys.h @@ -8,6 +8,7 @@ #ifndef __DPAA_SYS_H #define __DPAA_SYS_H +#include <compat.h> #include <of.h> /* For 2-element tables related to cache-inhibited and cache-enabled mappings */ diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c index 07cc5c667..8770c3a11 100644 --- a/drivers/bus/dpaa/dpaa_bus.c +++ b/drivers/bus/dpaa/dpaa_bus.c @@ -32,6 +32,7 @@ #include <rte_bus.h> #include <rte_mbuf_pool_ops.h> +#include <of.h> #include <rte_dpaa_bus.h> #include <rte_dpaa_logs.h> #include <dpaax_iova_table.h> @@ -39,7 +40,6 @@ #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> 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 <dpaa_list.h> #include <dpaa_bits.h> #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 <rte_ether.h> #include <compat.h> +#include <dpaa_list.h> #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 <compat.h> +#include <dpaa_list.h> #include <fsl_qman.h> #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..19e30069d 100644 --- a/drivers/bus/dpaa/rte_dpaa_bus.h +++ b/drivers/bus/dpaa/rte_dpaa_bus.h @@ -10,10 +10,10 @@ #include <rte_mempool.h> #include <dpaax_iova_table.h> +#include <of.h> #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> #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..f725d93d4 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 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/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..795cc84b9 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', 'of.c') cflags += ['-D_GNU_SOURCE'] +if cc.has_argument('-Wno-cast-qual') + cflags += '-Wno-cast-qual' +endif diff --git a/drivers/bus/dpaa/base/fman/of.c b/drivers/common/dpaax/of.c similarity index 88% rename from drivers/bus/dpaa/base/fman/of.c rename to drivers/common/dpaax/of.c index 1e97be54e..b713bfd54 100644 --- a/drivers/bus/dpaa/base/fman/of.c +++ b/drivers/common/dpaax/of.c @@ -6,8 +6,9 @@ */ #include <of.h> +#include <assert.h> #include <rte_string_fns.h> -#include <rte_dpaa_logs.h> +#include <dpaax_logs.h> 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/of.h similarity index 86% rename from drivers/bus/dpaa/include/of.h rename to drivers/common/dpaax/of.h index 7ea7608fc..e9761ce0e 100644 --- a/drivers/bus/dpaa/include/of.h +++ b/drivers/common/dpaax/of.h @@ -8,7 +8,24 @@ #ifndef __OF_H #define __OF_H -#include <compat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <stdlib.h> +#include <inttypes.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> +#include <fcntl.h> +#include <glob.h> +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <limits.h> +#include <inttypes.h> +#include <rte_common.h> +#include <dpaa_list.h> #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/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/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/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/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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-10-28 17:18 ` Stephen Hemminger 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 03/13] doc: add guide for ppfe net PMD Gagandeep Singh ` (13 subsequent siblings) 15 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal 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 <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- MAINTAINERS | 6 + config/common_base | 5 + config/common_linux | 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 | 77 +++++ drivers/net/ppfe/pfe_mod.h | 51 ++++ drivers/net/ppfe/ppfe_ethdev.c | 329 ++++++++++++++++++++++ drivers/net/ppfe/rte_pmd_ppfe_version.map | 4 + mk/rte.app.mk | 1 + 13 files changed, 527 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 410026086..7996dcdd8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -781,6 +781,12 @@ F: drivers/net/enetc/ F: doc/guides/nics/enetc.rst F: doc/guides/nics/features/enetc.ini +NXP ppfe +M: Gagandeep Singh <g.singh@nxp.com> +M: Akhil Goyal <akhil.goyal@nxp.com> +F: drivers/net/ppfe/ +F: doc/guides/nics/features/ppfe.ini + QLogic bnx2x M: Rasesh Mody <rmody@marvell.com> M: Shahed Shaikh <shshaikh@marvell.com> diff --git a/config/common_base b/config/common_base index 8ef75c203..1776a8fa8 100644 --- a/config/common_base +++ b/config/common_base @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n CONFIG_RTE_LIBRTE_CXGBE_TPUT=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/config/common_linux b/config/common_linux index 6e252553a..2ba70ba95 100644 --- a/config/common_linux +++ b/config/common_linux @@ -59,6 +59,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y # CONFIG_RTE_LIBRTE_ENETC_PMD=y +# +# NXP PPFE PMD Driver +# +CONFIG_RTE_LIBRTE_PPFE_PMD=y + # # HINIC PMD driver # 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 5767fdf65..b59cdbb83 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -49,6 +49,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 513f19b33..a3be718a6 100644 --- a/drivers/net/meson.build +++ b/drivers/net/meson.build @@ -37,6 +37,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..a8ce3e314 --- /dev/null +++ b/drivers/net/ppfe/pfe_eth.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_ETH_H_ +#define _PFE_ETH_H_ + +#include <compat.h> +#include <rte_ethdev.h> +#include <rte_ethdev_vdev.h> + +#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; +}; + +struct pfe_eth { + struct pfe_eth_priv_s *eth_priv[3]; +}; + +#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..61db998e5 --- /dev/null +++ b/drivers/net/ppfe/pfe_mod.h @@ -0,0 +1,51 @@ +/* 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 + +struct pfe { + uint64_t ddr_phys_baseaddr; + void *ddr_baseaddr; + uint64_t ddr_size; + void *cbus_baseaddr; + struct pfe_eth eth; + int mdio_muxval[PHYID_MAX_VAL]; + uint8_t nb_devs; + uint8_t max_intf; + int cdev_fd; +}; + +/* for link status and IOCTL support using pfe character device + * XXX: Should be kept in sync with Kernel module + */ + +/* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are + * supported by PFE driver. Should be updated if number of eth devices are + * changed. + */ +#define PFE_CDEV_ETH_COUNT 3 + +#define PFE_CDEV_PATH "/dev/pfe_us_cdev" +#define PFE_CDEV_INVALID_FD -1 + +/* 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 */ +}; + +/* 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..f31a11b93 --- /dev/null +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -0,0 +1,329 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include <rte_kvargs.h> +#include <rte_ethdev_vdev.h> +#include <rte_bus_vdev.h> +#include <of.h> + +#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; +}; +struct pfe *g_pfe; +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; + } +} + +/* pfe_eth_exit + */ +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_eth_dev_release_port(dev); + pfe->nb_devs--; +} + +/* pfe_eth_init_one + */ +static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) +{ + struct rte_eth_dev_data *data = NULL; + struct rte_eth_dev *eth_dev = NULL; + struct pfe_eth_priv_s *priv = NULL; + int err; + + if (id >= pfe->max_intf) + return -EINVAL; + + data = rte_zmalloc(NULL, sizeof(*data), 64); + if (data == NULL) + return -ENOMEM; + + eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); + if (eth_dev == NULL) { + rte_free(data); + return -ENOMEM; + } + + priv = eth_dev->data->dev_private; + rte_memcpy(data, eth_dev->data, sizeof(*data)); + + 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_free(data); + 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 = (int *)extra_args; + + *i = atoi(value); + if (*i < 0) + return -1; + + 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 (params == NULL) + return -EINVAL; + + + if (input_args) { + 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); + if (ret < 0) + goto free_kvlist; + } + +free_kvlist: + 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 = { + -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), 64); + 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; + + fd = open("/dev/mem", O_RDWR); + g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, cbus_addr); + 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: +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); + + return 0; +} + +static struct rte_vdev_driver pmd_pfe_drv = { + .probe = pmd_pfe_probe, + .remove = pmd_pfe_remove, +}; + +RTE_PMD_REGISTER_VDEV(PFE_PMD, pmd_pfe_drv); +RTE_PMD_REGISTER_ALIAS(PFE_PMD, eth_pfe); +RTE_PMD_REGISTER_PARAM_STRING(PFE_PMD, "intf=<int> "); 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 ba5c39e01..4df36a53c 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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh @ 2019-10-28 17:18 ` Stephen Hemminger 2019-10-29 9:27 ` Ferruh Yigit 0 siblings, 1 reply; 87+ messages in thread From: Stephen Hemminger @ 2019-10-28 17:18 UTC (permalink / raw) To: Gagandeep Singh; +Cc: dev, ferruh.yigit, thomas, Akhil Goyal On Mon, 26 Aug 2019 18:32:35 +0530 Gagandeep Singh <g.singh@nxp.com> wrote: > --- a/config/common_base > +++ b/config/common_base > @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n > CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n > CONFIG_RTE_LIBRTE_CXGBE_TPUT=y > > +# > +# Compile burst-oriented NXP PPFE PMD driver > +# > +CONFIG_RTE_LIBRTE_PPFE_PMD=n This driver should use the common naming convention for Poll Mode Drivers. s/CONFIG_RTE_LIBRTE_PPFE_PMD/CONFIG_RTE_LIBRTE_PMD_PPFE/ ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-10-28 17:18 ` Stephen Hemminger @ 2019-10-29 9:27 ` Ferruh Yigit 2019-11-04 11:06 ` Bruce Richardson 0 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-10-29 9:27 UTC (permalink / raw) To: Stephen Hemminger, Gagandeep Singh; +Cc: dev, thomas, Akhil Goyal On 10/28/2019 5:18 PM, Stephen Hemminger wrote: > On Mon, 26 Aug 2019 18:32:35 +0530 > Gagandeep Singh <g.singh@nxp.com> wrote: > >> --- a/config/common_base >> +++ b/config/common_base >> @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n >> CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n >> CONFIG_RTE_LIBRTE_CXGBE_TPUT=y >> >> +# >> +# Compile burst-oriented NXP PPFE PMD driver >> +# >> +CONFIG_RTE_LIBRTE_PPFE_PMD=n > > This driver should use the common naming convention for Poll Mode Drivers. > > s/CONFIG_RTE_LIBRTE_PPFE_PMD/CONFIG_RTE_LIBRTE_PMD_PPFE/ > Unfortunately we have both as naming convention, and *unintentionally* it become virtual ones PMD_XXXX (PMD_RING), physical ones (IXGBE_PMD), although this PMD registers itself as virtual, it is a physical PMD and I think exiting config option is good (PPFE_PMD). We can update config names to be consistent but not sure if it worth it, changing name for users/costumers which may break their scripts, automation etc. taking into account that it was like this since beginning, And now we are planning to switch to meson, these config option won't be used directly, so I think we can keep them as they are. ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-10-29 9:27 ` Ferruh Yigit @ 2019-11-04 11:06 ` Bruce Richardson 2019-11-05 16:02 ` Ferruh Yigit 0 siblings, 1 reply; 87+ messages in thread From: Bruce Richardson @ 2019-11-04 11:06 UTC (permalink / raw) To: Ferruh Yigit; +Cc: Stephen Hemminger, Gagandeep Singh, dev, thomas, Akhil Goyal On Tue, Oct 29, 2019 at 09:27:22AM +0000, Ferruh Yigit wrote: > On 10/28/2019 5:18 PM, Stephen Hemminger wrote: > > On Mon, 26 Aug 2019 18:32:35 +0530 > > Gagandeep Singh <g.singh@nxp.com> wrote: > > > >> --- a/config/common_base > >> +++ b/config/common_base > >> @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n > >> CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n > >> CONFIG_RTE_LIBRTE_CXGBE_TPUT=y > >> > >> +# > >> +# Compile burst-oriented NXP PPFE PMD driver > >> +# > >> +CONFIG_RTE_LIBRTE_PPFE_PMD=n > > > > This driver should use the common naming convention for Poll Mode Drivers. > > > > s/CONFIG_RTE_LIBRTE_PPFE_PMD/CONFIG_RTE_LIBRTE_PMD_PPFE/ > > > > Unfortunately we have both as naming convention, and *unintentionally* it become > virtual ones PMD_XXXX (PMD_RING), physical ones (IXGBE_PMD), > although this PMD registers itself as virtual, it is a physical PMD and I think > exiting config option is good (PPFE_PMD). > > We can update config names to be consistent but not sure if it worth it, > changing name for users/costumers which may break their scripts, automation etc. > taking into account that it was like this since beginning, > > And now we are planning to switch to meson, these config option won't be used > directly, so I think we can keep them as they are. ... and the meson default is PMD at the end as for physical PMDs. ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-11-04 11:06 ` Bruce Richardson @ 2019-11-05 16:02 ` Ferruh Yigit 2019-11-06 9:38 ` Bruce Richardson 0 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-11-05 16:02 UTC (permalink / raw) To: Bruce Richardson Cc: Stephen Hemminger, Gagandeep Singh, dev, thomas, Akhil Goyal On 11/4/2019 11:06 AM, Bruce Richardson wrote: > On Tue, Oct 29, 2019 at 09:27:22AM +0000, Ferruh Yigit wrote: >> On 10/28/2019 5:18 PM, Stephen Hemminger wrote: >>> On Mon, 26 Aug 2019 18:32:35 +0530 >>> Gagandeep Singh <g.singh@nxp.com> wrote: >>> >>>> --- a/config/common_base >>>> +++ b/config/common_base >>>> @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n >>>> CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n >>>> CONFIG_RTE_LIBRTE_CXGBE_TPUT=y >>>> >>>> +# >>>> +# Compile burst-oriented NXP PPFE PMD driver >>>> +# >>>> +CONFIG_RTE_LIBRTE_PPFE_PMD=n >>> >>> This driver should use the common naming convention for Poll Mode Drivers. >>> >>> s/CONFIG_RTE_LIBRTE_PPFE_PMD/CONFIG_RTE_LIBRTE_PMD_PPFE/ >>> >> >> Unfortunately we have both as naming convention, and *unintentionally* it become >> virtual ones PMD_XXXX (PMD_RING), physical ones (IXGBE_PMD), >> although this PMD registers itself as virtual, it is a physical PMD and I think >> exiting config option is good (PPFE_PMD). >> >> We can update config names to be consistent but not sure if it worth it, >> changing name for users/costumers which may break their scripts, automation etc. >> taking into account that it was like this since beginning, >> >> And now we are planning to switch to meson, these config option won't be used >> directly, so I think we can keep them as they are. > > ... and the meson default is PMD at the end as for physical PMDs. > Does meson need them? I was thinking these PMD build enable/disable configs will go away with meson. ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-11-05 16:02 ` Ferruh Yigit @ 2019-11-06 9:38 ` Bruce Richardson 2019-11-06 12:22 ` Ferruh Yigit 0 siblings, 1 reply; 87+ messages in thread From: Bruce Richardson @ 2019-11-06 9:38 UTC (permalink / raw) To: Ferruh Yigit; +Cc: Stephen Hemminger, Gagandeep Singh, dev, thomas, Akhil Goyal On Tue, Nov 05, 2019 at 04:02:52PM +0000, Ferruh Yigit wrote: > On 11/4/2019 11:06 AM, Bruce Richardson wrote: > > On Tue, Oct 29, 2019 at 09:27:22AM +0000, Ferruh Yigit wrote: > >> On 10/28/2019 5:18 PM, Stephen Hemminger wrote: > >>> On Mon, 26 Aug 2019 18:32:35 +0530 > >>> Gagandeep Singh <g.singh@nxp.com> wrote: > >>> > >>>> --- a/config/common_base > >>>> +++ b/config/common_base > >>>> @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n > >>>> CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n > >>>> CONFIG_RTE_LIBRTE_CXGBE_TPUT=y > >>>> > >>>> +# > >>>> +# Compile burst-oriented NXP PPFE PMD driver > >>>> +# > >>>> +CONFIG_RTE_LIBRTE_PPFE_PMD=n > >>> > >>> This driver should use the common naming convention for Poll Mode Drivers. > >>> > >>> s/CONFIG_RTE_LIBRTE_PPFE_PMD/CONFIG_RTE_LIBRTE_PMD_PPFE/ > >>> > >> > >> Unfortunately we have both as naming convention, and *unintentionally* it become > >> virtual ones PMD_XXXX (PMD_RING), physical ones (IXGBE_PMD), > >> although this PMD registers itself as virtual, it is a physical PMD and I think > >> exiting config option is good (PPFE_PMD). > >> > >> We can update config names to be consistent but not sure if it worth it, > >> changing name for users/costumers which may break their scripts, automation etc. > >> taking into account that it was like this since beginning, > >> > >> And now we are planning to switch to meson, these config option won't be used > >> directly, so I think we can keep them as they are. > > > > ... and the meson default is PMD at the end as for physical PMDs. > > > > Does meson need them? > I was thinking these PMD build enable/disable configs will go away with meson. They are not needed for meson, but they are needed for some C code so that applications or other drivers can have #ifdefs based on the presence of some other driver. Therefore, for each library or driver which will be built we add the appropriate RTE_LIBRTE_... #define to the config.h file. /Bruce ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-11-06 9:38 ` Bruce Richardson @ 2019-11-06 12:22 ` Ferruh Yigit 0 siblings, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-11-06 12:22 UTC (permalink / raw) To: Bruce Richardson Cc: Stephen Hemminger, Gagandeep Singh, dev, thomas, Akhil Goyal On 11/6/2019 9:38 AM, Bruce Richardson wrote: > On Tue, Nov 05, 2019 at 04:02:52PM +0000, Ferruh Yigit wrote: >> On 11/4/2019 11:06 AM, Bruce Richardson wrote: >>> On Tue, Oct 29, 2019 at 09:27:22AM +0000, Ferruh Yigit wrote: >>>> On 10/28/2019 5:18 PM, Stephen Hemminger wrote: >>>>> On Mon, 26 Aug 2019 18:32:35 +0530 >>>>> Gagandeep Singh <g.singh@nxp.com> wrote: >>>>> >>>>>> --- a/config/common_base >>>>>> +++ b/config/common_base >>>>>> @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n >>>>>> CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n >>>>>> CONFIG_RTE_LIBRTE_CXGBE_TPUT=y >>>>>> >>>>>> +# >>>>>> +# Compile burst-oriented NXP PPFE PMD driver >>>>>> +# >>>>>> +CONFIG_RTE_LIBRTE_PPFE_PMD=n >>>>> >>>>> This driver should use the common naming convention for Poll Mode Drivers. >>>>> >>>>> s/CONFIG_RTE_LIBRTE_PPFE_PMD/CONFIG_RTE_LIBRTE_PMD_PPFE/ >>>>> >>>> >>>> Unfortunately we have both as naming convention, and *unintentionally* it become >>>> virtual ones PMD_XXXX (PMD_RING), physical ones (IXGBE_PMD), >>>> although this PMD registers itself as virtual, it is a physical PMD and I think >>>> exiting config option is good (PPFE_PMD). >>>> >>>> We can update config names to be consistent but not sure if it worth it, >>>> changing name for users/costumers which may break their scripts, automation etc. >>>> taking into account that it was like this since beginning, >>>> >>>> And now we are planning to switch to meson, these config option won't be used >>>> directly, so I think we can keep them as they are. >>> >>> ... and the meson default is PMD at the end as for physical PMDs. >>> >> >> Does meson need them? >> I was thinking these PMD build enable/disable configs will go away with meson. > > They are not needed for meson, but they are needed for some C code so that > applications or other drivers can have #ifdefs based on the presence of > some other driver. Therefore, for each library or driver which will be > built we add the appropriate RTE_LIBRTE_... #define to the config.h file. I think only physical ones are used in C files, so using XXX_PMD syntax for everything will work for meson. And +1 to switch to this convention with meson. ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 03/13] doc: add guide for ppfe net PMD 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 04/13] net/ppfe: support dynamic logging Gagandeep Singh ` (12 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh 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 <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- MAINTAINERS | 1 + doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/index.rst | 1 + doc/guides/nics/ppfe.rst | 168 ++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 doc/guides/nics/ppfe.rst diff --git a/MAINTAINERS b/MAINTAINERS index 7996dcdd8..2b83235ac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -784,6 +784,7 @@ F: doc/guides/nics/features/enetc.ini NXP ppfe M: Gagandeep Singh <g.singh@nxp.com> M: Akhil Goyal <akhil.goyal@nxp.com> +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 9fec02f3e..46b0895f0 100644 --- a/doc/guides/nics/index.rst +++ b/doc/guides/nics/index.rst @@ -47,6 +47,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..5c58c7837 --- /dev/null +++ b/doc/guides/nics/ppfe.rst @@ -0,0 +1,168 @@ +.. 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 +<https://nxp.com/ls1012a>`_. + +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. + +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 <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_. + +2. **Linux Kernel** + + It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_. + +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 <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_. + +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 <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_ + +- **pfe kernel module** + + pfe kernel module can be obtained from NXP Layerscape software development kit at + location `/lib/modules/<kernel version>/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 <pmd_build_and_test>` +to launch **testpmd** + +Additionally, PPFE driver need `--vdev` as an input with value `eth_pfe` to execute DPDK application, +see the command below: + + .. code-block:: console + + <dpdk app> <EAL args> --vdev="eth_pfe0" --vdev="eth_pfe1" -- ... + + +Limitations +~~~~~~~~~~~ + +- Multi buffer pool cannot be supported. -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 04/13] net/ppfe: support dynamic logging 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (2 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 03/13] doc: add guide for ppfe net PMD Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 05/13] net/ppfe: add HW specific macros and operations Gagandeep Singh ` (11 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch introduces logging for the ppfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- drivers/net/ppfe/pfe_logs.h | 30 ++++++++++++++++ drivers/net/ppfe/ppfe_ethdev.c | 65 +++++++++++++++++++++++++++------- 2 files changed, 82 insertions(+), 13 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..8b34e8d1e --- /dev/null +++ b/drivers/net/ppfe/pfe_logs.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_LOGS_H_ +#define _PFE_LOGS_H_ + +/* PMD related logs */ + +#define PFE_PMD_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, RTE_LOGTYPE_PMD, "%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 f31a11b93..09d6ceec3 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -7,6 +7,7 @@ #include <rte_bus_vdev.h> #include <of.h> +#include "pfe_logs.h" #include "pfe_mod.h" #define PPFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/ @@ -24,14 +25,18 @@ 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); } @@ -46,6 +51,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; } @@ -72,6 +80,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); @@ -88,8 +98,11 @@ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) struct pfe_eth_priv_s *priv = NULL; int err; - if (id >= pfe->max_intf) + if (id >= pfe->max_intf) { + PFE_PMD_ERR("Requested intf (gemid) %d not supported Max is %d", + id, pfe->max_intf); return -EINVAL; + } data = rte_zmalloc(NULL, sizeof(*data), 64); if (data == NULL) @@ -119,6 +132,8 @@ static int 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; } @@ -149,8 +164,10 @@ parse_integer_arg(const char *key __rte_unused, int *i = (int *)extra_args; *i = atoi(value); - if (*i < 0) + if (*i < 0) { + PFE_PMD_ERR("argument has to be positive."); return -1; + } return 0; } @@ -210,10 +227,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; } @@ -223,31 +245,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; @@ -255,6 +286,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, cbus_addr); if (g_pfe->cbus_baseaddr == MAP_FAILED) { + PFE_PMD_ERR("Can not map cbus base"); rc = -EINVAL; goto err; } @@ -262,15 +294,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: @@ -307,6 +344,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; -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 05/13] net/ppfe: add HW specific macros and operations 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (3 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 04/13] net/ppfe: support dynamic logging Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 06/13] net/ppfe: add MAC and host interface initialisation Gagandeep Singh ` (10 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch add some hardware specific macros and functions that will be used by the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- 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 <compat.h> + +#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 <compat.h> + +/* @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 <linux/ethtool.h> + +#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..be485effe --- /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 int)(p)) & 0x7FFFFFFF) +#define DDR_PFE_TO_PHYS(p) (((unsigned long int)(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 int)(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_ */ -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 06/13] net/ppfe: add MAC and host interface initialisation 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (4 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 05/13] net/ppfe: add HW specific macros and operations Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 07/13] net/ppfe: add device start stop operations Gagandeep Singh ` (9 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal 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 <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- drivers/net/ppfe/Makefile | 8 + drivers/net/ppfe/base/pfe.h | 83 +++++ drivers/net/ppfe/meson.build | 9 +- drivers/net/ppfe/pfe_hal.c | 597 +++++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.c | 257 ++++++++++++++ drivers/net/ppfe/pfe_hif.h | 106 ++++++ drivers/net/ppfe/pfe_hif_lib.c | 18 + drivers/net/ppfe/pfe_hif_lib.h | 162 +++++++++ drivers/net/ppfe/pfe_mod.h | 5 + drivers/net/ppfe/ppfe_ethdev.c | 151 ++++++++- 10 files changed, 1393 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..4f7889e25 100644 --- a/drivers/net/ppfe/Makefile +++ b/drivers/net/ppfe/Makefile @@ -10,14 +10,22 @@ 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 +# depends on v2p APIs which uses experimental API +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 be485effe..c2c1896b6 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..ddbf60f38 100644 --- a/drivers/net/ppfe/meson.build +++ b/drivers/net/ppfe/meson.build @@ -6,6 +6,11 @@ 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/') +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..8bde4c037 --- /dev/null +++ b/drivers/net/ppfe/pfe_hal.c @@ -0,0 +1,597 @@ +/* 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..dee484b87 --- /dev/null +++ b/drivers/net/ppfe/pfe_hif.c @@ -0,0 +1,257 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include "pfe_logs.h" +#include "pfe_mod.h" +#include <sys/ioctl.h> +#include <sys/epoll.h> +#include <sys/eventfd.h> + +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +#define msleep(x) rte_delay_us(1000 * (x)) +#define usleep_range(min, max) msleep(DIV_ROUND_UP(min, 1000)) + +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))) +#elif defined(RTE_TOOLCHAIN_CLANG) +#pragma clang optimize off +#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 int)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 int)lmem_ptr, CLASS_INQ_PKTPTR); +} +#if defined(RTE_TOOLCHAIN_CLANG) +#pragma clang optimize on +#endif + +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(); + + usleep_range(100, 150); + } 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..c6c25458f --- /dev/null +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -0,0 +1,18 @@ +/* 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 61db998e5..f83c98b32 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 @@ -16,6 +19,8 @@ struct pfe { void *ddr_baseaddr; uint64_t ddr_size; void *cbus_baseaddr; + 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 09d6ceec3..8764d5d15 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -16,9 +16,32 @@ struct pfe_vdev_init_params { int8_t gem_id; }; + +static void *cbus_emac_base[3]; +static void *cbus_gpi_base[3]; struct pfe *g_pfe; unsigned int pfe_svr = SVR_LS1012A_REV1; +/* 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) { @@ -96,6 +119,8 @@ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) struct rte_eth_dev_data *data = NULL; 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; if (id >= pfe->max_intf) { @@ -113,15 +138,38 @@ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) rte_free(data); 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; rte_memcpy(data, eth_dev->data, sizeof(*data)); 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; @@ -139,6 +187,7 @@ static int 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; @@ -156,6 +205,57 @@ static int 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, @@ -216,7 +316,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 = { -1 @@ -280,6 +380,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; fd = open("/dev/mem", O_RDWR); @@ -309,6 +410,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) @@ -328,6 +465,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: err: rte_free(g_pfe); @@ -355,6 +498,12 @@ pmd_pfe_remove(struct rte_vdev_device *vdev) pfe_eth_exit(eth_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; + } return 0; } -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 07/13] net/ppfe: add device start stop operations 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (5 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 06/13] net/ppfe: add MAC and host interface initialisation Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 08/13] net/ppfe: add queue setup and release operations Gagandeep Singh ` (8 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch adds device start, stop and close operations. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- drivers/net/ppfe/Makefile | 2 +- drivers/net/ppfe/pfe_eth.h | 1 + drivers/net/ppfe/pfe_hif.c | 136 +++++++++++++ drivers/net/ppfe/pfe_hif.h | 41 ++++ drivers/net/ppfe/pfe_hif_lib.c | 350 ++++++++++++++++++++++++++++++++- drivers/net/ppfe/pfe_hif_lib.h | 11 ++ drivers/net/ppfe/pfe_mod.h | 1 + drivers/net/ppfe/ppfe_ethdev.c | 187 ++++++++++++++++++ 8 files changed, 727 insertions(+), 2 deletions(-) diff --git a/drivers/net/ppfe/Makefile b/drivers/net/ppfe/Makefile index 4f7889e25..5c724ace0 100644 --- a/drivers/net/ppfe/Makefile +++ b/drivers/net/ppfe/Makefile @@ -30,7 +30,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 a8ce3e314..79245c306 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 dee484b87..c2acee379 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -45,6 +45,142 @@ static void 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 c6c25458f..95a8b132b 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -5,10 +5,358 @@ #include "pfe_logs.h" #include "pfe_mod.h" -int pfe_hif_lib_init(__rte_unused struct pfe *pfe) +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 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 int)client->rx_qbase; + client_shm->rx_qsize = client->rx_qsize; + client_shm->tx_qbase = (unsigned long int)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 f83c98b32..deb19f82b 100644 --- a/drivers/net/ppfe/pfe_mod.h +++ b/drivers/net/ppfe/pfe_mod.h @@ -22,6 +22,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 8764d5d15..bb4d40077 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -64,6 +64,131 @@ pfe_soc_version_get(void) fclose(svr_file); } +/* pfe_eth_start + */ +static int pfe_eth_start(struct pfe_eth_priv_s *priv) +{ + gpi_enable(priv->GPI_baseaddr); + gemac_enable(priv->EMAC_baseaddr); + + return 0; +} + +/* pfe_eth_flush_txQ + */ +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); + } + } +} + + +/* pfe_eth_flush_tx + */ +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); +} + +/* pfe_eth_event_handler + */ +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; +} + +/* pfe_eth_open + */ +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) { @@ -98,6 +223,7 @@ pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) } } + /* pfe_eth_exit */ static void @@ -112,6 +238,65 @@ pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) pfe->nb_devs--; } +/* pfe_eth_stop + */ +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); +} + +/* pfe_eth_close + * + */ +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 void +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; +} + +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, +}; + /* pfe_eth_init_one */ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) @@ -187,6 +372,8 @@ static int 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; -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 08/13] net/ppfe: add queue setup and release operations 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (6 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 07/13] net/ppfe: add device start stop operations Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 09/13] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh ` (7 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add RX/TX queue setup operations and supported checksum offloads. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 2 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/pfe_hif.c | 114 ++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.h | 1 + drivers/net/ppfe/pfe_hif_lib.c | 48 +++++++++++++ drivers/net/ppfe/ppfe_ethdev.c | 100 +++++++++++++++++++++++++- 6 files changed, 263 insertions(+), 3 deletions(-) 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 5c58c7837..6313229cb 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -91,6 +91,7 @@ pfe.ko is required for PHY initialisation. 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 c2acee379..7e8250e34 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -45,6 +45,120 @@ static void 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 95a8b132b..739909f16 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -15,6 +15,54 @@ 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 bb4d40077..be9a7fec7 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -13,15 +13,28 @@ #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; -}; +/* 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; + static void *cbus_emac_base[3]; static void *cbus_gpi_base[3]; struct pfe *g_pfe; unsigned int pfe_svr = SVR_LS1012A_REV1; +struct pfe_vdev_init_params { + int8_t gem_id; +}; + /* pfe_gemac_init */ static int pfe_gemac_init(struct pfe_eth_priv_s *priv) @@ -287,6 +300,83 @@ 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; +} + +/* 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 = { @@ -295,6 +385,10 @@ static const struct eth_dev_ops ops = { .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, }; /* pfe_eth_init_one -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 09/13] net/ppfe: add burst enqueue and dequeue operations 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (7 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 08/13] net/ppfe: add queue setup and release operations Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 10/13] net/ppfe: add supported packet types and basic statistics Gagandeep Singh ` (6 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add burst enqueue and dequeue operations to the ppfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- drivers/net/ppfe/pfe_hif.c | 350 +++++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.h | 8 + drivers/net/ppfe/pfe_hif_lib.c | 143 ++++++++++++++ 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, 651 insertions(+) diff --git a/drivers/net/ppfe/pfe_hif.c b/drivers/net/ppfe/pfe_hif.c index 7e8250e34..8afeae1bb 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -45,6 +45,37 @@ static void 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 @@ -258,6 +289,322 @@ static void 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; + } else { + 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) { @@ -500,6 +847,9 @@ void 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 739909f16..ad021d732 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -356,6 +356,149 @@ int 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 deb19f82b..9466e3dcb 100644 --- a/drivers/net/ppfe/pfe_mod.h +++ b/drivers/net/ppfe/pfe_mod.h @@ -7,6 +7,8 @@ struct pfe; +#include <rte_ethdev.h> + #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 be9a7fec7..ca1f6a5c0 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -2,6 +2,7 @@ * Copyright 2019 NXP */ +#include <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> @@ -137,6 +138,120 @@ static int 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; +} + + /* pfe_eth_open */ static int pfe_eth_open(struct rte_eth_dev *dev) @@ -175,6 +290,20 @@ static int 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) { + for (int 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 */ @@ -198,6 +327,14 @@ static int 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; @@ -259,6 +396,9 @@ static void 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; } /* pfe_eth_close -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 10/13] net/ppfe: add supported packet types and basic statistics 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (8 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 09/13] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 11/13] net/ppfe: add MTU and MAC address set operations Gagandeep Singh ` (5 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh 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 <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 6313229cb..099abfee6 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -92,6 +92,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 ca1f6a5c0..a98d0eda2 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -519,6 +519,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, @@ -529,6 +570,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, }; /* pfe_eth_init_one -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 11/13] net/ppfe: add MTU and MAC address set operations 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (9 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 10/13] net/ppfe: add supported packet types and basic statistics Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 12/13] net/ppfe: add allmulticast and promiscuous Gagandeep Singh ` (4 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh To update MAC address or MTU, operations are added to the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/ppfe_ethdev.c | 62 +++++++++++++++++++++++++++++++ 3 files changed, 64 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 099abfee6..b4a756258 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -94,6 +94,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 a98d0eda2..a354b0d44 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -6,6 +6,7 @@ #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> +#include <rte_ether.h> #include <of.h> #include "pfe_logs.h" @@ -540,6 +541,58 @@ 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) @@ -571,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, }; @@ -583,6 +638,7 @@ static int 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; if (id >= pfe->max_intf) { @@ -648,6 +704,12 @@ static int 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); -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 12/13] net/ppfe: add allmulticast and promiscuous 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (10 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 11/13] net/ppfe: add MTU and MAC address set operations Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 13/13] net/ppfe: add link status update Gagandeep Singh ` (3 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch adds support to enable multicast and promiscuous mode. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 2 ++ doc/guides/nics/ppfe.rst | 2 ++ drivers/net/ppfe/ppfe_ethdev.c | 36 +++++++++++++++++++++++++++++++ 3 files changed, 40 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 b4a756258..71b049198 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -95,6 +95,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 a354b0d44..c35e517e0 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -541,6 +541,39 @@ pfe_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } +static void +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); +} + +static void +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); +} + +static void +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; +} + static int pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { @@ -624,6 +657,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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v1 13/13] net/ppfe: add link status update 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (11 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 12/13] net/ppfe: add allmulticast and promiscuous Gagandeep Singh @ 2019-08-26 13:02 ` Gagandeep Singh 2019-08-27 7:16 ` [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (2 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-26 13:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add link related operations like link update, up and down. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/ppfe_ethdev.c | 103 ++++++++++++++++++++++++++++++ 3 files changed, 105 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 71b049198..6c19a2c73 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -97,6 +97,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 c35e517e0..653862ef9 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -2,6 +2,8 @@ * Copyright 2019 NXP */ +#include <sys/ioctl.h> +#include <sys/epoll.h> #include <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> @@ -541,6 +543,90 @@ 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 void pfe_promiscuous_enable(struct rte_eth_dev *dev) { @@ -574,6 +660,20 @@ pfe_allmulticast_enable(struct rte_eth_dev *dev) dev->data->all_multicast = 1; } +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) { @@ -657,9 +757,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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (12 preceding siblings ...) 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 13/13] net/ppfe: add link status update Gagandeep Singh @ 2019-08-27 7:16 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-27 7:16 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas Hi Ferruh, > Subject: [PATCH v1 00/13] introduces ppfe network PMD > > This series introduces ppfe (programmable packet > forwarding engine) network poll mode driver for > NXP SoC ls1012a. > > First patch of this series move OF library code from > dpaa bus to a common folder as PPFE also uses the > same library for getting information from the device > tree. > This patch is included in this series so that > compilation by CI don't break. > > Gagandeep Singh (12): > net/ppfe: introduce ppfe net poll mode driver > doc: add guide for ppfe net PMD > net/ppfe: support dynamic logging > net/ppfe: add HW specific macros and operations > net/ppfe: add MAC and host interface initialisation > net/ppfe: add device start stop operations > net/ppfe: add queue setup and release operations > net/ppfe: add burst enqueue and dequeue operations > net/ppfe: add supported packet types and basic statistics > net/ppfe: add MTU and MAC address set operations > net/ppfe: add allmulticast and promiscuous > net/ppfe: add link status update > > Hemant Agrawal (1): > common/dpaax: moving OF lib code from dpaa bus > We are seeing DPDK compilation break on CENTOS in CI test reports. One of the error is " error: unknown pragma ignored [-Werror,-Wunknown-pragmas]" with clang version 3.4.2 which is pretty old and it seems this version of clang is not supporting the function level optimization. Do you know why we are using such an old version of clang? Can you please suggest how can I fix this issue? Thanks, Gagan ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 00/13] introduces ppfe network PMD 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (13 preceding siblings ...) 2019-08-27 7:16 ` [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh ` (13 more replies) 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh 15 siblings, 14 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This series introduces ppfe (programmable packet forwarding engine) network poll mode driver for NXP SoC ls1012a. First patch of this series move OF library code from dpaa bus to a common folder as PPFE also uses the same library for getting information from the device tree. This patch is included in this series so that compilation by CI don't break. V2 Change-log: * fix compilation break for clang3.4 and gcc 4.8 * fix checkpatch errors Gagandeep Singh (12): net/ppfe: introduce ppfe net poll mode driver doc: add guide for ppfe net PMD net/ppfe: support dynamic logging net/ppfe: add HW specific macros and operations net/ppfe: add MAC and host interface initialisation net/ppfe: add device start stop operations net/ppfe: add queue setup and release operations net/ppfe: add burst enqueue and dequeue operations net/ppfe: add supported packet types and basic statistics net/ppfe: add MTU and MAC address set operations net/ppfe: add allmulticast and promiscuous net/ppfe: add link status update Hemant Agrawal (1): common/dpaax: moving OF lib code from dpaa bus MAINTAINERS | 7 + config/common_base | 5 + config/common_linux | 5 + doc/guides/nics/features/ppfe.ini | 17 + doc/guides/nics/index.rst | 1 + doc/guides/nics/ppfe.rst | 175 +++ drivers/bus/dpaa/Makefile | 2 +- drivers/bus/dpaa/base/qbman/dpaa_sys.h | 1 + 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 drivers/common/dpaax/dpaax_logs.h | 10 + drivers/common/dpaax/meson.build | 5 +- .../{bus/dpaa/base/fman => common/dpaax}/of.c | 61 +- .../{bus/dpaa/include => common/dpaax}/of.h | 27 +- .../common/dpaax/rte_common_dpaax_version.map | 18 + drivers/crypto/caam_jr/Makefile | 2 + drivers/crypto/dpaa2_sec/Makefile | 2 +- drivers/crypto/dpaa_sec/Makefile | 1 + drivers/event/dpaa/Makefile | 1 + drivers/event/dpaa2/Makefile | 1 + drivers/mempool/dpaa/Makefile | 1 + drivers/mempool/dpaa2/Makefile | 1 + drivers/net/Makefile | 1 + drivers/net/dpaa/Makefile | 1 + drivers/net/dpaa2/Makefile | 1 + drivers/net/meson.build | 1 + drivers/net/ppfe/Makefile | 36 + 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 | 422 ++++++ drivers/net/ppfe/meson.build | 16 + drivers/net/ppfe/pfe_eth.h | 78 ++ drivers/net/ppfe/pfe_hal.c | 596 +++++++++ drivers/net/ppfe/pfe_hif.c | 848 ++++++++++++ drivers/net/ppfe/pfe_hif.h | 156 +++ drivers/net/ppfe/pfe_hif_lib.c | 557 ++++++++ drivers/net/ppfe/pfe_hif_lib.h | 181 +++ drivers/net/ppfe/pfe_logs.h | 30 + drivers/net/ppfe/pfe_mod.h | 59 + drivers/net/ppfe/ppfe_ethdev.c | 1183 +++++++++++++++++ drivers/net/ppfe/rte_pmd_ppfe_version.map | 4 + drivers/raw/dpaa2_cmdif/Makefile | 1 + drivers/raw/dpaa2_qdma/Makefile | 1 + mk/rte.app.mk | 1 + 58 files changed, 5504 insertions(+), 46 deletions(-) create mode 100644 doc/guides/nics/features/ppfe.ini create mode 100644 doc/guides/nics/ppfe.rst rename drivers/{bus/dpaa/include => common/dpaax}/dpaa_list.h (100%) rename drivers/{bus/dpaa/base/fman => common/dpaax}/of.c (88%) rename drivers/{bus/dpaa/include => common/dpaax}/of.h (86%) create mode 100644 drivers/net/ppfe/Makefile 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 create mode 100644 drivers/net/ppfe/meson.build create mode 100644 drivers/net/ppfe/pfe_eth.h 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 create mode 100644 drivers/net/ppfe/pfe_logs.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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 01/13] common/dpaax: moving OF lib code from dpaa bus 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-09-26 16:54 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh ` (12 subsequent siblings) 13 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Hemant Agrawal From: Hemant Agrawal <hemant.agrawal@nxp.com> This code is being shared by more than 1 type of driver. Common is most appropriate place for it. Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com> --- drivers/bus/dpaa/Makefile | 2 +- drivers/bus/dpaa/base/qbman/dpaa_sys.h | 1 + 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 drivers/common/dpaax/dpaax_logs.h | 10 +++ drivers/common/dpaax/meson.build | 5 +- .../{bus/dpaa/base/fman => common/dpaax}/of.c | 61 ++++++++++--------- .../{bus/dpaa/include => common/dpaax}/of.h | 27 ++++++-- .../common/dpaax/rte_common_dpaax_version.map | 18 ++++++ drivers/crypto/caam_jr/Makefile | 2 + drivers/crypto/dpaa2_sec/Makefile | 2 +- drivers/crypto/dpaa_sec/Makefile | 1 + 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/dpaa2/Makefile | 1 + drivers/raw/dpaa2_cmdif/Makefile | 1 + drivers/raw/dpaa2_qdma/Makefile | 1 + 27 files changed, 110 insertions(+), 46 deletions(-) rename drivers/{bus/dpaa/include => common/dpaax}/dpaa_list.h (100%) rename drivers/{bus/dpaa/base/fman => common/dpaax}/of.c (88%) rename drivers/{bus/dpaa/include => common/dpaax}/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/qbman/dpaa_sys.h b/drivers/bus/dpaa/base/qbman/dpaa_sys.h index 034991ba1..e86a480b7 100644 --- a/drivers/bus/dpaa/base/qbman/dpaa_sys.h +++ b/drivers/bus/dpaa/base/qbman/dpaa_sys.h @@ -8,6 +8,7 @@ #ifndef __DPAA_SYS_H #define __DPAA_SYS_H +#include <compat.h> #include <of.h> /* For 2-element tables related to cache-inhibited and cache-enabled mappings */ diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c index 07cc5c667..8770c3a11 100644 --- a/drivers/bus/dpaa/dpaa_bus.c +++ b/drivers/bus/dpaa/dpaa_bus.c @@ -32,6 +32,7 @@ #include <rte_bus.h> #include <rte_mbuf_pool_ops.h> +#include <of.h> #include <rte_dpaa_bus.h> #include <rte_dpaa_logs.h> #include <dpaax_iova_table.h> @@ -39,7 +40,6 @@ #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> 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 <dpaa_list.h> #include <dpaa_bits.h> #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 <rte_ether.h> #include <compat.h> +#include <dpaa_list.h> #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 <compat.h> +#include <dpaa_list.h> #include <fsl_qman.h> #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..19e30069d 100644 --- a/drivers/bus/dpaa/rte_dpaa_bus.h +++ b/drivers/bus/dpaa/rte_dpaa_bus.h @@ -10,10 +10,10 @@ #include <rte_mempool.h> #include <dpaax_iova_table.h> +#include <of.h> #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> #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..f725d93d4 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 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/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..795cc84b9 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', 'of.c') cflags += ['-D_GNU_SOURCE'] +if cc.has_argument('-Wno-cast-qual') + cflags += '-Wno-cast-qual' +endif diff --git a/drivers/bus/dpaa/base/fman/of.c b/drivers/common/dpaax/of.c similarity index 88% rename from drivers/bus/dpaa/base/fman/of.c rename to drivers/common/dpaax/of.c index 1e97be54e..b713bfd54 100644 --- a/drivers/bus/dpaa/base/fman/of.c +++ b/drivers/common/dpaax/of.c @@ -6,8 +6,9 @@ */ #include <of.h> +#include <assert.h> #include <rte_string_fns.h> -#include <rte_dpaa_logs.h> +#include <dpaax_logs.h> 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/of.h similarity index 86% rename from drivers/bus/dpaa/include/of.h rename to drivers/common/dpaax/of.h index 7ea7608fc..e9761ce0e 100644 --- a/drivers/bus/dpaa/include/of.h +++ b/drivers/common/dpaax/of.h @@ -8,7 +8,24 @@ #ifndef __OF_H #define __OF_H -#include <compat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <stdlib.h> +#include <inttypes.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> +#include <fcntl.h> +#include <glob.h> +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <limits.h> +#include <inttypes.h> +#include <rte_common.h> +#include <dpaa_list.h> #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/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/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/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/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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 01/13] common/dpaax: moving OF lib code from dpaa bus 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh @ 2019-09-26 16:54 ` Ferruh Yigit 0 siblings, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-09-26 16:54 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas, Hemant Agrawal On 8/28/2019 12:08 PM, Gagandeep Singh wrote: > From: Hemant Agrawal <hemant.agrawal@nxp.com> > > This code is being shared by more than 1 type of driver. > Common is most appropriate place for it. > > Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com> <...> > @@ -32,6 +32,7 @@ > #include <rte_bus.h> > #include <rte_mbuf_pool_ops.h> > > +#include <of.h> Is there any risk of this is conflicting with the linux 'of.h', does it make sense to rename it to something like 'dpaa_of.h' ? ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-09-26 16:53 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD Gagandeep Singh ` (11 subsequent siblings) 13 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal 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 <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- MAINTAINERS | 6 + config/common_base | 5 + config/common_linux | 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 | 77 +++++ drivers/net/ppfe/pfe_mod.h | 51 ++++ drivers/net/ppfe/ppfe_ethdev.c | 329 ++++++++++++++++++++++ drivers/net/ppfe/rte_pmd_ppfe_version.map | 4 + mk/rte.app.mk | 1 + 13 files changed, 527 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 410026086..7996dcdd8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -781,6 +781,12 @@ F: drivers/net/enetc/ F: doc/guides/nics/enetc.rst F: doc/guides/nics/features/enetc.ini +NXP ppfe +M: Gagandeep Singh <g.singh@nxp.com> +M: Akhil Goyal <akhil.goyal@nxp.com> +F: drivers/net/ppfe/ +F: doc/guides/nics/features/ppfe.ini + QLogic bnx2x M: Rasesh Mody <rmody@marvell.com> M: Shahed Shaikh <shshaikh@marvell.com> diff --git a/config/common_base b/config/common_base index 8ef75c203..1776a8fa8 100644 --- a/config/common_base +++ b/config/common_base @@ -224,6 +224,11 @@ CONFIG_RTE_LIBRTE_CXGBE_DEBUG_TX=n CONFIG_RTE_LIBRTE_CXGBE_DEBUG_RX=n CONFIG_RTE_LIBRTE_CXGBE_TPUT=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/config/common_linux b/config/common_linux index 6e252553a..2ba70ba95 100644 --- a/config/common_linux +++ b/config/common_linux @@ -59,6 +59,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=y # CONFIG_RTE_LIBRTE_ENETC_PMD=y +# +# NXP PPFE PMD Driver +# +CONFIG_RTE_LIBRTE_PPFE_PMD=y + # # HINIC PMD driver # 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 5767fdf65..b59cdbb83 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -49,6 +49,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 513f19b33..a3be718a6 100644 --- a/drivers/net/meson.build +++ b/drivers/net/meson.build @@ -37,6 +37,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..a8ce3e314 --- /dev/null +++ b/drivers/net/ppfe/pfe_eth.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_ETH_H_ +#define _PFE_ETH_H_ + +#include <compat.h> +#include <rte_ethdev.h> +#include <rte_ethdev_vdev.h> + +#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; +}; + +struct pfe_eth { + struct pfe_eth_priv_s *eth_priv[3]; +}; + +#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..61db998e5 --- /dev/null +++ b/drivers/net/ppfe/pfe_mod.h @@ -0,0 +1,51 @@ +/* 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 + +struct pfe { + uint64_t ddr_phys_baseaddr; + void *ddr_baseaddr; + uint64_t ddr_size; + void *cbus_baseaddr; + struct pfe_eth eth; + int mdio_muxval[PHYID_MAX_VAL]; + uint8_t nb_devs; + uint8_t max_intf; + int cdev_fd; +}; + +/* for link status and IOCTL support using pfe character device + * XXX: Should be kept in sync with Kernel module + */ + +/* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are + * supported by PFE driver. Should be updated if number of eth devices are + * changed. + */ +#define PFE_CDEV_ETH_COUNT 3 + +#define PFE_CDEV_PATH "/dev/pfe_us_cdev" +#define PFE_CDEV_INVALID_FD -1 + +/* 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 */ +}; + +/* 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..f31a11b93 --- /dev/null +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -0,0 +1,329 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include <rte_kvargs.h> +#include <rte_ethdev_vdev.h> +#include <rte_bus_vdev.h> +#include <of.h> + +#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; +}; +struct pfe *g_pfe; +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; + } +} + +/* pfe_eth_exit + */ +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_eth_dev_release_port(dev); + pfe->nb_devs--; +} + +/* pfe_eth_init_one + */ +static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) +{ + struct rte_eth_dev_data *data = NULL; + struct rte_eth_dev *eth_dev = NULL; + struct pfe_eth_priv_s *priv = NULL; + int err; + + if (id >= pfe->max_intf) + return -EINVAL; + + data = rte_zmalloc(NULL, sizeof(*data), 64); + if (data == NULL) + return -ENOMEM; + + eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); + if (eth_dev == NULL) { + rte_free(data); + return -ENOMEM; + } + + priv = eth_dev->data->dev_private; + rte_memcpy(data, eth_dev->data, sizeof(*data)); + + 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_free(data); + 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 = (int *)extra_args; + + *i = atoi(value); + if (*i < 0) + return -1; + + 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 (params == NULL) + return -EINVAL; + + + if (input_args) { + 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); + if (ret < 0) + goto free_kvlist; + } + +free_kvlist: + 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 = { + -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), 64); + 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; + + fd = open("/dev/mem", O_RDWR); + g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, cbus_addr); + 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: +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); + + return 0; +} + +static struct rte_vdev_driver pmd_pfe_drv = { + .probe = pmd_pfe_probe, + .remove = pmd_pfe_remove, +}; + +RTE_PMD_REGISTER_VDEV(PFE_PMD, pmd_pfe_drv); +RTE_PMD_REGISTER_ALIAS(PFE_PMD, eth_pfe); +RTE_PMD_REGISTER_PARAM_STRING(PFE_PMD, "intf=<int> "); 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 ba5c39e01..4df36a53c 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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh @ 2019-09-26 16:53 ` Ferruh Yigit 2019-10-01 7:05 ` Gagandeep Singh 0 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-09-26 16:53 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas, Akhil Goyal On 8/28/2019 12:08 PM, Gagandeep Singh wrote: > 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 <g.singh@nxp.com> > Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> <...> > @@ -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 Only arm? Should this be reflected to config file? like enabling it only in 'common_armv8a_linux'. <...> > +struct pfe_eth { > + struct pfe_eth_priv_s *eth_priv[3]; Why hardcoded 3? Can it use PFE_CDEV_ETH_COUNT (if they are for same thing) ? <...> > + > +/* for link status and IOCTL support using pfe character device > + * XXX: Should be kept in sync with Kernel module How can we know if it is in sync with kernel module, is there any check in the code? > + */ > + > +/* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are > + * supported by PFE driver. Should be updated if number of eth devices are > + * changed. > + */ > +#define PFE_CDEV_ETH_COUNT 3 > + > +#define PFE_CDEV_PATH "/dev/pfe_us_cdev" Can you please add a comment why this char device is used? <...> > +struct pfe *g_pfe; Any reason to not make this static? > +unsigned int pfe_svr = SVR_LS1012A_REV1; There are some checks for this in hal layer, should this be a runtime option instead of hardcoded in the .c file? <...> > +/* pfe_eth_exit > + */ > +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); You may want to do stop before close. > + > + rte_eth_dev_release_port(dev); > + pfe->nb_devs--; > +} > + > +/* pfe_eth_init_one Comment is wrong, and not sure commenting the function name is that useful > + */ > +static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) Please apply same syntax to function prototypes. > +{ > + struct rte_eth_dev_data *data = NULL; > + struct rte_eth_dev *eth_dev = NULL; > + struct pfe_eth_priv_s *priv = NULL; > + int err; > + > + if (id >= pfe->max_intf) > + return -EINVAL; Can this happen at this stage? > + > + data = rte_zmalloc(NULL, sizeof(*data), 64); > + if (data == NULL) > + return -ENOMEM; > + > + eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv)); > + if (eth_dev == NULL) { > + rte_free(data); > + return -ENOMEM; > + } > + > + priv = eth_dev->data->dev_private; > + rte_memcpy(data, eth_dev->data, sizeof(*data)); Why you allocate and copy to 'data', as far as I can see you are not using it at all J Unless I am missing something. <...> > + > + /* 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_free(data); Need to release the 'eth_dev', rte_eth_dev_release_port() > + 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 = (int *)extra_args; > + > + *i = atoi(value); > + if (*i < 0) If you are trying to detect the error, atoi is not working that way, 'strtol' can be better option for that. > + return -1; > + > + 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 (params == NULL) > + return -EINVAL; This is a static function and only used once, not sure about verifying the input param, although it won't hurt. > + > + > + if (input_args) { Not sure if 'input_args' can bu NULL at all, but anyway, what about retun immediately if it is NULL, it can reduce the indentation. Also if the PPFE_VDEV_GEM_ID_ARG is optional and you want to check if user provided it or not, you should check the value of the 'input_args' instead of its address I think. > + 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); > + if (ret < 0) > + goto free_kvlist; > + } > + > +free_kvlist: > + 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 = { > + -1 I would prefer designated initializes to make it more clear, up to you. > + }; > + > + 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), 64); If 64 is for cache line, may be better to use macro for it. > + if (g_pfe == NULL) > + return -EINVAL; Is there a value of dynamically allocate the g_pfe, it is already global, so why not define it statically? May be secondary process can have benefit from allocating in shared memory but you are not using shared process as far as I can see. > + > + /* 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; > + > + fd = open("/dev/mem", O_RDWR); > + g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, > + MAP_SHARED, fd, cbus_addr); Above reads device information from a device tree file and creates a new mapping for its address space. I wonder if device can be probbed as we do the pcie devices, do you have to depend on the 'of', can't the driver registered for a pysical device? <...> > + 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: Should 'munmap' here? and close fd? <...> > +RTE_PMD_REGISTER_VDEV(PFE_PMD, pmd_pfe_drv); > +RTE_PMD_REGISTER_ALIAS(PFE_PMD, eth_pfe); Please drop the alias, that is for compatibility for old pmds. > +RTE_PMD_REGISTER_PARAM_STRING(PFE_PMD, "intf=<int> "); Better to use 'PPFE_VDEV_GEM_ID_ARG' macro here to prevent typos etc... ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 02/13] net/ppfe: introduce ppfe net poll mode driver 2019-09-26 16:53 ` Ferruh Yigit @ 2019-10-01 7:05 ` Gagandeep Singh 0 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 7:05 UTC (permalink / raw) To: Ferruh Yigit, dev; +Cc: thomas, Akhil Goyal Hi Ferruh, I have incorporated most of your comments in V3 of this series. I'll send the series by today. For those, which will not be included in this version, I have added some comments, please see inline. > <...> > > > + > > +/* for link status and IOCTL support using pfe character device > > + * XXX: Should be kept in sync with Kernel module > > How can we know if it is in sync with kernel module, is there any check in the > code? There is no check for this in the code, but it is mandatory to load "pfe.ko" kernel Module to run PFFE driver, I have added this requirement in document under prerequisites section. <...> > > > +unsigned int pfe_svr = SVR_LS1012A_REV1; > > There are some checks for this in hal layer, should this be a runtime option > instead of hardcoded in the .c file? I agree with you, It should be a runtime option. Is it ok, if I send a separate patch for this? It may take some time as I have to look into the manual to find possible ways to get svr value from the HW. I'll add a comment here for this. <...> > > + g_pfe->ddr_size = ddr_size; > > + > > + fd = open("/dev/mem", O_RDWR); > > + g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | > PROT_WRITE, > > + MAP_SHARED, fd, cbus_addr); > > Above reads device information from a device tree file and creates a new > mapping > for its address space. I wonder if device can be probbed as we do the pcie > devices, do you have to depend on the 'of', can't the driver registered for a > pysical device? > These eth devices are actual Virtual interfaces created by Client driver (a part of the ppfe driver). Actually, HW provides a single interface (Host interface), which is the only device accessible by the userspace driver for enqueue and dequeue and ppfe driver create two virtual interfaces out of this single host interface. Also, this device is not on pcie bus. Thanks, Gagan ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-09-26 16:56 ` Ferruh Yigit 2019-09-26 18:00 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 04/13] net/ppfe: support dynamic logging Gagandeep Singh ` (10 subsequent siblings) 13 siblings, 2 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh 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 <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- MAINTAINERS | 1 + doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/index.rst | 1 + doc/guides/nics/ppfe.rst | 168 ++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 doc/guides/nics/ppfe.rst diff --git a/MAINTAINERS b/MAINTAINERS index 7996dcdd8..2b83235ac 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -784,6 +784,7 @@ F: doc/guides/nics/features/enetc.ini NXP ppfe M: Gagandeep Singh <g.singh@nxp.com> M: Akhil Goyal <akhil.goyal@nxp.com> +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 9fec02f3e..46b0895f0 100644 --- a/doc/guides/nics/index.rst +++ b/doc/guides/nics/index.rst @@ -47,6 +47,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..5c58c7837 --- /dev/null +++ b/doc/guides/nics/ppfe.rst @@ -0,0 +1,168 @@ +.. 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 +<https://nxp.com/ls1012a>`_. + +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. + +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 <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_. + +2. **Linux Kernel** + + It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_. + +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 <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_. + +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 <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_ + +- **pfe kernel module** + + pfe kernel module can be obtained from NXP Layerscape software development kit at + location `/lib/modules/<kernel version>/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 <pmd_build_and_test>` +to launch **testpmd** + +Additionally, PPFE driver need `--vdev` as an input with value `eth_pfe` to execute DPDK application, +see the command below: + + .. code-block:: console + + <dpdk app> <EAL args> --vdev="eth_pfe0" --vdev="eth_pfe1" -- ... + + +Limitations +~~~~~~~~~~~ + +- Multi buffer pool cannot be supported. -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD Gagandeep Singh @ 2019-09-26 16:56 ` Ferruh Yigit 2019-09-26 18:00 ` Ferruh Yigit 1 sibling, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-09-26 16:56 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas On 8/28/2019 12:08 PM, Gagandeep Singh wrote: > 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 <g.singh@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> > Acked-by: Akhil Goyal <akhil.goyal@nxp.com> <...> > +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 Is it always fixed size logical interface, eth0 & eth1? There is following comment in the code, is it something else: " /* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are * supported by PFE driver. Should be updated if number of eth devices are * changed. */ #define PFE_CDEV_ETH_COUNT 3 " > +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. Is char device "/dev/pfe_us_cdev" created by this kernel module? <...> > +Driver compilation and testing > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + > +Follow instructions available in the document > +:ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>` > +to launch **testpmd** > + > +Additionally, PPFE driver need `--vdev` as an input with value `eth_pfe` to execute DPDK application, > +see the command below: > + > + .. code-block:: console > + > + <dpdk app> <EAL args> --vdev="eth_pfe0" --vdev="eth_pfe1" -- ... Can you please document the "intf" (PPFE_VDEV_GEM_ID_ARG) device argument? ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD Gagandeep Singh 2019-09-26 16:56 ` Ferruh Yigit @ 2019-09-26 18:00 ` Ferruh Yigit 1 sibling, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-09-26 18:00 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas On 8/28/2019 12:08 PM, Gagandeep Singh wrote: > 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 <g.singh@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> > Acked-by: Akhil Goyal <akhil.goyal@nxp.com> > --- > MAINTAINERS | 1 + > doc/guides/nics/features/ppfe.ini | 1 + > doc/guides/nics/index.rst | 1 + > doc/guides/nics/ppfe.rst | 168 ++++++++++++++++++++++++++++++ Can you please update 19.11 release notes and document new driver? ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 04/13] net/ppfe: support dynamic logging 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (2 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-09-26 16:57 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 05/13] net/ppfe: add HW specific macros and operations Gagandeep Singh ` (9 subsequent siblings) 13 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch introduces logging for the ppfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- drivers/net/ppfe/pfe_logs.h | 30 ++++++++++++++++ drivers/net/ppfe/ppfe_ethdev.c | 65 +++++++++++++++++++++++++++------- 2 files changed, 82 insertions(+), 13 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..8b34e8d1e --- /dev/null +++ b/drivers/net/ppfe/pfe_logs.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _PFE_LOGS_H_ +#define _PFE_LOGS_H_ + +/* PMD related logs */ + +#define PFE_PMD_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, RTE_LOGTYPE_PMD, "%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 f31a11b93..09d6ceec3 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -7,6 +7,7 @@ #include <rte_bus_vdev.h> #include <of.h> +#include "pfe_logs.h" #include "pfe_mod.h" #define PPFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/ @@ -24,14 +25,18 @@ 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); } @@ -46,6 +51,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; } @@ -72,6 +80,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); @@ -88,8 +98,11 @@ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) struct pfe_eth_priv_s *priv = NULL; int err; - if (id >= pfe->max_intf) + if (id >= pfe->max_intf) { + PFE_PMD_ERR("Requested intf (gemid) %d not supported Max is %d", + id, pfe->max_intf); return -EINVAL; + } data = rte_zmalloc(NULL, sizeof(*data), 64); if (data == NULL) @@ -119,6 +132,8 @@ static int 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; } @@ -149,8 +164,10 @@ parse_integer_arg(const char *key __rte_unused, int *i = (int *)extra_args; *i = atoi(value); - if (*i < 0) + if (*i < 0) { + PFE_PMD_ERR("argument has to be positive."); return -1; + } return 0; } @@ -210,10 +227,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; } @@ -223,31 +245,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; @@ -255,6 +286,7 @@ pmd_pfe_probe(struct rte_vdev_device *vdev) g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, cbus_addr); if (g_pfe->cbus_baseaddr == MAP_FAILED) { + PFE_PMD_ERR("Can not map cbus base"); rc = -EINVAL; goto err; } @@ -262,15 +294,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: @@ -307,6 +344,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; -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 04/13] net/ppfe: support dynamic logging 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 04/13] net/ppfe: support dynamic logging Gagandeep Singh @ 2019-09-26 16:57 ` Ferruh Yigit 0 siblings, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-09-26 16:57 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas On 8/28/2019 12:08 PM, Gagandeep Singh wrote: > This patch introduces logging for the ppfe PMD. > > Signed-off-by: Gagandeep Singh <g.singh@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> > Acked-by: Akhil Goyal <akhil.goyal@nxp.com> > --- > drivers/net/ppfe/pfe_logs.h | 30 ++++++++++++++++ > drivers/net/ppfe/ppfe_ethdev.c | 65 +++++++++++++++++++++++++++------- > 2 files changed, 82 insertions(+), 13 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..8b34e8d1e > --- /dev/null > +++ b/drivers/net/ppfe/pfe_logs.h > @@ -0,0 +1,30 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright 2019 NXP > + */ > + > +#ifndef _PFE_LOGS_H_ > +#define _PFE_LOGS_H_ > + > +/* PMD related logs */ > + > +#define PFE_PMD_LOG(level, fmt, args...) \ > + rte_log(RTE_LOG_ ## level, RTE_LOGTYPE_PMD, "%s(): " fmt "\n",\ > + __func__, ##args) > + Please don't use 'RTE_LOGTYPE_PMD' log type but register a dynamic one for the driver. ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 05/13] net/ppfe: add HW specific macros and operations 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (3 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 04/13] net/ppfe: support dynamic logging Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 06/13] net/ppfe: add MAC and host interface initialisation Gagandeep Singh ` (8 subsequent siblings) 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch add some hardware specific macros and functions that will be used by the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- 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 <compat.h> + +#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 <compat.h> + +/* @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 <linux/ethtool.h> + +#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_ */ -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 06/13] net/ppfe: add MAC and host interface initialisation 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (4 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 05/13] net/ppfe: add HW specific macros and operations Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-09-26 17:00 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 07/13] net/ppfe: add device start stop operations Gagandeep Singh ` (7 subsequent siblings) 13 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal 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 <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- drivers/net/ppfe/Makefile | 8 + drivers/net/ppfe/base/pfe.h | 83 +++++ drivers/net/ppfe/meson.build | 9 +- drivers/net/ppfe/pfe_hal.c | 596 +++++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.c | 248 ++++++++++++++ drivers/net/ppfe/pfe_hif.h | 106 ++++++ drivers/net/ppfe/pfe_hif_lib.c | 18 + drivers/net/ppfe/pfe_hif_lib.h | 162 +++++++++ drivers/net/ppfe/pfe_mod.h | 5 + drivers/net/ppfe/ppfe_ethdev.c | 151 ++++++++- 10 files changed, 1383 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..4f7889e25 100644 --- a/drivers/net/ppfe/Makefile +++ b/drivers/net/ppfe/Makefile @@ -10,14 +10,22 @@ 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 +# depends on v2p APIs which uses experimental API +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..ddbf60f38 100644 --- a/drivers/net/ppfe/meson.build +++ b/drivers/net/ppfe/meson.build @@ -6,6 +6,11 @@ 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/') +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..29e9d2f32 --- /dev/null +++ b/drivers/net/ppfe/pfe_hal.c @@ -0,0 +1,596 @@ +/* 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..908700bc1 --- /dev/null +++ b/drivers/net/ppfe/pfe_hif.c @@ -0,0 +1,248 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include "pfe_logs.h" +#include "pfe_mod.h" +#include <sys/ioctl.h> +#include <sys/epoll.h> +#include <sys/eventfd.h> + +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..c6c25458f --- /dev/null +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -0,0 +1,18 @@ +/* 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 61db998e5..f83c98b32 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 @@ -16,6 +19,8 @@ struct pfe { void *ddr_baseaddr; uint64_t ddr_size; void *cbus_baseaddr; + 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 09d6ceec3..8764d5d15 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -16,9 +16,32 @@ struct pfe_vdev_init_params { int8_t gem_id; }; + +static void *cbus_emac_base[3]; +static void *cbus_gpi_base[3]; struct pfe *g_pfe; unsigned int pfe_svr = SVR_LS1012A_REV1; +/* 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) { @@ -96,6 +119,8 @@ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) struct rte_eth_dev_data *data = NULL; 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; if (id >= pfe->max_intf) { @@ -113,15 +138,38 @@ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) rte_free(data); 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; rte_memcpy(data, eth_dev->data, sizeof(*data)); 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; @@ -139,6 +187,7 @@ static int 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; @@ -156,6 +205,57 @@ static int 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, @@ -216,7 +316,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 = { -1 @@ -280,6 +380,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; fd = open("/dev/mem", O_RDWR); @@ -309,6 +410,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) @@ -328,6 +465,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: err: rte_free(g_pfe); @@ -355,6 +498,12 @@ pmd_pfe_remove(struct rte_vdev_device *vdev) pfe_eth_exit(eth_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; + } return 0; } -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 06/13] net/ppfe: add MAC and host interface initialisation 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 06/13] net/ppfe: add MAC and host interface initialisation Gagandeep Singh @ 2019-09-26 17:00 ` Ferruh Yigit 0 siblings, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-09-26 17:00 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas, Akhil Goyal On 8/28/2019 12:08 PM, Gagandeep Singh wrote: > 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 <g.singh@nxp.com> > Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> <...> > @@ -10,14 +10,22 @@ 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 > > +# depends on v2p APIs which uses experimental API > +CFLAGS += -DALLOW_EXPERIMENTAL_API Can you please list of experimental APIs used in the make and meson files, as comment. That may help us to trace when to remove this flag as APIs promoted to non experimental state. ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 07/13] net/ppfe: add device start stop operations 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (5 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 06/13] net/ppfe: add MAC and host interface initialisation Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 08/13] net/ppfe: add queue setup and release operations Gagandeep Singh ` (6 subsequent siblings) 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch adds device start, stop and close operations. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- drivers/net/ppfe/Makefile | 2 +- drivers/net/ppfe/pfe_eth.h | 1 + drivers/net/ppfe/pfe_hif.c | 136 +++++++++++++ drivers/net/ppfe/pfe_hif.h | 41 ++++ drivers/net/ppfe/pfe_hif_lib.c | 350 ++++++++++++++++++++++++++++++++- drivers/net/ppfe/pfe_hif_lib.h | 11 ++ drivers/net/ppfe/pfe_mod.h | 1 + drivers/net/ppfe/ppfe_ethdev.c | 187 ++++++++++++++++++ 8 files changed, 727 insertions(+), 2 deletions(-) diff --git a/drivers/net/ppfe/Makefile b/drivers/net/ppfe/Makefile index 4f7889e25..5c724ace0 100644 --- a/drivers/net/ppfe/Makefile +++ b/drivers/net/ppfe/Makefile @@ -30,7 +30,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 a8ce3e314..79245c306 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 908700bc1..3a044bc04 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -41,6 +41,142 @@ static void 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 c6c25458f..4c19108eb 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -5,10 +5,358 @@ #include "pfe_logs.h" #include "pfe_mod.h" -int pfe_hif_lib_init(__rte_unused struct pfe *pfe) +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 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 f83c98b32..deb19f82b 100644 --- a/drivers/net/ppfe/pfe_mod.h +++ b/drivers/net/ppfe/pfe_mod.h @@ -22,6 +22,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 8764d5d15..bb4d40077 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -64,6 +64,131 @@ pfe_soc_version_get(void) fclose(svr_file); } +/* pfe_eth_start + */ +static int pfe_eth_start(struct pfe_eth_priv_s *priv) +{ + gpi_enable(priv->GPI_baseaddr); + gemac_enable(priv->EMAC_baseaddr); + + return 0; +} + +/* pfe_eth_flush_txQ + */ +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); + } + } +} + + +/* pfe_eth_flush_tx + */ +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); +} + +/* pfe_eth_event_handler + */ +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; +} + +/* pfe_eth_open + */ +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) { @@ -98,6 +223,7 @@ pfe_eth_close_cdev(struct pfe_eth_priv_s *priv) } } + /* pfe_eth_exit */ static void @@ -112,6 +238,65 @@ pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe) pfe->nb_devs--; } +/* pfe_eth_stop + */ +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); +} + +/* pfe_eth_close + * + */ +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 void +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; +} + +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, +}; + /* pfe_eth_init_one */ static int pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id) @@ -187,6 +372,8 @@ static int 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; -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 08/13] net/ppfe: add queue setup and release operations 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (6 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 07/13] net/ppfe: add device start stop operations Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 09/13] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh ` (5 subsequent siblings) 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add RX/TX queue setup operations and supported checksum offloads. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 2 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/pfe_hif.c | 114 ++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.h | 1 + drivers/net/ppfe/pfe_hif_lib.c | 48 +++++++++++++ drivers/net/ppfe/ppfe_ethdev.c | 100 +++++++++++++++++++++++++- 6 files changed, 263 insertions(+), 3 deletions(-) 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 5c58c7837..6313229cb 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -91,6 +91,7 @@ pfe.ko is required for PHY initialisation. 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 3a044bc04..fc1a0fd91 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -41,6 +41,120 @@ static void 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 4c19108eb..d86f3ecaf 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -15,6 +15,54 @@ 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 bb4d40077..be9a7fec7 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -13,15 +13,28 @@ #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; -}; +/* 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; + static void *cbus_emac_base[3]; static void *cbus_gpi_base[3]; struct pfe *g_pfe; unsigned int pfe_svr = SVR_LS1012A_REV1; +struct pfe_vdev_init_params { + int8_t gem_id; +}; + /* pfe_gemac_init */ static int pfe_gemac_init(struct pfe_eth_priv_s *priv) @@ -287,6 +300,83 @@ 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; +} + +/* 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 = { @@ -295,6 +385,10 @@ static const struct eth_dev_ops ops = { .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, }; /* pfe_eth_init_one -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 09/13] net/ppfe: add burst enqueue and dequeue operations 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (7 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 08/13] net/ppfe: add queue setup and release operations Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 10/13] net/ppfe: add supported packet types and basic statistics Gagandeep Singh ` (4 subsequent siblings) 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add burst enqueue and dequeue operations to the ppfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- drivers/net/ppfe/pfe_hif.c | 350 +++++++++++++++++++++++++++++++++ drivers/net/ppfe/pfe_hif.h | 8 + drivers/net/ppfe/pfe_hif_lib.c | 143 ++++++++++++++ drivers/net/ppfe/pfe_hif_lib.h | 8 + drivers/net/ppfe/pfe_mod.h | 2 + drivers/net/ppfe/ppfe_ethdev.c | 141 +++++++++++++ 6 files changed, 652 insertions(+) diff --git a/drivers/net/ppfe/pfe_hif.c b/drivers/net/ppfe/pfe_hif.c index fc1a0fd91..b59a13597 100644 --- a/drivers/net/ppfe/pfe_hif.c +++ b/drivers/net/ppfe/pfe_hif.c @@ -41,6 +41,37 @@ static void 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 @@ -254,6 +285,322 @@ static void 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) { @@ -491,6 +838,9 @@ void 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 d86f3ecaf..a1ba76ca9 100644 --- a/drivers/net/ppfe/pfe_hif_lib.c +++ b/drivers/net/ppfe/pfe_hif_lib.c @@ -356,6 +356,149 @@ int 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 deb19f82b..9466e3dcb 100644 --- a/drivers/net/ppfe/pfe_mod.h +++ b/drivers/net/ppfe/pfe_mod.h @@ -7,6 +7,8 @@ struct pfe; +#include <rte_ethdev.h> + #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 be9a7fec7..019a331ac 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -2,6 +2,7 @@ * Copyright 2019 NXP */ +#include <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> @@ -137,6 +138,120 @@ static int 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; +} + + /* pfe_eth_open */ static int pfe_eth_open(struct rte_eth_dev *dev) @@ -175,6 +290,21 @@ static int 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 */ @@ -198,6 +328,14 @@ static int 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; @@ -259,6 +397,9 @@ static void 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; } /* pfe_eth_close -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 10/13] net/ppfe: add supported packet types and basic statistics 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (8 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 09/13] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 11/13] net/ppfe: add MTU and MAC address set operations Gagandeep Singh ` (3 subsequent siblings) 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh 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 <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 6313229cb..099abfee6 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -92,6 +92,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 019a331ac..9576a1a69 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -520,6 +520,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, @@ -530,6 +571,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, }; /* pfe_eth_init_one -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 11/13] net/ppfe: add MTU and MAC address set operations 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (9 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 10/13] net/ppfe: add supported packet types and basic statistics Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 12/13] net/ppfe: add allmulticast and promiscuous Gagandeep Singh ` (2 subsequent siblings) 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh To update MAC address or MTU, operations are added to the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/ppfe_ethdev.c | 62 +++++++++++++++++++++++++++++++ 3 files changed, 64 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 099abfee6..b4a756258 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -94,6 +94,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 9576a1a69..9215ec026 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -6,6 +6,7 @@ #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> +#include <rte_ether.h> #include <of.h> #include "pfe_logs.h" @@ -541,6 +542,58 @@ 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) @@ -572,6 +625,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, }; @@ -584,6 +639,7 @@ static int 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; if (id >= pfe->max_intf) { @@ -649,6 +705,12 @@ static int 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); -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 12/13] net/ppfe: add allmulticast and promiscuous 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (10 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 11/13] net/ppfe: add MTU and MAC address set operations Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 13/13] net/ppfe: add link status update Gagandeep Singh 2019-09-26 17:28 ` [dpdk-dev] [PATCH v2 00/13] introduces ppfe network PMD Ferruh Yigit 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch adds support to enable multicast and promiscuous mode. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 2 ++ doc/guides/nics/ppfe.rst | 2 ++ drivers/net/ppfe/ppfe_ethdev.c | 36 +++++++++++++++++++++++++++++++ 3 files changed, 40 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 b4a756258..71b049198 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -95,6 +95,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 9215ec026..165b1ce6e 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -542,6 +542,39 @@ pfe_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } +static void +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); +} + +static void +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); +} + +static void +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; +} + static int pfe_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { @@ -625,6 +658,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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v2 13/13] net/ppfe: add link status update 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (11 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 12/13] net/ppfe: add allmulticast and promiscuous Gagandeep Singh @ 2019-08-28 11:08 ` Gagandeep Singh 2019-09-26 17:28 ` [dpdk-dev] [PATCH v2 00/13] introduces ppfe network PMD Ferruh Yigit 13 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-08-28 11:08 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add link related operations like link update, up and down. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/ppfe.ini | 1 + doc/guides/nics/ppfe.rst | 1 + drivers/net/ppfe/ppfe_ethdev.c | 103 ++++++++++++++++++++++++++++++ 3 files changed, 105 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 71b049198..6c19a2c73 100644 --- a/doc/guides/nics/ppfe.rst +++ b/doc/guides/nics/ppfe.rst @@ -97,6 +97,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 165b1ce6e..215858cc6 100644 --- a/drivers/net/ppfe/ppfe_ethdev.c +++ b/drivers/net/ppfe/ppfe_ethdev.c @@ -2,6 +2,8 @@ * Copyright 2019 NXP */ +#include <sys/ioctl.h> +#include <sys/epoll.h> #include <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> @@ -542,6 +544,90 @@ 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 void pfe_promiscuous_enable(struct rte_eth_dev *dev) { @@ -575,6 +661,20 @@ pfe_allmulticast_enable(struct rte_eth_dev *dev) dev->data->all_multicast = 1; } +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) { @@ -658,9 +758,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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 00/13] introduces ppfe network PMD 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh ` (12 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 13/13] net/ppfe: add link status update Gagandeep Singh @ 2019-09-26 17:28 ` Ferruh Yigit 2019-09-27 14:55 ` Gagandeep Singh 13 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-09-26 17:28 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas On 8/28/2019 12:08 PM, Gagandeep Singh wrote: > This series introduces ppfe (programmable packet > forwarding engine) network poll mode driver for > NXP SoC ls1012a. > > First patch of this series move OF library code from > dpaa bus to a common folder as PPFE also uses the > same library for getting information from the device > tree. > This patch is included in this series so that > compilation by CI don't break. > > V2 Change-log: > * fix compilation break for clang3.4 and gcc 4.8 > * fix checkpatch errors > > Gagandeep Singh (12): > net/ppfe: introduce ppfe net poll mode driver > doc: add guide for ppfe net PMD > net/ppfe: support dynamic logging > net/ppfe: add HW specific macros and operations > net/ppfe: add MAC and host interface initialisation > net/ppfe: add device start stop operations > net/ppfe: add queue setup and release operations > net/ppfe: add burst enqueue and dequeue operations > net/ppfe: add supported packet types and basic statistics > net/ppfe: add MTU and MAC address set operations > net/ppfe: add allmulticast and promiscuous > net/ppfe: add link status update > > Hemant Agrawal (1): > common/dpaax: moving OF lib code from dpaa bus > Hi Gagandeep, Hemant, There has been some ethdev API changes in next-net and driver needs to comply with them, can you please send a new version rebasing latest next-net? Meanwhile I put some comments to patches, please check them as well, I am planning to do another round on next version. Thanks, ferruh ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v2 00/13] introduces ppfe network PMD 2019-09-26 17:28 ` [dpdk-dev] [PATCH v2 00/13] introduces ppfe network PMD Ferruh Yigit @ 2019-09-27 14:55 ` Gagandeep Singh 0 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-09-27 14:55 UTC (permalink / raw) To: Ferruh Yigit, dev; +Cc: thomas Hi Ferruh, > > Gagandeep Singh (12): > > net/ppfe: introduce ppfe net poll mode driver > > doc: add guide for ppfe net PMD > > net/ppfe: support dynamic logging > > net/ppfe: add HW specific macros and operations > > net/ppfe: add MAC and host interface initialisation > > net/ppfe: add device start stop operations > > net/ppfe: add queue setup and release operations > > net/ppfe: add burst enqueue and dequeue operations > > net/ppfe: add supported packet types and basic statistics > > net/ppfe: add MTU and MAC address set operations > > net/ppfe: add allmulticast and promiscuous > > net/ppfe: add link status update > > > > Hemant Agrawal (1): > > common/dpaax: moving OF lib code from dpaa bus > > > > Hi Gagandeep, Hemant, > > There has been some ethdev API changes in next-net and driver needs to comply > with them, can you please send a new version rebasing latest next-net? > > Meanwhile I put some comments to patches, please check them as well, I am > planning to do another round on next version. > > Thanks, > ferruh I saw your comments, will handle them in next version of this series. Thanks, Gagan ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 00/14] introduces ppfe network PMD 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh ` (14 preceding siblings ...) 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh @ 2019-10-01 11:01 ` Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh ` (14 more replies) 15 siblings, 15 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:01 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This series introduces ppfe (programmable packet forwarding engine) network poll mode driver for NXP SoC ls1012a. First patch of this series move OF library code from dpaa bus to a common folder as PPFE also uses the same library for getting information from the device tree. This patch is included in this series so that compilation by CI don't break. V2 Change-log: * fix compilation break for clang3.4 and gcc 4.8 * fix checkpatch errors V3 Change-log: * Release notes updated for PPFE PMD * Experimental APIs list added in Makefile and meson * Dynamic logging added * PPFE documentation is updated for kernel module "pfe.ko" and parameter "intf" is mentioned. * of.h and of.c are renamed to dpaa_of.h and dpaa_of.c * enable PPFE compilation only in 'common_armv8a_linux' * PFE_CDEV_ETH_COUNT updated 2, as only 2 eth devices supported. * Comment updated for "pfe_us_cdev" device * functions prototype updated * intf params value check added during parsing and unwanted port id checks removed. * unwanted dev->data memcpy removed. * munmap and rte_eth_dev_release_port added in error case * atoi replaced with strtol * add static to global variable g_pfe Gagandeep Singh (13): net/ppfe: introduce ppfe net poll mode driver doc: add guide for ppfe net PMD net/ppfe: support dynamic logging net/ppfe: add HW specific macros and operations net/ppfe: add MAC and host interface initialisation net/ppfe: add device start stop operations net/ppfe: add queue setup and release operations net/ppfe: add burst enqueue and dequeue operations net/ppfe: add supported packet types and basic statistics net/ppfe: add MTU and MAC address set operations net/ppfe: add allmulticast and promiscuous net/ppfe: add link status update doc: add NXP PPFE PMD in release notes Hemant Agrawal (1): common/dpaax: moving OF lib code from dpaa bus MAINTAINERS | 7 + config/common_armv8a_linux | 5 + config/common_base | 5 + doc/guides/nics/features/ppfe.ini | 17 + doc/guides/nics/index.rst | 1 + doc/guides/nics/ppfe.rst | 180 +++ doc/guides/rel_notes/release_19_11.rst | 5 + 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/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/net/meson.build | 1 + drivers/net/ppfe/Makefile | 38 + 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 | 422 ++++++ drivers/net/ppfe/meson.build | 19 + drivers/net/ppfe/pfe_eth.h | 74 + drivers/net/ppfe/pfe_hal.c | 635 +++++++++ drivers/net/ppfe/pfe_hif.c | 868 ++++++++++++ drivers/net/ppfe/pfe_hif.h | 156 +++ drivers/net/ppfe/pfe_hif_lib.c | 576 ++++++++ drivers/net/ppfe/pfe_hif_lib.h | 181 +++ drivers/net/ppfe/pfe_logs.h | 31 + drivers/net/ppfe/pfe_mod.h | 64 + drivers/net/ppfe/ppfe_ethdev.c | 1186 +++++++++++++++++ drivers/net/ppfe/rte_pmd_ppfe_version.map | 4 + drivers/raw/dpaa2_cmdif/Makefile | 1 + drivers/raw/dpaa2_qdma/Makefile | 1 + mk/rte.app.mk | 1 + 65 files changed, 5610 insertions(+), 54 deletions(-) create mode 100644 doc/guides/nics/features/ppfe.ini create mode 100644 doc/guides/nics/ppfe.rst 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%) create mode 100644 drivers/net/ppfe/Makefile 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 create mode 100644 drivers/net/ppfe/meson.build create mode 100644 drivers/net/ppfe/pfe_eth.h 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 create mode 100644 drivers/net/ppfe/pfe_logs.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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 01/14] common/dpaax: moving OF lib code from dpaa bus 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh @ 2019-10-01 11:01 ` Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh ` (13 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:01 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Hemant Agrawal From: Hemant Agrawal <hemant.agrawal@nxp.com> This code is being shared by more than 1 type of driver. Common is most appropriate place for it. Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com> --- 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 <fman.h> -#include <of.h> +#include <dpaa_of.h> #include <rte_malloc.h> #include <rte_dpaa_logs.h> #include <rte_string_fns.h> 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 <inttypes.h> -#include <of.h> +#include <dpaa_of.h> #include <net/if.h> #include <sys/ioctl.h> #include <error.h> 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 <of.h> +#include <compat.h> +#include <dpaa_of.h> /* 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 <rte_bus.h> #include <rte_mbuf_pool_ops.h> +#include <dpaa_of.h> #include <rte_dpaa_bus.h> #include <rte_dpaa_logs.h> #include <dpaax_iova_table.h> @@ -39,7 +40,6 @@ #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> 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 <dpaa_list.h> #include <dpaa_bits.h> #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 <rte_ether.h> #include <compat.h> +#include <dpaa_list.h> #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 <compat.h> +#include <dpaa_list.h> #include <fsl_qman.h> #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 <rte_mempool.h> #include <dpaax_iova_table.h> +#include <dpaa_of.h> #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> #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 <of.h> +#include <dpaa_of.h> +#include <assert.h> #include <rte_string_fns.h> -#include <rte_dpaa_logs.h> +#include <dpaax_logs.h> 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 <compat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <stdlib.h> +#include <inttypes.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> +#include <fcntl.h> +#include <glob.h> +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <limits.h> +#include <inttypes.h> +#include <rte_common.h> +#include <dpaa_list.h> #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 <hw/desc/common.h> #include <hw/desc/algo.h> -#include <of.h> +#include <dpaa_of.h> #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 <fsl_usd.h> #include <fsl_qman.h> -#include <of.h> +#include <dpaa_of.h> /* RTA header files */ #include <hw/desc/common.h> 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 <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> +#include <dpaa_of.h> #include <netcfg.h> #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 <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> +#include <dpaa_of.h> #include <netcfg.h> #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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh @ 2019-10-01 11:01 ` Gagandeep Singh 2019-10-04 15:38 ` Ferruh Yigit 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD Gagandeep Singh ` (12 subsequent siblings) 14 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:01 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal 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 <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- 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 <g.singh@nxp.com> +M: Akhil Goyal <akhil.goyal@nxp.com> +F: drivers/net/ppfe/ +F: doc/guides/nics/features/ppfe.ini + QLogic bnx2x M: Rasesh Mody <rmody@marvell.com> M: Shahed Shaikh <shshaikh@marvell.com> 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 <compat.h> +#include <rte_ethdev.h> +#include <rte_ethdev_vdev.h> + +#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 <rte_kvargs.h> +#include <rte_ethdev_vdev.h> +#include <rte_bus_vdev.h> +#include <dpaa_of.h> + +#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 "=<int> "); 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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh @ 2019-10-04 15:38 ` Ferruh Yigit 2019-10-09 6:52 ` Gagandeep Singh 0 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-10-04 15:38 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas, Akhil Goyal On 10/1/2019 12:01 PM, Gagandeep Singh wrote: > 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 <g.singh@nxp.com> > Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> <...> > @@ -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/ This driver is a virtual driver and using something like 'cbus', btw, out of curiosity would you mind giving some detail what cbus is? In that case why need to include 'bus/dpaa' files? Is this PMD depends on 'dpaa' bus? Or should some 'bus/dpaa' files indeed be in the 'common/dpaax'? ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver 2019-10-04 15:38 ` Ferruh Yigit @ 2019-10-09 6:52 ` Gagandeep Singh 0 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-09 6:52 UTC (permalink / raw) To: Ferruh Yigit, dev; +Cc: thomas, Akhil Goyal > <...> > > > @@ -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/ > > This driver is a virtual driver and using something like 'cbus', btw, out of > curiosity would you mind giving some detail what cbus is? cbus (crate bus) is a NXP PFE IP internal bus. To access other IPs (mac, hif, bmu etc.) registers, we use base address of cbus and then we use HIF (host interface) to create virtual interfaces, which then used by the driver. > > In that case why need to include 'bus/dpaa' files? Is this PMD depends on 'dpaa' > bus? Or should some 'bus/dpaa' files indeed be in the 'common/dpaax'? PFE driver shouldn't be dependent on dpaa bus. There are some common functions and macros defined in dpaa/compat.h and pfe driver is dependent on it. I will remove the dependency on dpaa bus and move the compat.h to common/dpaax. ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh @ 2019-10-01 11:01 ` Gagandeep Singh 2019-10-04 15:41 ` Ferruh Yigit 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 04/14] net/ppfe: support dynamic logging Gagandeep Singh ` (11 subsequent siblings) 14 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:01 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh 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 <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 <g.singh@nxp.com> M: Akhil Goyal <akhil.goyal@nxp.com> +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 +<https://nxp.com/ls1012a>`_. + +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 <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_. + +2. **Linux Kernel** + + It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_. + +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 <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_. + +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 <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_ + +- **pfe kernel module** + + pfe kernel module can be obtained from NXP Layerscape software development kit at + location `/lib/modules/<kernel version>/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 <pmd_build_and_test>` +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 + + <dpdk app> <EAL args> --vdev="eth_pfe0,intf=0" --vdev="eth_pfe1,intf=1" -- ... + + +Limitations +~~~~~~~~~~~ + +- Multi buffer pool cannot be supported. -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD Gagandeep Singh @ 2019-10-04 15:41 ` Ferruh Yigit 2019-10-09 6:54 ` Gagandeep Singh 0 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-10-04 15:41 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas On 10/1/2019 12:01 PM, Gagandeep Singh wrote: > 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 <g.singh@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> > Acked-by: Akhil Goyal <akhil.goyal@nxp.com> <...> > +Driver compilation and testing > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + > +Follow instructions available in the document > +:ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>` > +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 > + > + <dpdk app> <EAL args> --vdev="eth_pfe0,intf=0" --vdev="eth_pfe1,intf=1" -- ... Previously "eth_" was the prefix for the virtual devices, we have renamed it to "net_" [1], for this new PMD, can you please use 'net_pfe' for consistency? Also the driver name is 'ppfe', it is under 'net/ppfe' folder, but the device name is 'pfe'. Is there any specific reason for this? Would it be better to stick 'pfe' or 'ppfe' everywhere? [1] That is why we have alias device names, to keep backward compatibility for "eth_". ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD 2019-10-04 15:41 ` Ferruh Yigit @ 2019-10-09 6:54 ` Gagandeep Singh 0 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-09 6:54 UTC (permalink / raw) To: Ferruh Yigit, dev; +Cc: thomas > <...> > > > +Driver compilation and testing > > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > + > > +Follow instructions available in the document > > +:ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>` > > +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 > > + > > + <dpdk app> <EAL args> --vdev="eth_pfe0,intf=0" --vdev="eth_pfe1,intf=1" > -- ... > > Previously "eth_" was the prefix for the virtual devices, we have renamed it to > "net_" [1], for this new PMD, can you please use 'net_pfe' for consistency? > > Also the driver name is 'ppfe', it is under 'net/ppfe' folder, but the device > name is 'pfe'. Is there any specific reason for this? > Would it be better to stick 'pfe' or 'ppfe' everywhere? Ok, I will change the interfaces names to net_pfe and will rename the ppfe to pfe everywhere. > > [1] > That is why we have alias device names, to keep backward compatibility for > "eth_". ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 04/14] net/ppfe: support dynamic logging 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (2 preceding siblings ...) 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD Gagandeep Singh @ 2019-10-01 11:01 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 05/14] net/ppfe: add HW specific macros and operations Gagandeep Singh ` (10 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:01 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch introduces logging for the ppfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 <rte_bus_vdev.h> #include <dpaa_of.h> +#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 "=<int> "); + +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); +} -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 05/14] net/ppfe: add HW specific macros and operations 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (3 preceding siblings ...) 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 04/14] net/ppfe: support dynamic logging Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 06/14] net/ppfe: add MAC and host interface initialisation Gagandeep Singh ` (9 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch add some hardware specific macros and functions that will be used by the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- 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 <compat.h> + +#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 <compat.h> + +/* @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 <linux/ethtool.h> + +#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_ */ -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 06/14] net/ppfe: add MAC and host interface initialisation 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (4 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 05/14] net/ppfe: add HW specific macros and operations Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations Gagandeep Singh ` (8 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal 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 <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- 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 <sys/ioctl.h> +#include <sys/epoll.h> +#include <sys/eventfd.h> + +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; } -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (5 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 06/14] net/ppfe: add MAC and host interface initialisation Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-04 15:42 ` Ferruh Yigit 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 08/14] net/ppfe: add queue setup and release operations Gagandeep Singh ` (7 subsequent siblings) 14 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch adds device start, stop and close operations. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- 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; -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations Gagandeep Singh @ 2019-10-04 15:42 ` Ferruh Yigit 2019-10-09 6:54 ` Gagandeep Singh 0 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-10-04 15:42 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas, Akhil Goyal On 10/1/2019 12:02 PM, Gagandeep Singh wrote: > This patch adds device start, stop and close > operations. > > Signed-off-by: Gagandeep Singh <g.singh@nxp.com> > Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> <...> > +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; Since set MTU supported in this patchet, it can be good to set 'min_mtu' & 'max_mtu' too. ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations 2019-10-04 15:42 ` Ferruh Yigit @ 2019-10-09 6:54 ` Gagandeep Singh 0 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-09 6:54 UTC (permalink / raw) To: Ferruh Yigit, dev; +Cc: thomas, Akhil Goyal > -----Original Message----- > From: Ferruh Yigit <ferruh.yigit@intel.com> > Sent: Friday, October 4, 2019 9:13 PM > To: Gagandeep Singh <G.Singh@nxp.com>; dev@dpdk.org > Cc: thomas@monjalon.net; Akhil Goyal <akhil.goyal@nxp.com> > Subject: Re: [PATCH v3 07/14] net/ppfe: add device start stop operations > > On 10/1/2019 12:02 PM, Gagandeep Singh wrote: > > This patch adds device start, stop and close > > operations. > > > > Signed-off-by: Gagandeep Singh <g.singh@nxp.com> > > Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> > > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> > > <...> > > > +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; > > Since set MTU supported in this patchet, it can be good to set 'min_mtu' & > 'max_mtu' too. Ok. ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 08/14] net/ppfe: add queue setup and release operations 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (6 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 09/14] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh ` (6 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add RX/TX queue setup operations and supported checksum offloads. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 09/14] net/ppfe: add burst enqueue and dequeue operations 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (7 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 08/14] net/ppfe: add queue setup and release operations Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 10/14] net/ppfe: add supported packet types and basic statistics Gagandeep Singh ` (5 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add burst enqueue and dequeue operations to the ppfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 <rte_ethdev.h> + #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 <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> @@ -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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 10/14] net/ppfe: add supported packet types and basic statistics 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (8 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 09/14] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 11/14] net/ppfe: add MTU and MAC address set operations Gagandeep Singh ` (4 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh 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 <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 11/14] net/ppfe: add MTU and MAC address set operations 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (9 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 10/14] net/ppfe: add supported packet types and basic statistics Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 12/14] net/ppfe: add allmulticast and promiscuous Gagandeep Singh ` (3 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh To update MAC address or MTU, operations are added to the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> +#include <rte_ether.h> #include <dpaa_of.h> #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); -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 12/14] net/ppfe: add allmulticast and promiscuous 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (10 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 11/14] net/ppfe: add MTU and MAC address set operations Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update Gagandeep Singh ` (2 subsequent siblings) 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch adds support to enable multicast and promiscuous mode. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (11 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 12/14] net/ppfe: add allmulticast and promiscuous Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-04 15:43 ` Ferruh Yigit 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 14/14] doc: add NXP PPFE PMD in release notes Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh 14 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add link related operations like link update, up and down. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- 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 <sys/ioctl.h> +#include <sys/epoll.h> #include <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> @@ -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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update Gagandeep Singh @ 2019-10-04 15:43 ` Ferruh Yigit 2019-10-09 6:57 ` Gagandeep Singh 0 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-10-04 15:43 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas On 10/1/2019 12:02 PM, Gagandeep Singh wrote: > This patch add link related operations like > link update, up and down. > > Signed-off-by: Gagandeep Singh <g.singh@nxp.com> > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> > Acked-by: Akhil Goyal <akhil.goyal@nxp.com> <...> > + > +static int > +pfe_eth_link_update(struct rte_eth_dev *dev, > + int wait_to_complete __rte_unused) nitpicking but, this can be single line ... ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update 2019-10-04 15:43 ` Ferruh Yigit @ 2019-10-09 6:57 ` Gagandeep Singh 0 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-09 6:57 UTC (permalink / raw) To: Ferruh Yigit, dev; +Cc: thomas > -----Original Message----- > From: Ferruh Yigit <ferruh.yigit@intel.com> > Sent: Friday, October 4, 2019 9:13 PM > To: Gagandeep Singh <G.Singh@nxp.com>; dev@dpdk.org > Cc: thomas@monjalon.net > Subject: Re: [PATCH v3 13/14] net/ppfe: add link status update > > On 10/1/2019 12:02 PM, Gagandeep Singh wrote: > > This patch add link related operations like > > link update, up and down. > > > > Signed-off-by: Gagandeep Singh <g.singh@nxp.com> > > Acked-by: Nipun Gupta <nipun.gupta@nxp.com> > > Acked-by: Akhil Goyal <akhil.goyal@nxp.com> > > <...> > > > + > > +static int > > +pfe_eth_link_update(struct rte_eth_dev *dev, > > + int wait_to_complete __rte_unused) > > nitpicking but, this can be single line ... Sure. ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v3 14/14] doc: add NXP PPFE PMD in release notes 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (12 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update Gagandeep Singh @ 2019-10-01 11:02 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh 14 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-01 11:02 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh Update release notes for NXP PPFE driver supported for 19.11. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> --- 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 ------------- -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh ` (13 preceding siblings ...) 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 14/14] doc: add NXP PPFE PMD in release notes Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh ` (15 more replies) 14 siblings, 16 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This series introduces pfe (packet forwarding engine) network poll mode driver for NXP SoC ls1012a. First patch of this series move OF library code from dpaa bus to a common folder as PFE also uses the same library for getting information from the device tree. This patch is included in this series so that compilation by CI don't break. V2 Change-log: * fix compilation break for clang3.4 and gcc 4.8 * fix checkpatch errors V3 Change-log: * Release notes updated for PPFE PMD * Experimental APIs list added in Makefile and meson * Dynamic logging added * PPFE documentation is updated for kernel module "pfe.ko" and parameter "intf" is mentioned. * of.h and of.c are renamed to dpaa_of.h and dpaa_of.c * enable PPFE compilation only in 'common_armv8a_linux' * PFE_CDEV_ETH_COUNT updated 2, as only 2 eth devices supported. * Comment updated for "pfe_us_cdev" device * functions prototype updated * intf params value check added during parsing and unwanted port id checks removed. * unwanted dev->data memcpy removed. * munmap and rte_eth_dev_release_port added in error case * atoi replaced with strtol * add static to global variable g_pfe V4 Change-log: * DPAA dependency removed by moving compat.h from bus/dpaa/include to common/dpaax * Updated interface name to net_pfe in document * Updated driver name to PFE from PPFE everywhere for consistency * min_mtu and max_mtu added Gagandeep Singh (13): net/pfe: introduce pfe net poll mode driver doc: add guide for pfe net PMD net/pfe: support dynamic logging net/pfe: add HW specific macros and operations net/pfe: add MAC and host interface initialisation net/pfe: add device start stop operations net/pfe: add queue setup and release operations net/pfe: add burst enqueue and dequeue operations net/pfe: add supported packet types and basic statistics net/pfe: add MTU and MAC address set operations net/pfe: add allmulticast and promiscuous net/pfe: add link status update doc: add NXP PFE PMD in release notes Hemant Agrawal (1): common/dpaax: moving OF lib code from dpaa bus MAINTAINERS | 7 + config/common_armv8a_linux | 5 + config/common_base | 5 + doc/guides/nics/features/pfe.ini | 17 + doc/guides/nics/index.rst | 1 + doc/guides/nics/pfe.rst | 180 +++ doc/guides/rel_notes/release_19_11.rst | 5 + 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/base/qbman/qman.c | 2 + drivers/bus/dpaa/dpaa_bus.c | 2 +- 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}/compat.h | 3 - .../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/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/net/meson.build | 1 + drivers/net/pfe/Makefile | 37 + drivers/net/pfe/base/cbus.h | 66 + drivers/net/pfe/base/cbus/bmu.h | 41 + drivers/net/pfe/base/cbus/class_csr.h | 277 ++++ drivers/net/pfe/base/cbus/emac_mtip.h | 231 ++++ drivers/net/pfe/base/cbus/gpi.h | 77 ++ drivers/net/pfe/base/cbus/hif.h | 86 ++ drivers/net/pfe/base/cbus/hif_nocpy.h | 36 + drivers/net/pfe/base/cbus/tmu_csr.h | 154 +++ drivers/net/pfe/base/cbus/util_csr.h | 47 + drivers/net/pfe/base/pfe.h | 422 ++++++ drivers/net/pfe/meson.build | 19 + drivers/net/pfe/pfe_eth.h | 76 ++ drivers/net/pfe/pfe_ethdev.c | 1192 +++++++++++++++++ drivers/net/pfe/pfe_hal.c | 629 +++++++++ drivers/net/pfe/pfe_hif.c | 868 ++++++++++++ drivers/net/pfe/pfe_hif.h | 156 +++ drivers/net/pfe/pfe_hif_lib.c | 576 ++++++++ drivers/net/pfe/pfe_hif_lib.h | 181 +++ drivers/net/pfe/pfe_logs.h | 31 + drivers/net/pfe/pfe_mod.h | 64 + drivers/net/pfe/rte_pmd_pfe_version.map | 4 + drivers/raw/dpaa2_cmdif/Makefile | 1 + drivers/raw/dpaa2_qdma/Makefile | 1 + mk/rte.app.mk | 1 + 66 files changed, 5613 insertions(+), 56 deletions(-) create mode 100644 doc/guides/nics/features/pfe.ini create mode 100644 doc/guides/nics/pfe.rst rename drivers/{bus/dpaa/include => common/dpaax}/compat.h (99%) 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%) create mode 100644 drivers/net/pfe/Makefile create mode 100644 drivers/net/pfe/base/cbus.h create mode 100644 drivers/net/pfe/base/cbus/bmu.h create mode 100644 drivers/net/pfe/base/cbus/class_csr.h create mode 100644 drivers/net/pfe/base/cbus/emac_mtip.h create mode 100644 drivers/net/pfe/base/cbus/gpi.h create mode 100644 drivers/net/pfe/base/cbus/hif.h create mode 100644 drivers/net/pfe/base/cbus/hif_nocpy.h create mode 100644 drivers/net/pfe/base/cbus/tmu_csr.h create mode 100644 drivers/net/pfe/base/cbus/util_csr.h create mode 100644 drivers/net/pfe/base/pfe.h create mode 100644 drivers/net/pfe/meson.build create mode 100644 drivers/net/pfe/pfe_eth.h create mode 100644 drivers/net/pfe/pfe_ethdev.c create mode 100644 drivers/net/pfe/pfe_hal.c create mode 100644 drivers/net/pfe/pfe_hif.c create mode 100644 drivers/net/pfe/pfe_hif.h create mode 100644 drivers/net/pfe/pfe_hif_lib.c create mode 100644 drivers/net/pfe/pfe_hif_lib.h create mode 100644 drivers/net/pfe/pfe_logs.h create mode 100644 drivers/net/pfe/pfe_mod.h create mode 100644 drivers/net/pfe/rte_pmd_pfe_version.map -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 01/14] common/dpaax: moving OF lib code from dpaa bus 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 17:01 ` Ferruh Yigit 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 02/14] net/pfe: introduce pfe net poll mode driver Gagandeep Singh ` (14 subsequent siblings) 15 siblings, 1 reply; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Hemant Agrawal From: Hemant Agrawal <hemant.agrawal@nxp.com> This code is being shared by more than 1 type of driver. Common is most appropriate place for it. Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com> --- 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/base/qbman/qman.c | 2 + drivers/bus/dpaa/dpaa_bus.c | 2 +- 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}/compat.h | 3 - .../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 + 34 files changed, 120 insertions(+), 56 deletions(-) rename drivers/{bus/dpaa/include => common/dpaax}/compat.h (99%) 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 <fman.h> -#include <of.h> +#include <dpaa_of.h> #include <rte_malloc.h> #include <rte_dpaa_logs.h> #include <rte_string_fns.h> 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 <inttypes.h> -#include <of.h> +#include <dpaa_of.h> #include <net/if.h> #include <sys/ioctl.h> #include <error.h> 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 <of.h> +#include <compat.h> +#include <dpaa_of.h> /* For 2-element tables related to cache-inhibited and cache-enabled mappings */ #define DPAA_PORTAL_CE 0 diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c index 96208bc40..be321fc66 100644 --- a/drivers/bus/dpaa/base/qbman/qman.c +++ b/drivers/bus/dpaa/base/qbman/qman.c @@ -11,6 +11,8 @@ #include <rte_eventdev.h> #include <rte_byteorder.h> +#include <dpaa_bits.h> + /* Compilation constants */ #define DQRR_MAXFILL 15 #define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */ diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c index 1d8a294b1..d028ef3be 100644 --- a/drivers/bus/dpaa/dpaa_bus.c +++ b/drivers/bus/dpaa/dpaa_bus.c @@ -32,6 +32,7 @@ #include <rte_bus.h> #include <rte_mbuf_pool_ops.h> +#include <dpaa_of.h> #include <rte_dpaa_bus.h> #include <rte_dpaa_logs.h> #include <dpaax_iova_table.h> @@ -39,7 +40,6 @@ #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> int dpaa_logtype_bus; 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 <rte_ether.h> #include <compat.h> +#include <dpaa_list.h> #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 3c26d6ccb..263d9bb97 100644 --- a/drivers/bus/dpaa/include/fsl_usd.h +++ b/drivers/bus/dpaa/include/fsl_usd.h @@ -10,6 +10,7 @@ #define __FSL_USD_H #include <compat.h> +#include <dpaa_list.h> #include <fsl_qman.h> #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 9601aebdd..c2b237534 100644 --- a/drivers/bus/dpaa/rte_dpaa_bus.h +++ b/drivers/bus/dpaa/rte_dpaa_bus.h @@ -10,10 +10,10 @@ #include <rte_mempool.h> #include <dpaax_iova_table.h> +#include <dpaa_of.h> #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> #include <netcfg.h> #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/compat.h b/drivers/common/dpaax/compat.h similarity index 99% rename from drivers/bus/dpaa/include/compat.h rename to drivers/common/dpaax/compat.h index 277ce6369..12c9d9917 100644 --- a/drivers/bus/dpaa/include/compat.h +++ b/drivers/common/dpaax/compat.h @@ -390,7 +390,4 @@ 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 <dpaa_list.h> -#include <dpaa_bits.h> - #endif /* __COMPAT_H */ 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 <of.h> +#include <dpaa_of.h> +#include <assert.h> #include <rte_string_fns.h> -#include <rte_dpaa_logs.h> +#include <dpaax_logs.h> 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 <compat.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <stdlib.h> +#include <inttypes.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> +#include <fcntl.h> +#include <glob.h> +#include <errno.h> +#include <ctype.h> +#include <unistd.h> +#include <limits.h> +#include <inttypes.h> +#include <rte_common.h> +#include <dpaa_list.h> #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 <hw/desc/common.h> #include <hw/desc/algo.h> -#include <of.h> +#include <dpaa_of.h> #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 1754862be..39f091cd9 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -27,7 +27,7 @@ #include <fsl_usd.h> #include <fsl_qman.h> -#include <of.h> +#include <dpaa_of.h> /* RTA header files */ #include <hw/desc/common.h> 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 <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> +#include <dpaa_of.h> #include <netcfg.h> #define MAX_DPAA_CORES 4 diff --git a/drivers/net/dpaa/dpaa_rxtx.c b/drivers/net/dpaa/dpaa_rxtx.c index 2de1a1a7e..bbe615099 100644 --- a/drivers/net/dpaa/dpaa_rxtx.c +++ b/drivers/net/dpaa/dpaa_rxtx.c @@ -44,7 +44,7 @@ #include <fsl_usd.h> #include <fsl_qman.h> #include <fsl_bman.h> -#include <of.h> +#include <dpaa_of.h> #include <netcfg.h> #define DPAA_MBUF_TO_CONTIG_FD(_mbuf, _fd, _bpid) \ diff --git a/drivers/net/dpaa2/Makefile b/drivers/net/dpaa2/Makefile index 7924871c8..e5a2d3fde 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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v4 01/14] common/dpaax: moving OF lib code from dpaa bus 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh @ 2019-10-10 17:01 ` Ferruh Yigit 0 siblings, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-10-10 17:01 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas, Hemant Agrawal On 10/10/2019 7:32 AM, Gagandeep Singh wrote: > From: Hemant Agrawal <hemant.agrawal@nxp.com> > > This code is being shared by more than 1 type of driver. > Common is most appropriate place for it. > > Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com> <...> > 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; Seems forgot to remove following APIs from 'bus/dpaa' .map file, if it is just .map file update, I can do while merging. of_find_compatible_node of_get_mac_address of_get_property > + > + local: *; No need the "local: *;" on the blocks other than first block. ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 02/14] net/pfe: introduce pfe net poll mode driver 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 03/14] doc: add guide for pfe net PMD Gagandeep Singh ` (13 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal pfe (packet forwarding engine) is a network poll mode driver for NXP SoC ls1012a. This patch introduces the framework of pfe driver with basic functions of initialisation and teardown. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- MAINTAINERS | 6 + config/common_armv8a_linux | 5 + config/common_base | 5 + doc/guides/nics/features/pfe.ini | 8 + drivers/net/Makefile | 1 + drivers/net/meson.build | 1 + drivers/net/pfe/Makefile | 27 ++ drivers/net/pfe/meson.build | 9 + drivers/net/pfe/pfe_eth.h | 73 ++++++ drivers/net/pfe/pfe_ethdev.c | 322 ++++++++++++++++++++++++ drivers/net/pfe/pfe_mod.h | 56 +++++ drivers/net/pfe/rte_pmd_pfe_version.map | 4 + mk/rte.app.mk | 1 + 13 files changed, 518 insertions(+) create mode 100644 doc/guides/nics/features/pfe.ini create mode 100644 drivers/net/pfe/Makefile create mode 100644 drivers/net/pfe/meson.build create mode 100644 drivers/net/pfe/pfe_eth.h create mode 100644 drivers/net/pfe/pfe_ethdev.c create mode 100644 drivers/net/pfe/pfe_mod.h create mode 100644 drivers/net/pfe/rte_pmd_pfe_version.map diff --git a/MAINTAINERS b/MAINTAINERS index 6adf20107..ac5e981a7 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 pfe +M: Gagandeep Singh <g.singh@nxp.com> +M: Akhil Goyal <akhil.goyal@nxp.com> +F: drivers/net/pfe/ +F: doc/guides/nics/features/pfe.ini + QLogic bnx2x M: Rasesh Mody <rmody@marvell.com> M: Shahed Shaikh <shshaikh@marvell.com> diff --git a/config/common_armv8a_linux b/config/common_armv8a_linux index 481712ebc..782877bb2 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 PFE PMD Driver +# +CONFIG_RTE_LIBRTE_PFE_PMD=y + CONFIG_RTE_SCHED_VECTOR=n diff --git a/config/common_base b/config/common_base index 6a7e00d75..6680cacc4 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 PFE PMD driver +# +CONFIG_RTE_LIBRTE_PFE_PMD=n + # NXP DPAA Bus CONFIG_RTE_LIBRTE_DPAA_BUS=n CONFIG_RTE_LIBRTE_DPAA_MEMPOOL=n diff --git a/doc/guides/nics/features/pfe.ini b/doc/guides/nics/features/pfe.ini new file mode 100644 index 000000000..9c8aeb23f --- /dev/null +++ b/doc/guides/nics/features/pfe.ini @@ -0,0 +1,8 @@ +; +; Supported features of the 'pfe' 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..cee30367a 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_PFE_PMD) += pfe 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 55f4c5176..c300afb91 100644 --- a/drivers/net/meson.build +++ b/drivers/net/meson.build @@ -38,6 +38,7 @@ drivers = ['af_packet', 'octeontx', 'octeontx2', 'pcap', + 'pfe', 'qede', 'ring', 'sfc', diff --git a/drivers/net/pfe/Makefile b/drivers/net/pfe/Makefile new file mode 100644 index 000000000..ea9da0e30 --- /dev/null +++ b/drivers/net/pfe/Makefile @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019 NXP +# + +include $(RTE_SDK)/mk/rte.vars.mk + +# +# library name +# +LIB = librte_pmd_pfe.a + +CFLAGS += -O3 $(WERROR_FLAGS) +CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax + +EXPORT_MAP := rte_pmd_pfe_version.map +LIBABIVER := 1 + +# Interfaces with DPDK +SRCS-$(CONFIG_RTE_LIBRTE_PFE_PMD) += pfe_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/pfe/meson.build b/drivers/net/pfe/meson.build new file mode 100644 index 000000000..fa5dfad69 --- /dev/null +++ b/drivers/net/pfe/meson.build @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2019 NXP + +if host_machine.system() != 'linux' + build = false +endif +deps += ['bus_dpaa'] + +sources = files('pfe_ethdev.c') diff --git a/drivers/net/pfe/pfe_eth.h b/drivers/net/pfe/pfe_eth.h new file mode 100644 index 000000000..5811b54eb --- /dev/null +++ b/drivers/net/pfe/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 <compat.h> +#include <rte_ethdev.h> +#include <rte_ethdev_vdev.h> + +#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/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c new file mode 100644 index 000000000..7f238fcc0 --- /dev/null +++ b/drivers/net/pfe/pfe_ethdev.c @@ -0,0 +1,322 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include <rte_kvargs.h> +#include <rte_ethdev_vdev.h> +#include <rte_bus_vdev.h> +#include <dpaa_of.h> + +#include "pfe_mod.h" + +#define PFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/ +#define PFE_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 * PFE_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[] = { + PFE_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, + PFE_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, PFE_VDEV_GEM_ID_ARG "=<int> "); diff --git a/drivers/net/pfe/pfe_mod.h b/drivers/net/pfe/pfe_mod.h new file mode 100644 index 000000000..8a41370c3 --- /dev/null +++ b/drivers/net/pfe/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 + +/* PFE DPDK driver supports two interfaces. + */ +#define PFE_CDEV_ETH_COUNT 2 + +/* PFE 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. PFE 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 net_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/pfe/rte_pmd_pfe_version.map b/drivers/net/pfe/rte_pmd_pfe_version.map new file mode 100644 index 000000000..b7b7c9168 --- /dev/null +++ b/drivers/net/pfe/rte_pmd_pfe_version.map @@ -0,0 +1,4 @@ +DPDK_19.11 { + + local: *; +}; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 17b991604..5cb752b9f 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -201,6 +201,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lrte_pmd_nfp _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += -lrte_pmd_null _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX2_PMD) += -lrte_pmd_octeontx2 -lm _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap -lpcap +_LDLIBS-$(CONFIG_RTE_LIBRTE_PFE_PMD) += -lrte_pmd_pfe _LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += -lrte_pmd_qede _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring ifeq ($(CONFIG_RTE_LIBRTE_SCHED),y) -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 03/14] doc: add guide for pfe net PMD 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 02/14] net/pfe: introduce pfe net poll mode driver Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 04/14] net/pfe: support dynamic logging Gagandeep Singh ` (12 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add documentation for pfe network poll mode driver. PFE is a hardware programmable packet forwarding engine to provide high performance ethernet interfaces. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- MAINTAINERS | 1 + doc/guides/nics/features/pfe.ini | 1 + doc/guides/nics/index.rst | 1 + doc/guides/nics/pfe.rst | 173 +++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 doc/guides/nics/pfe.rst diff --git a/MAINTAINERS b/MAINTAINERS index ac5e981a7..e049aae04 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -790,6 +790,7 @@ F: doc/guides/nics/features/enetc.ini NXP pfe M: Gagandeep Singh <g.singh@nxp.com> M: Akhil Goyal <akhil.goyal@nxp.com> +F: doc/guides/nics/pfe.rst F: drivers/net/pfe/ F: doc/guides/nics/features/pfe.ini diff --git a/doc/guides/nics/features/pfe.ini b/doc/guides/nics/features/pfe.ini index 9c8aeb23f..dc78e9500 100644 --- a/doc/guides/nics/features/pfe.ini +++ b/doc/guides/nics/features/pfe.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..d61c27fdf 100644 --- a/doc/guides/nics/index.rst +++ b/doc/guides/nics/index.rst @@ -48,6 +48,7 @@ Network Interface Controller Drivers nfp octeontx octeontx2 + pfe qede sfc_efx softnic diff --git a/doc/guides/nics/pfe.rst b/doc/guides/nics/pfe.rst new file mode 100644 index 000000000..2e713c3d5 --- /dev/null +++ b/doc/guides/nics/pfe.rst @@ -0,0 +1,173 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright 2019 NXP + +PFE Poll Mode Driver +====================== + +The PFE NIC PMD (**librte_pmd_pfe**) provides poll mode driver +support for the inbuilt NIC found in the **NXP LS1012** SoC. + +More information can be found at `NXP Official Website +<https://nxp.com/ls1012a>`_. + +PFE +--- + +This section provides an overview of the NXP PFE +and how it is integrated into the DPDK. + +Contents summary + +- PFE overview +- PFE features +- Supported PFE SoCs +- Prerequisites +- Driver compilation and testing +- Limitations + +PFE Overview +~~~~~~~~~~~~ + +PFE is a hardware programmable packet forwarding engine to provide +high performance Ethernet interfaces. The diagram below shows a +system level overview of PFE: + +.. code-block:: console + + ====================================================+=============== + US +-----------------------------------------+ | Kernel Space + | | | + | PFE Ethernet Driver | | + +-----------------------------------------+ | + ^ | ^ | | + PFE RXQ| |TXQ RXQ| |TXQ | + PMD | | | | | + | v | v | +----------+ + +---------+ +----------+ | | pfe.ko | + | net_pfe0| | net_pfe1 | | +----------+ + +---------+ +----------+ | + ^ | ^ | | + TXQ| |RXQ TXQ| |RXQ | + | | | | | + | v | v | + +------------------------+ | + | | | + | PFE HIF driver | | + +------------------------+ | + ^ | | + RX | TX | | + RING| RING| | + | v | + +--------------+ | + | | | + ==================| HIF |==================+=============== + +-----------+ +--------------+ + | | | | HW + | PFE +--------------+ | + | +-----+ +-----+ | + | | MAC | | MAC | | + | | | | | | + +-------+-----+----------------+-----+----+ + | PHY | | PHY | + +-----+ +-----+ + + +The HIF, PFE, MAC and PHY are the hardware blocks, the pfe.ko is a kernel +module, the PFE HIF driver and the PFE ethernet driver combined represent +as DPDK PFE poll mode driver are running in the userspace. + +The PFE 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. + +net_pfe0 and net_pfe1 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. PFE 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. + +PFE Features +~~~~~~~~~~~~ + +- ARMv8 + +Supported PFE SoCs +~~~~~~~~~~~~~~~~~~ + +- LS1012 + +Prerequisites +~~~~~~~~~~~~~ + +Below are some pre-requisites for executing PFE PMD on a PFE +compatible board: + +1. **ARM 64 Tool Chain** + + For example, the `*aarch64* Linaro Toolchain <https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-i686_aarch64-linux-gnu.tar.xz>`_. + +2. **Linux Kernel** + + It can be obtained from `NXP's Github hosting <https://source.codeaurora.org/external/qoriq/qoriq-components/linux>`_. + +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 <http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.1-base-arm64.tar.gz>`_. + +4. The ethernet device will be registered as virtual device, so pfe has dependency on + **rte_bus_vdev** library and it is mandatory to use `--vdev` with value `net_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 <https://www.nxp.com/support/developer-resources/run-time-software/linux-software-and-development-tools/layerscape-software-development-kit:LAYERSCAPE-SDK>`_ + +- **pfe kernel module** + + pfe kernel module can be obtained from NXP Layerscape software development kit at + location `/lib/modules/<kernel version>/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 <pmd_build_and_test>` +to launch **testpmd** + +Additionally, PFE driver needs `--vdev` as an input with value `net_pfe` +to execute DPDK application. There is an optional parameter `intf` available +to specify port ID. PFE driver supports only two interfaces, so valid values +for `intf` are 0 and 1. +see the command below: + + .. code-block:: console + + <dpdk app> <EAL args> --vdev="net_pfe0,intf=0" --vdev="net_pfe1,intf=1" -- ... + + +Limitations +~~~~~~~~~~~ + +- Multi buffer pool cannot be supported. -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 04/14] net/pfe: support dynamic logging 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (2 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 03/14] doc: add guide for pfe net PMD Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 05/14] net/pfe: add HW specific macros and operations Gagandeep Singh ` (11 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch introduces logging for the pfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- drivers/net/pfe/pfe_ethdev.c | 69 +++++++++++++++++++++++++++++------- drivers/net/pfe/pfe_logs.h | 31 ++++++++++++++++ 2 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 drivers/net/pfe/pfe_logs.h diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index 7f238fcc0..26a1fed10 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_ethdev.c @@ -7,6 +7,7 @@ #include <rte_bus_vdev.h> #include <dpaa_of.h> +#include "pfe_logs.h" #include "pfe_mod.h" #define PFE_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 pfe_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 * PFE_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 * PFE_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("PFE %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, PFE_VDEV_GEM_ID_ARG "=<int> "); + +RTE_INIT(pfe_pmd_init_log) +{ + pfe_logtype_pmd = rte_log_register("pmd.net.pfe"); + if (pfe_logtype_pmd >= 0) + rte_log_set_level(pfe_logtype_pmd, RTE_LOG_NOTICE); +} diff --git a/drivers/net/pfe/pfe_logs.h b/drivers/net/pfe/pfe_logs.h new file mode 100644 index 000000000..272aa1d34 --- /dev/null +++ b/drivers/net/pfe/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 pfe_logtype_pmd; + +/* PMD related logs */ +#define PFE_PMD_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, pfe_logtype_pmd, "pfe_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_ */ -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 05/14] net/pfe: add HW specific macros and operations 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (3 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 04/14] net/pfe: support dynamic logging Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 06/14] net/pfe: add MAC and host interface initialisation Gagandeep Singh ` (10 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch add some hardware specific macros and functions that will be used by the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- drivers/net/pfe/base/cbus.h | 66 +++++ drivers/net/pfe/base/cbus/bmu.h | 41 ++++ drivers/net/pfe/base/cbus/class_csr.h | 277 +++++++++++++++++++++ drivers/net/pfe/base/cbus/emac_mtip.h | 231 ++++++++++++++++++ drivers/net/pfe/base/cbus/gpi.h | 77 ++++++ drivers/net/pfe/base/cbus/hif.h | 86 +++++++ drivers/net/pfe/base/cbus/hif_nocpy.h | 36 +++ drivers/net/pfe/base/cbus/tmu_csr.h | 154 ++++++++++++ drivers/net/pfe/base/cbus/util_csr.h | 47 ++++ drivers/net/pfe/base/pfe.h | 339 ++++++++++++++++++++++++++ 10 files changed, 1354 insertions(+) create mode 100644 drivers/net/pfe/base/cbus.h create mode 100644 drivers/net/pfe/base/cbus/bmu.h create mode 100644 drivers/net/pfe/base/cbus/class_csr.h create mode 100644 drivers/net/pfe/base/cbus/emac_mtip.h create mode 100644 drivers/net/pfe/base/cbus/gpi.h create mode 100644 drivers/net/pfe/base/cbus/hif.h create mode 100644 drivers/net/pfe/base/cbus/hif_nocpy.h create mode 100644 drivers/net/pfe/base/cbus/tmu_csr.h create mode 100644 drivers/net/pfe/base/cbus/util_csr.h create mode 100644 drivers/net/pfe/base/pfe.h diff --git a/drivers/net/pfe/base/cbus.h b/drivers/net/pfe/base/cbus.h new file mode 100644 index 000000000..2de2bfa5d --- /dev/null +++ b/drivers/net/pfe/base/cbus.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#ifndef _CBUS_H_ +#define _CBUS_H_ + +#include <compat.h> + +#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/pfe/base/cbus/bmu.h b/drivers/net/pfe/base/cbus/bmu.h new file mode 100644 index 000000000..c2a4a2813 --- /dev/null +++ b/drivers/net/pfe/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/pfe/base/cbus/class_csr.h b/drivers/net/pfe/base/cbus/class_csr.h new file mode 100644 index 000000000..70af01a27 --- /dev/null +++ b/drivers/net/pfe/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 <compat.h> + +/* @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/pfe/base/cbus/emac_mtip.h b/drivers/net/pfe/base/cbus/emac_mtip.h new file mode 100644 index 000000000..ea54e2ee5 --- /dev/null +++ b/drivers/net/pfe/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 <linux/ethtool.h> + +#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/pfe/base/cbus/gpi.h b/drivers/net/pfe/base/cbus/gpi.h new file mode 100644 index 000000000..60d834323 --- /dev/null +++ b/drivers/net/pfe/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/pfe/base/cbus/hif.h b/drivers/net/pfe/base/cbus/hif.h new file mode 100644 index 000000000..bffd3d923 --- /dev/null +++ b/drivers/net/pfe/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/pfe/base/cbus/hif_nocpy.h b/drivers/net/pfe/base/cbus/hif_nocpy.h new file mode 100644 index 000000000..8c627b1c7 --- /dev/null +++ b/drivers/net/pfe/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/pfe/base/cbus/tmu_csr.h b/drivers/net/pfe/base/cbus/tmu_csr.h new file mode 100644 index 000000000..2f4a62a76 --- /dev/null +++ b/drivers/net/pfe/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/pfe/base/cbus/util_csr.h b/drivers/net/pfe/base/cbus/util_csr.h new file mode 100644 index 000000000..8b37b6fac --- /dev/null +++ b/drivers/net/pfe/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/pfe/base/pfe.h b/drivers/net/pfe/base/pfe.h new file mode 100644 index 000000000..15b17802c --- /dev/null +++ b/drivers/net/pfe/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_PFE_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_PFE_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_ */ -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 06/14] net/pfe: add MAC and host interface initialisation 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (4 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 05/14] net/pfe: add HW specific macros and operations Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 07/14] net/pfe: add device start stop operations Gagandeep Singh ` (9 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal 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 <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- drivers/net/pfe/Makefile | 10 + drivers/net/pfe/base/pfe.h | 83 +++++ drivers/net/pfe/meson.build | 12 +- drivers/net/pfe/pfe_eth.h | 2 + drivers/net/pfe/pfe_ethdev.c | 153 ++++++++- drivers/net/pfe/pfe_hal.c | 629 ++++++++++++++++++++++++++++++++++ drivers/net/pfe/pfe_hif.c | 256 ++++++++++++++ drivers/net/pfe/pfe_hif.h | 106 ++++++ drivers/net/pfe/pfe_hif_lib.c | 20 ++ drivers/net/pfe/pfe_hif_lib.h | 162 +++++++++ drivers/net/pfe/pfe_mod.h | 5 + 11 files changed, 1436 insertions(+), 2 deletions(-) create mode 100644 drivers/net/pfe/pfe_hal.c create mode 100644 drivers/net/pfe/pfe_hif.c create mode 100644 drivers/net/pfe/pfe_hif.h create mode 100644 drivers/net/pfe/pfe_hif_lib.c create mode 100644 drivers/net/pfe/pfe_hif_lib.h diff --git a/drivers/net/pfe/Makefile b/drivers/net/pfe/Makefile index ea9da0e30..5c317e10b 100644 --- a/drivers/net/pfe/Makefile +++ b/drivers/net/pfe/Makefile @@ -10,13 +10,23 @@ include $(RTE_SDK)/mk/rte.vars.mk LIB = librte_pmd_pfe.a CFLAGS += -O3 $(WERROR_FLAGS) +CFLAGS += -Wno-pointer-arith +CFLAGS += -I$(RTE_SDK)/drivers/net/pfe/base/ CFLAGS += -I$(RTE_SDK)/drivers/common/dpaax EXPORT_MAP := rte_pmd_pfe_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_PFE_PMD) += pfe_ethdev.c +SRCS-$(CONFIG_RTE_LIBRTE_PFE_PMD) += pfe_hal.c +SRCS-$(CONFIG_RTE_LIBRTE_PFE_PMD) += pfe_hif_lib.c +SRCS-$(CONFIG_RTE_LIBRTE_PFE_PMD) += pfe_hif.c LDLIBS += -lrte_bus_vdev LDLIBS += -lrte_bus_dpaa diff --git a/drivers/net/pfe/base/pfe.h b/drivers/net/pfe/base/pfe.h index 15b17802c..92e81914a 100644 --- a/drivers/net/pfe/base/pfe.h +++ b/drivers/net/pfe/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/pfe/meson.build b/drivers/net/pfe/meson.build index fa5dfad69..bb2597668 100644 --- a/drivers/net/pfe/meson.build +++ b/drivers/net/pfe/meson.build @@ -6,4 +6,14 @@ if host_machine.system() != 'linux' endif deps += ['bus_dpaa'] -sources = files('pfe_ethdev.c') +sources = files('pfe_ethdev.c', + 'pfe_hal.c', + 'pfe_hif_lib.c', + 'pfe_hif.c') + +# Driver uses below experimental APIs +# rte_mem_iova2virt +# rte_mem_virt2memseg +allow_experimental_apis = true + +includes += include_directories('base') diff --git a/drivers/net/pfe/pfe_eth.h b/drivers/net/pfe/pfe_eth.h index 5811b54eb..ab739f03c 100644 --- a/drivers/net/pfe/pfe_eth.h +++ b/drivers/net/pfe/pfe_eth.h @@ -17,6 +17,8 @@ extern unsigned int pfe_svr; #define SVR_LS1012A_REV2 0x87040020 #define SVR_LS1012A_REV1 0x87040010 +#define PFE_ETH_OVERHEAD (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN) +#define MAX_MTU_ON_REV1 1878 struct ls1012a_eth_platform_data { /* device specific information */ u32 device_flags; diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index 26a1fed10..ac1e608c8 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_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 pfe_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; } diff --git a/drivers/net/pfe/pfe_hal.c b/drivers/net/pfe/pfe_hal.c new file mode 100644 index 000000000..be3b0d01b --- /dev/null +++ b/drivers/net/pfe/pfe_hal.c @@ -0,0 +1,629 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2019 NXP + */ + +#include "pfe_logs.h" +#include "pfe_mod.h" + +#define PFE_MTU_RESET_MASK 0xC000FFFF + +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_PFE_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_ETH_OVERHEAD)) { + PFE_PMD_ERR("Max supported MTU on Rev1 is %d", MAX_MTU_ON_REV1); + 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/pfe/pfe_hif.c b/drivers/net/pfe/pfe_hif.c new file mode 100644 index 000000000..28530d12c --- /dev/null +++ b/drivers/net/pfe/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 <sys/ioctl.h> +#include <sys/epoll.h> +#include <sys/eventfd.h> + +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("PFE_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/pfe/pfe_hif.h b/drivers/net/pfe/pfe_hif.h new file mode 100644 index 000000000..fa3c08cc7 --- /dev/null +++ b/drivers/net/pfe/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/pfe/pfe_hif_lib.c b/drivers/net/pfe/pfe_hif_lib.c new file mode 100644 index 000000000..8f8121be1 --- /dev/null +++ b/drivers/net/pfe/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/pfe/pfe_hif_lib.h b/drivers/net/pfe/pfe_hif_lib.h new file mode 100644 index 000000000..45fae7d93 --- /dev/null +++ b/drivers/net/pfe/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_PFE_SW_PARSE +#define PFE_PKT_HEADER_SZ PFE_HIF_SIZE +#else +#define PFE_PKT_HEADER_SZ (PFE_HIF_SIZE + sizeof(struct pfe_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/pfe/pfe_mod.h b/drivers/net/pfe/pfe_mod.h index 8a41370c3..97fbb4891 100644 --- a/drivers/net/pfe/pfe_mod.h +++ b/drivers/net/pfe/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; -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 07/14] net/pfe: add device start stop operations 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (5 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 06/14] net/pfe: add MAC and host interface initialisation Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 08/14] net/pfe: add queue setup and release operations Gagandeep Singh ` (8 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh, Akhil Goyal This patch adds device start, stop and close operations. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> --- drivers/net/pfe/Makefile | 2 +- drivers/net/pfe/pfe_eth.h | 1 + drivers/net/pfe/pfe_ethdev.c | 184 +++++++++++++++++ drivers/net/pfe/pfe_hif.c | 139 +++++++++++++ drivers/net/pfe/pfe_hif.h | 41 ++++ drivers/net/pfe/pfe_hif_lib.c | 362 +++++++++++++++++++++++++++++++++- drivers/net/pfe/pfe_hif_lib.h | 11 ++ drivers/net/pfe/pfe_mod.h | 1 + 8 files changed, 739 insertions(+), 2 deletions(-) diff --git a/drivers/net/pfe/Makefile b/drivers/net/pfe/Makefile index 5c317e10b..91815fc0c 100644 --- a/drivers/net/pfe/Makefile +++ b/drivers/net/pfe/Makefile @@ -31,7 +31,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PFE_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/pfe/pfe_eth.h b/drivers/net/pfe/pfe_eth.h index ab739f03c..63e5aca42 100644 --- a/drivers/net/pfe/pfe_eth.h +++ b/drivers/net/pfe/pfe_eth.h @@ -55,6 +55,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/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index ac1e608c8..08f3716b0 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_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,58 @@ 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 = PFE_MAX_MACS; + 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; + if (pfe_svr == SVR_LS1012A_REV1) + dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; + else + dev_info->max_rx_pktlen = JUMBO_FRAME_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 +360,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; diff --git a/drivers/net/pfe/pfe_hif.c b/drivers/net/pfe/pfe_hif.c index 28530d12c..39a6ec8d4 100644 --- a/drivers/net/pfe/pfe_hif.c +++ b/drivers/net/pfe/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/pfe/pfe_hif.h b/drivers/net/pfe/pfe_hif.h index fa3c08cc7..9c4e57730 100644 --- a/drivers/net/pfe/pfe_hif.h +++ b/drivers/net/pfe/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 pfe_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/pfe/pfe_hif_lib.c b/drivers/net/pfe/pfe_hif_lib.c index 8f8121be1..2012d896a 100644 --- a/drivers/net/pfe/pfe_hif_lib.c +++ b/drivers/net/pfe/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/pfe/pfe_hif_lib.h b/drivers/net/pfe/pfe_hif_lib.h index 45fae7d93..25c1a3363 100644 --- a/drivers/net/pfe/pfe_hif_lib.h +++ b/drivers/net/pfe/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/pfe/pfe_mod.h b/drivers/net/pfe/pfe_mod.h index 97fbb4891..363feed45 100644 --- a/drivers/net/pfe/pfe_mod.h +++ b/drivers/net/pfe/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; -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 08/14] net/pfe: add queue setup and release operations 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (6 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 07/14] net/pfe: add device start stop operations Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 09/14] net/pfe: add burst enqueue and dequeue operations Gagandeep Singh ` (7 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add RX/TX queue setup operations and supported checksum offloads. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/pfe.ini | 2 + doc/guides/nics/pfe.rst | 1 + drivers/net/pfe/pfe_ethdev.c | 93 +++++++++++++++++++++++++ drivers/net/pfe/pfe_hif.c | 115 +++++++++++++++++++++++++++++++ drivers/net/pfe/pfe_hif.h | 1 + drivers/net/pfe/pfe_hif_lib.c | 50 ++++++++++++++ 6 files changed, 262 insertions(+) diff --git a/doc/guides/nics/features/pfe.ini b/doc/guides/nics/features/pfe.ini index dc78e9500..3b96a1a0f 100644 --- a/doc/guides/nics/features/pfe.ini +++ b/doc/guides/nics/features/pfe.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/pfe.rst b/doc/guides/nics/pfe.rst index 2e713c3d5..23aa15b0d 100644 --- a/doc/guides/nics/pfe.rst +++ b/doc/guides/nics/pfe.rst @@ -93,6 +93,7 @@ the kernel layer for link status. PFE Features ~~~~~~~~~~~~ +- L3/L4 checksum offload - ARMv8 Supported PFE SoCs diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index 08f3716b0..d59ccde11 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_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 @@ -284,6 +295,8 @@ 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; if (pfe_svr == SVR_LS1012A_REV1) dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; else @@ -292,12 +305,92 @@ pfe_eth_info(struct rte_eth_dev *dev, 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 diff --git a/drivers/net/pfe/pfe_hif.c b/drivers/net/pfe/pfe_hif.c index 39a6ec8d4..bd5bf7a19 100644 --- a/drivers/net/pfe/pfe_hif.c +++ b/drivers/net/pfe/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]; + + /* PFE mbuf structure is as follow: + * ----------------------------------------------------------+ + * | mbuf | priv | headroom (annotation + PFE data) | data | + * ----------------------------------------------------------+ + * + * As we are expecting additional information like parse + * results, eth id, queue id from PFE block along with data. + * so we have to provide additional memory for each packet to + * HIF rx rings so that PFE 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 PFE + * block headers. On packet reception, HIF driver will use + * PFE 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/pfe/pfe_hif.h b/drivers/net/pfe/pfe_hif.h index 9c4e57730..d8bb26bc4 100644 --- a/drivers/net/pfe/pfe_hif.h +++ b/drivers/net/pfe/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/pfe/pfe_hif_lib.c b/drivers/net/pfe/pfe_hif_lib.c index 2012d896a..f5e290f27 100644 --- a/drivers/net/pfe/pfe_hif_lib.c +++ b/drivers/net/pfe/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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 09/14] net/pfe: add burst enqueue and dequeue operations 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (7 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 08/14] net/pfe: add queue setup and release operations Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 10/14] net/pfe: add supported packet types and basic statistics Gagandeep Singh ` (6 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add burst enqueue and dequeue operations to the pfe PMD. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- drivers/net/pfe/pfe_ethdev.c | 140 +++++++++++++ drivers/net/pfe/pfe_hif.c | 360 +++++++++++++++++++++++++++++++++- drivers/net/pfe/pfe_hif.h | 8 + drivers/net/pfe/pfe_hif_lib.c | 146 ++++++++++++++ drivers/net/pfe/pfe_hif_lib.h | 8 + drivers/net/pfe/pfe_mod.h | 2 + 6 files changed, 663 insertions(+), 1 deletion(-) diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index d59ccde11..4f408059b 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_ethdev.c @@ -2,6 +2,7 @@ * Copyright 2019 NXP */ +#include <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> @@ -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("PFE_INTR_SUPPORT")) { + dev->rx_pkt_burst = &pfe_recv_pkts_on_intr; + PFE_PMD_INFO("PFE 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 diff --git a/drivers/net/pfe/pfe_hif.c b/drivers/net/pfe/pfe_hif.c index bd5bf7a19..715d5b85a 100644 --- a/drivers/net/pfe/pfe_hif.c +++ b/drivers/net/pfe/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/pfe/pfe_hif.h b/drivers/net/pfe/pfe_hif.h index d8bb26bc4..6eebbdfc9 100644 --- a/drivers/net/pfe/pfe_hif.h +++ b/drivers/net/pfe/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/pfe/pfe_hif_lib.c b/drivers/net/pfe/pfe_hif_lib.c index f5e290f27..7bb9e3866 100644 --- a/drivers/net/pfe/pfe_hif_lib.c +++ b/drivers/net/pfe/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_PFE_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_PFE_SW_PARSE + struct pfe_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_PFE_SW_PARSE + pfe_sw_parse_pkt(mbuf); +#else + parse_res = (struct pfe_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/pfe/pfe_hif_lib.h b/drivers/net/pfe/pfe_hif_lib.h index 25c1a3363..da4a2108b 100644 --- a/drivers/net/pfe/pfe_hif_lib.h +++ b/drivers/net/pfe/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/pfe/pfe_mod.h b/drivers/net/pfe/pfe_mod.h index 363feed45..30079ae5b 100644 --- a/drivers/net/pfe/pfe_mod.h +++ b/drivers/net/pfe/pfe_mod.h @@ -7,6 +7,8 @@ struct pfe; +#include <rte_ethdev.h> + #include "pfe.h" #include "pfe_hif.h" #include "pfe_hif_lib.h" -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 10/14] net/pfe: add supported packet types and basic statistics 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (8 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 09/14] net/pfe: add burst enqueue and dequeue operations Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 11/14] net/pfe: add MTU and MAC address set operations Gagandeep Singh ` (5 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh 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 <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/pfe.ini | 2 ++ doc/guides/nics/pfe.rst | 2 ++ drivers/net/pfe/pfe_ethdev.c | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/doc/guides/nics/features/pfe.ini b/doc/guides/nics/features/pfe.ini index 3b96a1a0f..6274b5965 100644 --- a/doc/guides/nics/features/pfe.ini +++ b/doc/guides/nics/features/pfe.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/pfe.rst b/doc/guides/nics/pfe.rst index 23aa15b0d..8a9fc0639 100644 --- a/doc/guides/nics/pfe.rst +++ b/doc/guides/nics/pfe.rst @@ -94,6 +94,8 @@ PFE Features ~~~~~~~~~~~~ - L3/L4 checksum offload +- Packet type parsing +- Basic stats - ARMv8 Supported PFE SoCs diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index 4f408059b..09ab0b02e 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_ethdev.c @@ -521,6 +521,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, @@ -531,6 +572,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 -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 11/14] net/pfe: add MTU and MAC address set operations 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (9 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 10/14] net/pfe: add supported packet types and basic statistics Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 12/14] net/pfe: add allmulticast and promiscuous Gagandeep Singh ` (4 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh To update MAC address or MTU, operations are added to the driver. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/pfe.ini | 1 + doc/guides/nics/pfe.rst | 1 + drivers/net/pfe/pfe_ethdev.c | 71 +++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/features/pfe.ini b/doc/guides/nics/features/pfe.ini index 6274b5965..dceccc199 100644 --- a/doc/guides/nics/features/pfe.ini +++ b/doc/guides/nics/features/pfe.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/pfe.rst b/doc/guides/nics/pfe.rst index 8a9fc0639..ad7d15ac6 100644 --- a/doc/guides/nics/pfe.rst +++ b/doc/guides/nics/pfe.rst @@ -96,6 +96,7 @@ PFE Features - L3/L4 checksum offload - Packet type parsing - Basic stats +- MTU update - ARMv8 Supported PFE SoCs diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index 09ab0b02e..58e2dfaf8 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_ethdev.c @@ -6,6 +6,7 @@ #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> #include <rte_bus_vdev.h> +#include <rte_ether.h> #include <dpaa_of.h> #include "pfe_logs.h" @@ -435,12 +436,16 @@ 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->min_mtu = RTE_ETHER_MIN_MTU; dev_info->rx_offload_capa = dev_rx_offloads_sup; dev_info->tx_offload_capa = dev_tx_offloads_sup; - if (pfe_svr == SVR_LS1012A_REV1) + if (pfe_svr == SVR_LS1012A_REV1) { dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD; - else + dev_info->max_mtu = MAX_MTU_ON_REV1; + } else { dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE; + dev_info->max_mtu = JUMBO_FRAME_SIZE - PFE_ETH_OVERHEAD; + } return 0; } @@ -542,6 +547,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) @@ -573,6 +631,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, }; @@ -583,6 +643,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)); @@ -635,6 +696,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); -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 12/14] net/pfe: add allmulticast and promiscuous 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (10 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 11/14] net/pfe: add MTU and MAC address set operations Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 13/14] net/pfe: add link status update Gagandeep Singh ` (3 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch adds support to enable multicast and promiscuous mode. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/pfe.ini | 2 ++ doc/guides/nics/pfe.rst | 2 ++ drivers/net/pfe/pfe_ethdev.c | 42 ++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/doc/guides/nics/features/pfe.ini b/doc/guides/nics/features/pfe.ini index dceccc199..f48cb2694 100644 --- a/doc/guides/nics/features/pfe.ini +++ b/doc/guides/nics/features/pfe.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/pfe.rst b/doc/guides/nics/pfe.rst index ad7d15ac6..db407a807 100644 --- a/doc/guides/nics/pfe.rst +++ b/doc/guides/nics/pfe.rst @@ -97,6 +97,8 @@ PFE Features - Packet type parsing - Basic stats - MTU update +- Promiscuous mode +- Allmulticast mode - ARMv8 Supported PFE SoCs diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index 58e2dfaf8..8af003782 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_ethdev.c @@ -547,6 +547,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) { @@ -631,6 +670,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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 13/14] net/pfe: add link status update 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (11 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 12/14] net/pfe: add allmulticast and promiscuous Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 14/14] doc: add NXP PFE PMD in release notes Gagandeep Singh ` (2 subsequent siblings) 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh This patch add link related operations like link update, up and down. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> Acked-by: Nipun Gupta <nipun.gupta@nxp.com> Acked-by: Akhil Goyal <akhil.goyal@nxp.com> --- doc/guides/nics/features/pfe.ini | 1 + doc/guides/nics/pfe.rst | 1 + drivers/net/pfe/pfe_ethdev.c | 105 +++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/doc/guides/nics/features/pfe.ini b/doc/guides/nics/features/pfe.ini index f48cb2694..5b6a367d7 100644 --- a/doc/guides/nics/features/pfe.ini +++ b/doc/guides/nics/features/pfe.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/pfe.rst b/doc/guides/nics/pfe.rst index db407a807..c1b4a3e47 100644 --- a/doc/guides/nics/pfe.rst +++ b/doc/guides/nics/pfe.rst @@ -99,6 +99,7 @@ PFE Features - MTU update - Promiscuous mode - Allmulticast mode +- Link status - ARMv8 Supported PFE SoCs diff --git a/drivers/net/pfe/pfe_ethdev.c b/drivers/net/pfe/pfe_ethdev.c index 8af003782..79555185b 100644 --- a/drivers/net/pfe/pfe_ethdev.c +++ b/drivers/net/pfe/pfe_ethdev.c @@ -2,6 +2,8 @@ * Copyright 2019 NXP */ +#include <sys/ioctl.h> +#include <sys/epoll.h> #include <sys/epoll.h> #include <rte_kvargs.h> #include <rte_ethdev_vdev.h> @@ -547,6 +549,90 @@ 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) { @@ -586,6 +672,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) { @@ -670,9 +772,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, -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* [dpdk-dev] [PATCH v4 14/14] doc: add NXP PFE PMD in release notes 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (12 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 13/14] net/pfe: add link status update Gagandeep Singh @ 2019-10-10 6:32 ` Gagandeep Singh 2019-10-10 7:11 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Thomas Monjalon 2019-10-10 17:47 ` Ferruh Yigit 15 siblings, 0 replies; 87+ messages in thread From: Gagandeep Singh @ 2019-10-10 6:32 UTC (permalink / raw) To: dev, ferruh.yigit; +Cc: thomas, Gagandeep Singh Update release notes for NXP PFE driver supported for 19.11. Signed-off-by: Gagandeep Singh <g.singh@nxp.com> --- 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 7a1223249..883108165 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -93,6 +93,11 @@ New Features gives ability to print port supported ptypes in different protocol layers. +* **Added NXP PFE PMD.** + + Added the new PFE driver for the NXP LS1012A platform. See the + :doc:`../nics/pfe` NIC driver guide for more details on this new driver. + Removed Items ------------- -- 2.17.1 ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (13 preceding siblings ...) 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 14/14] doc: add NXP PFE PMD in release notes Gagandeep Singh @ 2019-10-10 7:11 ` Thomas Monjalon 2019-10-10 17:01 ` Ferruh Yigit 2019-10-10 17:47 ` Ferruh Yigit 15 siblings, 1 reply; 87+ messages in thread From: Thomas Monjalon @ 2019-10-10 7:11 UTC (permalink / raw) To: Gagandeep Singh; +Cc: dev, ferruh.yigit 10/10/2019 08:32, Gagandeep Singh: > Gagandeep Singh (13): > net/pfe: introduce pfe net poll mode driver > doc: add guide for pfe net PMD > net/pfe: support dynamic logging > net/pfe: add HW specific macros and operations > net/pfe: add MAC and host interface initialisation > net/pfe: add device start stop operations > net/pfe: add queue setup and release operations > net/pfe: add burst enqueue and dequeue operations > net/pfe: add supported packet types and basic statistics > net/pfe: add MTU and MAC address set operations > net/pfe: add allmulticast and promiscuous > net/pfe: add link status update > doc: add NXP PFE PMD in release notes Patches introducing the doc and release notes can be squashed in the patch introducing the driver. ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD 2019-10-10 7:11 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Thomas Monjalon @ 2019-10-10 17:01 ` Ferruh Yigit 0 siblings, 0 replies; 87+ messages in thread From: Ferruh Yigit @ 2019-10-10 17:01 UTC (permalink / raw) To: Thomas Monjalon, Gagandeep Singh; +Cc: dev On 10/10/2019 8:11 AM, Thomas Monjalon wrote: > 10/10/2019 08:32, Gagandeep Singh: >> Gagandeep Singh (13): >> net/pfe: introduce pfe net poll mode driver >> doc: add guide for pfe net PMD >> net/pfe: support dynamic logging >> net/pfe: add HW specific macros and operations >> net/pfe: add MAC and host interface initialisation >> net/pfe: add device start stop operations >> net/pfe: add queue setup and release operations >> net/pfe: add burst enqueue and dequeue operations >> net/pfe: add supported packet types and basic statistics >> net/pfe: add MTU and MAC address set operations >> net/pfe: add allmulticast and promiscuous >> net/pfe: add link status update >> doc: add NXP PFE PMD in release notes > > Patches introducing the doc and release notes can be squashed in the patch introducing the driver. > +1, I will do while merging. ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh ` (14 preceding siblings ...) 2019-10-10 7:11 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Thomas Monjalon @ 2019-10-10 17:47 ` Ferruh Yigit 2019-10-25 7:59 ` Thomas Monjalon 15 siblings, 1 reply; 87+ messages in thread From: Ferruh Yigit @ 2019-10-10 17:47 UTC (permalink / raw) To: Gagandeep Singh, dev; +Cc: thomas On 10/10/2019 7:32 AM, Gagandeep Singh wrote: > This series introduces pfe (packet forwarding engine) > network poll mode driver for NXP SoC ls1012a. > > First patch of this series move OF library code from > dpaa bus to a common folder as PFE also uses the > same library for getting information from the device > tree. > This patch is included in this series so that > compilation by CI don't break. > > V2 Change-log: > * fix compilation break for clang3.4 and gcc 4.8 > * fix checkpatch errors > > V3 Change-log: > * Release notes updated for PPFE PMD > * Experimental APIs list added in Makefile and meson > * Dynamic logging added > * PPFE documentation is updated for kernel module "pfe.ko" > and parameter "intf" is mentioned. > * of.h and of.c are renamed to dpaa_of.h and dpaa_of.c > * enable PPFE compilation only in 'common_armv8a_linux' > * PFE_CDEV_ETH_COUNT updated 2, as only 2 eth devices supported. > * Comment updated for "pfe_us_cdev" device > * functions prototype updated > * intf params value check added during parsing and unwanted > port id checks removed. > * unwanted dev->data memcpy removed. > * munmap and rte_eth_dev_release_port added in error case > * atoi replaced with strtol > * add static to global variable g_pfe > > V4 Change-log: > * DPAA dependency removed by moving compat.h from > bus/dpaa/include to common/dpaax > * Updated interface name to net_pfe in document > * Updated driver name to PFE from PPFE everywhere > for consistency > * min_mtu and max_mtu added > > Gagandeep Singh (13): > net/pfe: introduce pfe net poll mode driver > doc: add guide for pfe net PMD > net/pfe: support dynamic logging > net/pfe: add HW specific macros and operations > net/pfe: add MAC and host interface initialisation > net/pfe: add device start stop operations > net/pfe: add queue setup and release operations > net/pfe: add burst enqueue and dequeue operations > net/pfe: add supported packet types and basic statistics > net/pfe: add MTU and MAC address set operations > net/pfe: add allmulticast and promiscuous > net/pfe: add link status update > doc: add NXP PFE PMD in release notes > > Hemant Agrawal (1): > common/dpaax: moving OF lib code from dpaa bus Series applied to dpdk-next-net/master, thanks. Please add web patch to announce the new PMD. ^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD 2019-10-10 17:47 ` Ferruh Yigit @ 2019-10-25 7:59 ` Thomas Monjalon 0 siblings, 0 replies; 87+ messages in thread From: Thomas Monjalon @ 2019-10-25 7:59 UTC (permalink / raw) To: Gagandeep Singh, hemant.agrawal; +Cc: dev, Ferruh Yigit 10/10/2019 19:47, Ferruh Yigit: > On 10/10/2019 7:32 AM, Gagandeep Singh wrote: > > Gagandeep Singh (13): > > net/pfe: introduce pfe net poll mode driver > > doc: add guide for pfe net PMD > > net/pfe: support dynamic logging > > net/pfe: add HW specific macros and operations > > net/pfe: add MAC and host interface initialisation > > net/pfe: add device start stop operations > > net/pfe: add queue setup and release operations > > net/pfe: add burst enqueue and dequeue operations > > net/pfe: add supported packet types and basic statistics > > net/pfe: add MTU and MAC address set operations > > net/pfe: add allmulticast and promiscuous > > net/pfe: add link status update > > doc: add NXP PFE PMD in release notes > > > > Hemant Agrawal (1): > > common/dpaax: moving OF lib code from dpaa bus > > Series applied to dpdk-next-net/master, thanks. While rebasing on top of master, I had to do some changes to the meson files in following commits: common/dpaax: moving OF lib code from dpaa bus net/pfe: add MAC and host interface initialisation --- a/drivers/common/dpaax/meson.build +++ b/drivers/common/dpaax/meson.build +if cc.has_argument('-Wno-pointer-arith') + cflags += '-Wno-pointer-arith' + endif --- a/drivers/crypto/caam_jr/meson.build +++ b/drivers/crypto/caam_jr/meson.build includes += include_directories('../../bus/dpaa/include/') +includes += include_directories('../../common/dpaax/') includes += include_directories('../../common/dpaax/caamflib/') --- a/drivers/crypto/dpaa_sec/meson.build +++ b/drivers/crypto/dpaa_sec/meson.build includes += include_directories('../../bus/dpaa/include') +includes += include_directories('../../common/dpaax') includes += include_directories('../../common/dpaax/caamflib/') --- a/drivers/net/pfe/meson.build +++ b/drivers/net/pfe/meson.build +if cc.has_argument('-Wno-pointer-arith') + cflags += '-Wno-pointer-arith' +endif 2 notes: - You should fix your pointer arithmetics instead of disabling warnings - Having 3 compat.h files in fslmc and dpaax is an horror for includes ^ permalink raw reply [flat|nested] 87+ messages in thread
end of thread, other threads:[~2019-11-06 12:22 UTC | newest] Thread overview: 87+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-08-26 13:02 [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh 2019-10-28 17:18 ` Stephen Hemminger 2019-10-29 9:27 ` Ferruh Yigit 2019-11-04 11:06 ` Bruce Richardson 2019-11-05 16:02 ` Ferruh Yigit 2019-11-06 9:38 ` Bruce Richardson 2019-11-06 12:22 ` Ferruh Yigit 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 03/13] doc: add guide for ppfe net PMD Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 04/13] net/ppfe: support dynamic logging Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 05/13] net/ppfe: add HW specific macros and operations Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 06/13] net/ppfe: add MAC and host interface initialisation Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 07/13] net/ppfe: add device start stop operations Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 08/13] net/ppfe: add queue setup and release operations Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 09/13] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 10/13] net/ppfe: add supported packet types and basic statistics Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 11/13] net/ppfe: add MTU and MAC address set operations Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 12/13] net/ppfe: add allmulticast and promiscuous Gagandeep Singh 2019-08-26 13:02 ` [dpdk-dev] [PATCH v1 13/13] net/ppfe: add link status update Gagandeep Singh 2019-08-27 7:16 ` [dpdk-dev] [PATCH v1 00/13] introduces ppfe network PMD Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 " Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 01/13] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-09-26 16:54 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 02/13] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh 2019-09-26 16:53 ` Ferruh Yigit 2019-10-01 7:05 ` Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 03/13] doc: add guide for ppfe net PMD Gagandeep Singh 2019-09-26 16:56 ` Ferruh Yigit 2019-09-26 18:00 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 04/13] net/ppfe: support dynamic logging Gagandeep Singh 2019-09-26 16:57 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 05/13] net/ppfe: add HW specific macros and operations Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 06/13] net/ppfe: add MAC and host interface initialisation Gagandeep Singh 2019-09-26 17:00 ` Ferruh Yigit 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 07/13] net/ppfe: add device start stop operations Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 08/13] net/ppfe: add queue setup and release operations Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 09/13] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 10/13] net/ppfe: add supported packet types and basic statistics Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 11/13] net/ppfe: add MTU and MAC address set operations Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 12/13] net/ppfe: add allmulticast and promiscuous Gagandeep Singh 2019-08-28 11:08 ` [dpdk-dev] [PATCH v2 13/13] net/ppfe: add link status update Gagandeep Singh 2019-09-26 17:28 ` [dpdk-dev] [PATCH v2 00/13] introduces ppfe network PMD Ferruh Yigit 2019-09-27 14:55 ` Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 00/14] " Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 02/14] net/ppfe: introduce ppfe net poll mode driver Gagandeep Singh 2019-10-04 15:38 ` Ferruh Yigit 2019-10-09 6:52 ` Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 03/14] doc: add guide for ppfe net PMD Gagandeep Singh 2019-10-04 15:41 ` Ferruh Yigit 2019-10-09 6:54 ` Gagandeep Singh 2019-10-01 11:01 ` [dpdk-dev] [PATCH v3 04/14] net/ppfe: support dynamic logging Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 05/14] net/ppfe: add HW specific macros and operations Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 06/14] net/ppfe: add MAC and host interface initialisation Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 07/14] net/ppfe: add device start stop operations Gagandeep Singh 2019-10-04 15:42 ` Ferruh Yigit 2019-10-09 6:54 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 08/14] net/ppfe: add queue setup and release operations Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 09/14] net/ppfe: add burst enqueue and dequeue operations Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 10/14] net/ppfe: add supported packet types and basic statistics Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 11/14] net/ppfe: add MTU and MAC address set operations Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 12/14] net/ppfe: add allmulticast and promiscuous Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 13/14] net/ppfe: add link status update Gagandeep Singh 2019-10-04 15:43 ` Ferruh Yigit 2019-10-09 6:57 ` Gagandeep Singh 2019-10-01 11:02 ` [dpdk-dev] [PATCH v3 14/14] doc: add NXP PPFE PMD in release notes Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 01/14] common/dpaax: moving OF lib code from dpaa bus Gagandeep Singh 2019-10-10 17:01 ` Ferruh Yigit 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 02/14] net/pfe: introduce pfe net poll mode driver Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 03/14] doc: add guide for pfe net PMD Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 04/14] net/pfe: support dynamic logging Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 05/14] net/pfe: add HW specific macros and operations Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 06/14] net/pfe: add MAC and host interface initialisation Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 07/14] net/pfe: add device start stop operations Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 08/14] net/pfe: add queue setup and release operations Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 09/14] net/pfe: add burst enqueue and dequeue operations Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 10/14] net/pfe: add supported packet types and basic statistics Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 11/14] net/pfe: add MTU and MAC address set operations Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 12/14] net/pfe: add allmulticast and promiscuous Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 13/14] net/pfe: add link status update Gagandeep Singh 2019-10-10 6:32 ` [dpdk-dev] [PATCH v4 14/14] doc: add NXP PFE PMD in release notes Gagandeep Singh 2019-10-10 7:11 ` [dpdk-dev] [PATCH v4 00/14] introduces pfe network PMD Thomas Monjalon 2019-10-10 17:01 ` Ferruh Yigit 2019-10-10 17:47 ` Ferruh Yigit 2019-10-25 7:59 ` Thomas Monjalon
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).