From 9ed8d95bd803d0523f2146f3518bc91d9ead046c Mon Sep 17 00:00:00 2001 From: Tomaz Zaman Date: Mon, 10 Aug 2026 13:51:12 +0200 Subject: [PATCH 05/77] package: add the ASK hardware-offload stack All components pin the same ASK revision (ask-version.mk), so kernel patches and userspace can never skew: - ask-modules: cdx.ko (fast-path translator, spawns dpa_app at init), fci.ko (NETLINK_FF bridge), auto_bridge.ko (L2 flow learning), built as external modules with AutoLoad 30/31/52 - cmm: conntrack monitor daemon (SysV init - it self-daemonizes), /etc/config/fastforward ALG blacklist - dpa-app: FMan PCD loader + cdx XML configs. -DLS1043 is mandatory: libfmc.a is built with it and sizeof(fmc_model_t) must match, or fmc_compile's memset overruns the caller's allocation - fmc/fmlib: NXP userspace at lf-6.12.49-2.2.0 with mono-ask extensions; fmc ships /etc/fmc/config/hxs_pdl_v3.xml (hard dpa_app dependency) - libcli, tclap: support libraries Co-Authored-By: Claude Fable 5 --- package/ask/ask-modules/Makefile | 92 ++++++ package/ask/ask-version.mk | 15 + package/ask/cmm/Makefile | 71 +++++ package/ask/cmm/files/cmm.init | 26 ++ package/ask/dpa-app/Makefile | 70 +++++ package/ask/fmc/Makefile | 58 ++++ .../fmc/patches/100-mono-ask-extensions.patch | 290 ++++++++++++++++++ package/ask/fmlib/Makefile | 44 +++ .../patches/100-mono-ask-extensions.patch | 180 +++++++++++ package/ask/libcli/Makefile | 52 ++++ package/ask/tclap/Makefile | 44 +++ 11 files changed, 942 insertions(+) create mode 100644 package/ask/ask-modules/Makefile create mode 100644 package/ask/ask-version.mk create mode 100644 package/ask/cmm/Makefile create mode 100644 package/ask/cmm/files/cmm.init create mode 100644 package/ask/dpa-app/Makefile create mode 100644 package/ask/fmc/Makefile create mode 100644 package/ask/fmc/patches/100-mono-ask-extensions.patch create mode 100644 package/ask/fmlib/Makefile create mode 100644 package/ask/fmlib/patches/100-mono-ask-extensions.patch create mode 100644 package/ask/libcli/Makefile create mode 100644 package/ask/tclap/Makefile diff --git a/package/ask/ask-modules/Makefile b/package/ask/ask-modules/Makefile new file mode 100644 index 0000000000..247076a55e --- /dev/null +++ b/package/ask/ask-modules/Makefile @@ -0,0 +1,92 @@ +include $(TOPDIR)/rules.mk +include $(TOPDIR)/package/ask/ask-version.mk + +PKG_NAME:=ask-modules +PKG_VERSION:=$(ASK_PKG_VERSION) +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=$(ASK_SOURCE_URL) +PKG_SOURCE_VERSION:=$(ASK_VERSION) +PKG_SOURCE:=$(ASK_SOURCE) +PKG_SOURCE_SUBDIR:=ask-$(ASK_VERSION) +PKG_MIRROR_HASH:=skip + +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/kernel.mk + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/ask-modules-$(ASK_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/ask-cdx + SUBMENU:=Network Devices + TITLE:=ASK CDX fast-path translator (DPAA) + DEPENDS:=@TARGET_layerscape + FILES:=$(PKG_BUILD_DIR)/cdx/cdx.ko + AUTOLOAD:=$(call AutoLoad,30,cdx) +endef + +define KernelPackage/ask-cdx/description + Programs DPAA hardware (FMan external hash table, CEETM, SEC frame + queues) from CMM/FPP commands. Spawns /usr/bin/dpa_app at init to + apply the FMan PCD classification graph. +endef + +define KernelPackage/ask-auto-bridge + SUBMENU:=Network Devices + TITLE:=ASK automatic bridging module + DEPENDS:=@TARGET_layerscape +kmod-ask-cdx + FILES:=$(PKG_BUILD_DIR)/auto_bridge/auto_bridge.ko + AUTOLOAD:=$(call AutoLoad,31,auto_bridge) +endef + +define KernelPackage/ask-auto-bridge/description + L2 bridge flow learning for the ASK fast path. Subscribes to the + kernel brevent notifier chain and reports bridged flows over + NETLINK_L2FLOW so they can be hardware-forwarded. +endef + +define KernelPackage/ask-fci + SUBMENU:=Network Devices + TITLE:=ASK Fast Control Interface + DEPENDS:=@TARGET_layerscape +kmod-ask-cdx +kmod-nf-conntrack-netlink +kmod-ipt-conntrack + FILES:=$(PKG_BUILD_DIR)/fci/fci.ko + AUTOLOAD:=$(call AutoLoad,52,fci) +endef + +define KernelPackage/ask-fci/description + Netlink bridge (NETLINK_FF) routing FPP command messages between + the cmm daemon and the cdx kernel backend. Loaded after the + conntrack stack, per the ASK module load order. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + xzcat $(DL_DIR)/$(ASK_SOURCE) | $(TAR) -C $(PKG_BUILD_DIR) --strip-components=1 -xf - + printf '/*Auto-generated file. Do not edit !*/\n#ifndef CDX_VERSION_H\n\n#define CDX_VERSION_H\n\n#define CDX_VERSION "ask-%.12s"\n\n#endif /* CDX_VERSION_H */\n' \ + "$(ASK_VERSION)" > $(PKG_BUILD_DIR)/cdx/version.h +endef + +ASK_KBUILD_ARGS:= \ + CROSS_COMPILE="$(KERNEL_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + PLATFORM=LS1043A + +define Build/Compile + +$(KERNEL_MAKE) M=$(PKG_BUILD_DIR)/cdx \ + $(ASK_KBUILD_ARGS) KERNELDIR=$(LINUX_DIR) KERNELVERSION=6.12 \ + CONFIG_ASK_CDX=m modules + +$(KERNEL_MAKE) M=$(PKG_BUILD_DIR)/fci \ + $(ASK_KBUILD_ARGS) KERNEL_SOURCE=$(LINUX_DIR) BOARD_ARCH=$(LINUX_KARCH) \ + KBUILD_EXTRA_SYMBOLS=$(PKG_BUILD_DIR)/cdx/Module.symvers \ + CONFIG_ASK_FCI=m modules + +$(KERNEL_MAKE) M=$(PKG_BUILD_DIR)/auto_bridge \ + $(ASK_KBUILD_ARGS) KERNEL_SOURCE=$(LINUX_DIR) \ + CONFIG_ASK_AUTO_BRIDGE=m modules +endef + +$(eval $(call KernelPackage,ask-cdx)) +$(eval $(call KernelPackage,ask-auto-bridge)) +$(eval $(call KernelPackage,ask-fci)) diff --git a/package/ask/ask-version.mk b/package/ask/ask-version.mk new file mode 100644 index 0000000000..8baef4e240 --- /dev/null +++ b/package/ask/ask-version.mk @@ -0,0 +1,15 @@ +# Single source of truth for the ASK revision used by all ASK packages. +# Must match ASK_VERSION in target/linux/layerscape/Makefile so the kernel +# patches and the userspace/modules always come from the same commit. +ASK_VERSION:=b4c31a46dfb7b03984ebfa3a8eabd06ccbc0cc91 +ASK_SOURCE:=ask-$(ASK_VERSION).tar.xz +ASK_SOURCE_URL:=https://github.com/we-are-mono/ASK + +# APK-valid package version for ASK-sourced packages (apk rejects +# versions that do not start with a digit, so the raw sha cannot be used) +ASK_PKG_VERSION:=1.0_git20260808 + +# NXP userspace components, pinned to the same LSDK tag as the kernel +# (lf-6.12.49-2.2.0; expressed digits-only for apk) +ASK_NXP_TAG:=lf-6.12.49-2.2.0 +ASK_NXP_PKG_VERSION:=6.12.49.2.2.0 diff --git a/package/ask/cmm/Makefile b/package/ask/cmm/Makefile new file mode 100644 index 0000000000..dcdc2b13cc --- /dev/null +++ b/package/ask/cmm/Makefile @@ -0,0 +1,71 @@ +include $(TOPDIR)/rules.mk +include $(TOPDIR)/package/ask/ask-version.mk + +PKG_NAME:=cmm +PKG_VERSION:=$(ASK_PKG_VERSION) +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=$(ASK_SOURCE_URL) +PKG_SOURCE_VERSION:=$(ASK_VERSION) +PKG_SOURCE:=$(ASK_SOURCE) +PKG_SOURCE_SUBDIR:=ask-$(ASK_VERSION) +PKG_MIRROR_HASH:=skip + +PKG_BUILD_DIR:=$(BUILD_DIR)/cmm-ask-$(ASK_VERSION) +PKG_BUILD_PARALLEL:=1 +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/cmm + SECTION:=net + CATEGORY:=Network + TITLE:=ASK Connection Manager (conntrack monitor / fast-path control) + DEPENDS:=@TARGET_layerscape +libcli +libpcap +libmnl +libnetfilter-conntrack \ + +kmod-ask-fci +kmod-ask-auto-bridge +kmod-nf-conntrack-netlink +endef + +define Package/cmm/description + Watches conntrack, routing, neighbour and interface state and + programs offloadable flows into the DPAA fast path through + libfci -> NETLINK_FF -> fci.ko -> cdx.ko. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + xzcat $(DL_DIR)/$(ASK_SOURCE) | $(TAR) -C $(PKG_BUILD_DIR) --strip-components=1 -xf - +endef + +# CFLAGS/LDFLAGS go through the environment, not the command line: both +# Makefiles build their include/define lists with CFLAGS +=, which a +# command-line assignment would override. +define Build/Compile + +CFLAGS="$(TARGET_CFLAGS)" \ + $(MAKE) -C $(PKG_BUILD_DIR)/fci/lib \ + CC="$(TARGET_CC)" AR="$(TARGET_AR)" + +CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + $(MAKE) -C $(PKG_BUILD_DIR)/cmm \ + CC="$(TARGET_CC)" \ + LIBFCI_DIR=$(PKG_BUILD_DIR)/fci/lib \ + ABM_DIR=$(PKG_BUILD_DIR)/auto_bridge \ + PKG_CONFIG="$(PKG_CONFIG)" \ + PKG_CONFIG_PATH="$(STAGING_DIR)/usr/lib/pkgconfig" \ + SYSROOT="$(STAGING_DIR)/usr" +endef + +define Package/cmm/conffiles +/etc/config/fastforward +endef + +define Package/cmm/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/cmm/src/cmm $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) $(PKG_BUILD_DIR)/config/fastforward $(1)/etc/config/fastforward + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/cmm.init $(1)/etc/init.d/cmm +endef + +$(eval $(call BuildPackage,cmm)) diff --git a/package/ask/cmm/files/cmm.init b/package/ask/cmm/files/cmm.init new file mode 100644 index 0000000000..3d93c9eb8f --- /dev/null +++ b/package/ask/cmm/files/cmm.init @@ -0,0 +1,26 @@ +#!/bin/sh /etc/rc.common +# ASK Connection Manager. cmm self-daemonizes (no foreground mode), so this +# is a plain SysV script rather than a procd service. Modules cdx (30), +# auto_bridge (31) and fci (52) are loaded by kmodloader before START=54. + +START=54 +STOP=10 + +vwd_fast_path() { + [ -e /sys/class/vwd/vwd0/vwd_fast_path_enable ] && \ + echo "$1" > /sys/class/vwd/vwd0/vwd_fast_path_enable +} + +start() { + [ -e /dev/cdx_ctrl ] || { + echo "cmm: /dev/cdx_ctrl not present, cdx.ko not loaded - not starting" >&2 + return 1 + } + vwd_fast_path 1 + /usr/bin/cmm -f /etc/config/fastforward -n 131072 +} + +stop() { + killall cmm 2>/dev/null + vwd_fast_path 0 +} diff --git a/package/ask/dpa-app/Makefile b/package/ask/dpa-app/Makefile new file mode 100644 index 0000000000..388baf6108 --- /dev/null +++ b/package/ask/dpa-app/Makefile @@ -0,0 +1,70 @@ +include $(TOPDIR)/rules.mk +include $(TOPDIR)/package/ask/ask-version.mk + +PKG_NAME:=dpa-app +PKG_VERSION:=$(ASK_PKG_VERSION) +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=$(ASK_SOURCE_URL) +PKG_SOURCE_VERSION:=$(ASK_VERSION) +PKG_SOURCE:=$(ASK_SOURCE) +PKG_SOURCE_SUBDIR:=ask-$(ASK_VERSION) +PKG_MIRROR_HASH:=skip + +PKG_BUILD_DIR:=$(BUILD_DIR)/dpa-app-ask-$(ASK_VERSION) +PKG_BUILD_DEPENDS:=fmlib fmc +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/dpa-app + SECTION:=net + CATEGORY:=Network + TITLE:=ASK FMan PCD loader (dpa_app) + DEPENDS:=@TARGET_layerscape +libxml2 +libstdcpp +libcli +kmod-ask-cdx +endef + +define Package/dpa-app/description + One-shot boot-time tool, spawned by cdx.ko at module init, that + applies the FMan PCD classification graph (/etc/cdx_pcd.xml, + /etc/cdx_sp.xml, /etc/cdx_cfg.xml) whose leaf is the external + hash table the fast path forwards from. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + xzcat $(DL_DIR)/$(ASK_SOURCE) | $(TAR) -C $(PKG_BUILD_DIR) --strip-components=1 -xf - +endef + +# -DLS1043 is MANDATORY (see meta-ask dpa-app recipe): it selects +# dpaa_integration_LS1043.h / DPAA_VERSION=11. libfmc.a is built with +# -DLS1043 (fmc Makefile, MACHINE=ls1046); without it here, +# sizeof(fmc_model_t) differs between dpa_app and the library and +# fmc_compile's memset() overruns the BSS allocation and SIGSEGVs. +define Build/Compile + +$(MAKE) -C $(PKG_BUILD_DIR)/dpa_app \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) \ + -DENDIAN_LITTLE -DLS1043 -DNCSW_LINUX \ + -DDPAA_DEBUG_ENABLE -DSEC_PROFILE_SUPPORT -DVLAN_FILTER \ + -I$(STAGING_DIR)/usr/include/fmc \ + -I$(PKG_BUILD_DIR)/cdx \ + -I$(STAGING_DIR)/include/fmd \ + -I$(STAGING_DIR)/include/fmd/Peripherals \ + -I$(STAGING_DIR)/include/fmd/integrations \ + -I$(STAGING_DIR)/usr/include/libxml2" \ + LDFLAGS="$(TARGET_LDFLAGS) -lpthread -lcli \ + -L$(STAGING_DIR)/usr/lib -lfmc -lfm -lstdc++ -lxml2 -lm" +endef + +define Package/dpa-app/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/dpa_app/dpa_app $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) $(PKG_BUILD_DIR)/dpa_app/files/etc/cdx_pcd.xml $(1)/etc/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/dpa_app/files/etc/cdx_sp.xml $(1)/etc/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/config/gateway-dk/cdx_cfg.xml $(1)/etc/ +endef + +$(eval $(call BuildPackage,dpa-app)) diff --git a/package/ask/fmc/Makefile b/package/ask/fmc/Makefile new file mode 100644 index 0000000000..1b1487a21e --- /dev/null +++ b/package/ask/fmc/Makefile @@ -0,0 +1,58 @@ +include $(TOPDIR)/rules.mk +include $(TOPDIR)/package/ask/ask-version.mk + +PKG_NAME:=fmc +PKG_VERSION:=$(ASK_NXP_PKG_VERSION) +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/nxp-qoriq/fmc +PKG_SOURCE_VERSION:=15a31335e254ba18134244bfd6dc57304a0cbfb4 +PKG_MIRROR_HASH:=skip + +PKG_BUILD_PARALLEL:=0 +PKG_LICENSE:=MIT + +include $(INCLUDE_DIR)/package.mk + +define Package/fmc + SECTION:=net + CATEGORY:=Network + DEPENDS:=@TARGET_layerscape +libxml2 +libstdcpp + TITLE:=Layerscape Frame Manager Configuration tool (ASK-extended) +endef + +define Package/fmc/description + Converts Parse-Classify-Police-Distribute (PCD) XML descriptions + into FMan hardware configuration. Carries the mono ASK extensions + (port ID, shared-scheme replication, PPPoE field fix). libfmc is + linked statically into dpa_app; the fmc binary is shipped for + manual PCD work. +endef + +MAKE_PATH:=source +MAKE_FLAGS += \ + MACHINE=ls1046 \ + FMD_USPACE_HEADER_PATH="$(STAGING_DIR)/include/fmd" \ + FMD_USPACE_LIB_PATH="$(STAGING_DIR)/usr/lib" \ + LIBXML2_HEADER_PATH="$(STAGING_DIR)/usr/include/libxml2" \ + TCLAP_HEADER_PATH="$(STAGING_DIR)/usr/include" + +PKG_BUILD_DEPENDS:=fmlib tclap + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/source/*.a $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/include/fmc + $(CP) $(PKG_BUILD_DIR)/source/fmc.h $(1)/usr/include/fmc/ +endef + +define Package/fmc/install + $(INSTALL_DIR) $(1)/usr/bin + $(CP) $(PKG_BUILD_DIR)/source/fmc $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc/fmc/config + $(INSTALL_DATA) $(PKG_BUILD_DIR)/etc/fmc/config/hxs_pdl_v3.xml $(1)/etc/fmc/config/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/etc/fmc/config/*.xsd $(1)/etc/fmc/config/ +endef + +$(eval $(call BuildPackage,fmc)) diff --git a/package/ask/fmc/patches/100-mono-ask-extensions.patch b/package/ask/fmc/patches/100-mono-ask-extensions.patch new file mode 100644 index 0000000000..6e7f676ebd --- /dev/null +++ b/package/ask/fmc/patches/100-mono-ask-extensions.patch @@ -0,0 +1,290 @@ +diff --git a/source/FMCCModelOutput.cpp b/source/FMCCModelOutput.cpp +index 2a3d257..54b6f21 100644 +--- a/source/FMCCModelOutput.cpp ++++ b/source/FMCCModelOutput.cpp +@@ -725,6 +725,7 @@ CFMCCModelOutput::output_fmc_port( const CFMCModel& model, fmc_model_t* cmodel, + + EMIT4STR( port[, index, ].type =, model.all_ports[index].type ); + EMIT4( port[, index, ].number = , model.all_ports[index].number ); ++ EMIT4( port[, index, ].portid = , model.all_ports[index].portid ); + + EMIT4( port[, index, ].schemes_count =, model.all_ports[index].schemes.size() ); + for ( unsigned int i = 0; i < cmodel->port[index].schemes_count; ++i ) { +@@ -952,6 +953,7 @@ CFMCCModelOutput::output_fmc_scheme( const CFMCModel& model, fmc_model_t* cmodel + unsigned int useHash = sch.key.empty() ? 0 : 1; + EMIT4( scheme[, index, ].useHash =, useHash ); + EMIT4( scheme[, index, ].baseFqid =, sch.qbase ); ++ EMIT4( scheme[, index, ].shared =, sch.shared ); + if (sch.bypass) { + EMIT4( scheme[, index, ].bypassFqidGeneration =, sch.bypass ); + } +diff --git a/source/FMCGenericError.cpp b/source/FMCGenericError.cpp +index 0bbd284..5ba2f2b 100644 +--- a/source/FMCGenericError.cpp ++++ b/source/FMCGenericError.cpp +@@ -33,7 +33,11 @@ + #include "FMCUtils.h" + #include "logger.hpp" + ++#if LIBXML_VERSION >= 21200 + void errorFuncHandler( void * ctx, const xmlError * error ) ++#else ++void errorFuncHandler( void * ctx, xmlError * error ) ++#endif + { + char *filestr = (char*)""; + char *msgstr = (char*)""; +diff --git a/source/FMCGenericError.h b/source/FMCGenericError.h +index 4bd05b2..ddefce1 100644 +--- a/source/FMCGenericError.h ++++ b/source/FMCGenericError.h +@@ -32,10 +32,15 @@ + + #include + #include ++#include + + const int NO_LINE = -1; + ++#if LIBXML_VERSION >= 21200 + void errorFuncHandler( void * ctx, const xmlError * error ); ++#else ++void errorFuncHandler( void * ctx, xmlError * error ); ++#endif + + + class CGenericError { +diff --git a/source/FMCPCDModel.cpp b/source/FMCPCDModel.cpp +index d785eee..7a25f91 100755 +--- a/source/FMCPCDModel.cpp ++++ b/source/FMCPCDModel.cpp +@@ -133,12 +133,131 @@ CFMCModel::CFMCModel() + } + + ++HTNode& ++CFMCModel::replicateHtNodes(const CTaskDef* pTaskDef, Port& port, HTNode& refnode) ++{ ++ uint32_t ii; ++ uint32_t index; ++ ++ for( ii = 0; ii < port.htnodes.size(); ii++) { ++ if (all_htnodes[port.htnodes[ii]].name == refnode.name) { ++ return all_htnodes[ii]; ++ } ++ } ++ ++ HTNode& htNode = all_htnodes[FMBlock::assignIndex( all_htnodes )]; ++ ApplyOrder::Entry n1( ApplyOrder::HTNode, htNode.getIndex() ); ++ applier.add_edge( n1, ApplyOrder::Entry( ApplyOrder::None, 0 ) ); ++ port.htnodes.push_back(htNode.getIndex() ); ++ ++ htNode.name = refnode.name; ++ htNode.maxNumOfKeys = refnode.maxNumOfKeys; ++ htNode.statistics = refnode.statistics; ++ htNode.hashResMask = refnode.hashResMask; ++ htNode.matchKeySize = refnode.matchKeySize; ++ htNode.hashShift = refnode.hashShift; ++ htNode.kgHashShift = refnode.kgHashShift; ++ for (ii = 0; ii < refnode.keys.size(); ii++) { ++ htNode.keys.push_back(HTNode::CCData()); ++ } ++ for (ii = 0; ii < refnode.masks.size(); ii++) { ++ htNode.masks.push_back(HTNode::CCData()); ++ } ++ for (ii = 0; ii < refnode.nextEngines.size(); ii++) { ++ htNode.nextEngines.push_back(HTNode::CCNextEngine()); ++ } ++ ++ for (ii = 0; ii < refnode.frag.size(); ii++) { ++ index = refnode.frag[ii]; ++ htNode.frag.push_back(index); ++ } ++ for (ii = 0; ii < refnode.header.size(); ii++) { ++ index = refnode.header[ii]; ++ htNode.header.push_back(index); ++ } ++ for (ii = 0; ii < refnode.indices.size(); ii++) { ++ index = refnode.indices[ii]; ++ htNode.indices.push_back(index); ++ } ++ ++ htNode.nextEngineOnMiss = refnode.nextEngineOnMiss; ++ htNode.fragOnMiss = refnode.fragOnMiss; ++ htNode.headerOnMiss = refnode.headerOnMiss; ++ htNode.port_signature = port.name; ++ ++ ApplyOrder::Entry root( ApplyOrder::CCTree, port.getIndex() ); ++ ++ port.cctrees.push_back( htNode.getIndex() ); ++ port.cctrees_type.push_back( e_FM_PCD_HASH ); ++ port.hdrmanips.push_back( 0 ); ++ return htNode; ++} ++ ++CCNode& ++CFMCModel::replicateCCNodes(const CTaskDef* pTaskDef, Port& port, CCNode& refnode) ++{ ++ uint32_t ii; ++ uint32_t index; ++ ++ CCNode& ccNode = all_ccnodes[FMBlock::assignIndex( all_ccnodes )]; ++ ++ ApplyOrder::Entry n1( ApplyOrder::CCNode, ccNode.getIndex() ); ++ applier.add_edge( n1, ApplyOrder::Entry( ApplyOrder::None, 0 ) ); ++ ++ port.ccnodes.push_back(ccNode.getIndex() ); ++ ++ ccNode.name = refnode.name; ++ ccNode.maxNumOfKeys = refnode.maxNumOfKeys; ++ ccNode.statistics = refnode.statistics; ++ ccNode.maskSupport = refnode.maskSupport; ++ ccNode.shared = 0; ++ ccNode.extract = refnode.extract; ++ ccNode.keySize = refnode.keySize; ++ ccNode.used_protocols.insert(refnode.used_protocols.begin(), refnode.used_protocols.end()); ++ for (ii = 0; ii < refnode.keys.size(); ii++) { ++ ccNode.keys.push_back(CCNode::CCData()); ++ } ++ for (ii = 0; ii < refnode.masks.size(); ii++) { ++ ccNode.masks.push_back(CCNode::CCData()); ++ } ++ for (ii = 0; ii < refnode.nextEngines.size(); ii++) { ++ ccNode.nextEngines.push_back(CCNode::CCNextEngine()); ++ } ++ for (ii = 0; ii < refnode.frag.size(); ii++) { ++ index = refnode.frag[ii]; ++ ccNode.frag.push_back(index); ++ } ++ for (ii = 0; ii < refnode.header.size(); ii++) { ++ index = refnode.header[ii]; ++ ccNode.header.push_back(index); ++ } ++ for (ii = 0; ii < refnode.indices.size(); ii++) { ++ index = refnode.indices[ii]; ++ ccNode.indices.push_back(index); ++ } ++ for (ii = 0; ii < refnode.frameLength.size(); ii++) { ++ index = refnode.frameLength[ii]; ++ ccNode.frameLength.push_back(index); ++ } ++ ccNode.nextEngineOnMiss = refnode.nextEngineOnMiss; ++ ccNode.fragOnMiss = refnode.fragOnMiss; ++ ccNode.headerOnMiss = refnode.headerOnMiss; ++ ccNode.port_signature = port.name; ++ port.cctrees.push_back( ccNode.getIndex() ); ++ port.cctrees_type.push_back( e_FM_PCD_CC ); ++ port.hdrmanips.push_back( 0 ); ++ return ccNode; ++} ++ ++ + //////////////////////////////////////////////////////////////////////////////// + /// Create model by building the internal database + //////////////////////////////////////////////////////////////////////////////// + bool + CFMCModel::createModel( CTaskDef* pTaskDef ) + { ++ uint32_t ii; ++ uint32_t jj; + assert( pTaskDef ); + + // For all engines +@@ -192,6 +311,23 @@ CFMCModel::createModel( CTaskDef* pTaskDef ) + + Scheme& scheme = all_schemes[index]; + scheme.scheme_index_per_port = scheme_index; ++ if (scheme.shared && (port.name != scheme.port_signature)) { ++ if (scheme.nextEngine == e_FM_PCD_CC) { ++ std::map< std::string, CClassification >::const_iterator nodeIt; ++ nodeIt = pTaskDef->classifications.find(scheme.nextActionName); ++ if ( nodeIt == pTaskDef->classifications.end() ) { ++ throw CGenericError( ERR_CC_NOT_FOUND, scheme.nextActionName, ++ scheme.name ); ++ } ++ if ( nodeIt->second.key.hashTable ) { ++ HTNode& refnode = all_htnodes[scheme.actionHandleIndex]; ++ CFMCModel::replicateHtNodes(pTaskDef, port, refnode); ++ } else { ++ CCNode& refnode = all_ccnodes[scheme.actionHandleIndex]; ++ CFMCModel::replicateCCNodes(pTaskDef, port, refnode); ++ } ++ } ++ } + + // Add scheme's protocols to the port's protocol list + std::set< Protocol >::iterator protoIt; +@@ -1011,6 +1147,7 @@ CFMCModel::createScheme( const CTaskDef* pTaskDef, Port& port, const CDistributi + // Add next engine entry + scheme.nextEngine = getEngineByType( xmlDist.action ); + scheme.nextEngineStr = getEngineByTypeStr( xmlDist.action ); ++ scheme.nextActionName = xmlDist.actionName; + scheme.doneAction = e_FM_PCD_ENQ_FRAME; + scheme.doneActionStr = "e_FM_PCD_ENQ_FRAME"; + scheme.actionHandleIndex = 0xFFFFFFFF; +@@ -2920,7 +3057,7 @@ CFMCModel::getNetCommFieldType( std::string fieldname ) + fields["pppoe.code"] = NET_HEADER_FIELD_PPPoE_CODE; + fields["pppoe.session_ID"] = NET_HEADER_FIELD_PPPoE_SID; + fields["pppoe.hlen"] = NET_HEADER_FIELD_PPPoE_LEN; +- fields["pppoe.nextp"] = NET_HEADER_FIELD_PPP_PID; ++ fields["pppoe.nextp"] = NET_HEADER_FIELD_PPPoE_PID; + fields["minencap.dst"] = NET_HEADER_FIELD_MINENCAP_DST_IP; + fields["sctp.sport"] = NET_HEADER_FIELD_SCTP_PORT_SRC; + fields["sctp.dport"] = NET_HEADER_FIELD_SCTP_PORT_DST; +@@ -3007,7 +3144,7 @@ CFMCModel::getNetCommFieldTypeStr( std::string fieldname ) + fields["pppoe.code"] = "NET_HEADER_FIELD_PPPoE_CODE"; + fields["pppoe.session_ID"] = "NET_HEADER_FIELD_PPPoE_SID"; + fields["pppoe.hlen"] = "NET_HEADER_FIELD_PPPoE_LEN"; +- fields["pppoe.nextp"] = "NET_HEADER_FIELD_PPP_PID"; ++ fields["pppoe.nextp"] = "NET_HEADER_FIELD_PPPoE_PID"; + fields["minencap.dst"] = "NET_HEADER_FIELD_MINENCAP_DST_IP"; + fields["sctp.sport"] = "NET_HEADER_FIELD_SCTP_PORT_SRC"; + fields["sctp.dport"] = "NET_HEADER_FIELD_SCTP_PORT_DST"; +diff --git a/source/FMCPCDModel.h b/source/FMCPCDModel.h +index 696eb79..2789d52 100755 +--- a/source/FMCPCDModel.h ++++ b/source/FMCPCDModel.h +@@ -192,6 +192,7 @@ public: + + e_FmPcdEngine nextEngine; + std::string nextEngineStr; ++ std::string nextActionName; + e_FmPcdDoneAction doneAction; + std::string doneActionStr; + unsigned int actionHandleIndex; +@@ -604,6 +605,8 @@ private: + #endif /* (DPAA_VERSION >= 11) */ + unsigned int get_policer_index( const CTaskDef* pTaskDef, std::string name, + std::string from, Port& port ); ++ CCNode& replicateCCNodes(const CTaskDef* pTaskDef, Port& port, CCNode& refnode); ++ HTNode& replicateHtNodes(const CTaskDef* pTaskDef, Port& port, HTNode& refnode); + }; + + #endif // FMCMODEL_H +diff --git a/source/FMCPDLReader.cpp b/source/FMCPDLReader.cpp +index f8eb076..a7970a4 100644 +--- a/source/FMCPDLReader.cpp ++++ b/source/FMCPDLReader.cpp +@@ -116,7 +116,10 @@ CPDLReader::parseNetPDL( std::string filename ) + // LibXML preparations + xmlInitParser(); + // init line numbers - critical for Linux ++ // (no-op and deprecated in libxml2 2.12+, where line numbers are always on) ++#if LIBXML_VERSION < 21200 + xmlLineNumbersDefault(1); ++#endif + + LIBXML_TEST_VERSION; + xmlSetStructuredErrorFunc( &error, errorFuncHandler ); +diff --git a/source/fmc.h b/source/fmc.h +index 700ce41..0657530 100644 +--- a/source/fmc.h ++++ b/source/fmc.h +@@ -102,6 +102,7 @@ typedef struct fmc_fman_t { + typedef struct fmc_port_t { + e_FmPortType type; ///< Port type + unsigned int number; ///< Port number ++ unsigned int portid; ///< Port identification from xml file + t_FmPcdNetEnvParams distinctionUnits; ///< Port's network env + t_FmPortPcdParams pcdParam; + t_FmPortPcdPrsParams prsParam; diff --git a/package/ask/fmlib/Makefile b/package/ask/fmlib/Makefile new file mode 100644 index 0000000000..d72cac6e33 --- /dev/null +++ b/package/ask/fmlib/Makefile @@ -0,0 +1,44 @@ +include $(TOPDIR)/rules.mk +include $(TOPDIR)/package/ask/ask-version.mk + +PKG_NAME:=fmlib +PKG_VERSION:=$(ASK_NXP_PKG_VERSION) +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/nxp-qoriq/fmlib +PKG_SOURCE_VERSION:=79c5c2ec2e1262b6331bd5f864d7bd60c310923c +PKG_MIRROR_HASH:=skip + +PKG_BUILD_PARALLEL:=0 +PKG_LICENSE:=BSD-3-Clause GPL-2.0 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +define Package/fmlib + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Layerscape Frame Manager userspace library (ASK-extended) + DEPENDS:=@TARGET_layerscape + BUILDONLY:=1 +endef + +define Package/fmlib/description + Static userspace library on top of the FMan driver ioctl interface, + with the mono ASK extensions (external hash table, IP reassembly, + shared schemes). Build-time dependency of fmc and dpa_app. +endef + +MAKE_FLAGS += \ + libfm-arm.a install-libfm-arm \ + KERNEL_SRC="$(LINUX_DIR)" \ + PREFIX="$(PKG_INSTALL_DIR)" + +define Build/InstallDev + $(CP) $(PKG_INSTALL_DIR)/* $(1)/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/libfm-arm.a $(1)/usr/lib/libfm.a +endef + +$(eval $(call BuildPackage,fmlib)) diff --git a/package/ask/fmlib/patches/100-mono-ask-extensions.patch b/package/ask/fmlib/patches/100-mono-ask-extensions.patch new file mode 100644 index 0000000000..8a06997834 --- /dev/null +++ b/package/ask/fmlib/patches/100-mono-ask-extensions.patch @@ -0,0 +1,180 @@ +From: Tomaz Zaman +Date: Mon, 12 Jan 2026 12:00:00 +0100 +Subject: [PATCH] fmlib: Add ASK timestamp and hash table extensions + +Add FM_ReadTimeStamp() and FM_GetTimeStampIncrementPerUsec() functions +for timestamp reading from FMan engine. + +Add hash table type enumeration and extended t_FmPcdHashTableParams +structure fields for IP reassembly table support. + +Add FM_PCD_Get_Sch_handle() function for scheme handle access. + +Add 'shared' field to t_FmPcdKgSchemeParams for shared scheme support. + +These extensions are required for the CMM daemon and fast path offload +functionality on the Mono Gateway. + +Upstream-Status: Inappropriate [vendor-specific extension] +Signed-off-by: Tomaz Zaman +--- +diff --git a/include/fmd/Peripherals/fm_ext.h b/include/fmd/Peripherals/fm_ext.h +index 3607b86..e6db99a 100644 +--- a/include/fmd/Peripherals/fm_ext.h ++++ b/include/fmd/Peripherals/fm_ext.h +@@ -581,6 +581,38 @@ t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p + *//***************************************************************************/ + t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception); + ++/**************************************************************************//* ++ @Function FM_ReadTimeStamp ++ ++ @Description Reads the FMan engine's timestamp. ++ ++ @Param[in] h_Fm A handle to an FM Module. ++ ++ @Return The indicated engine's timestamp on success; zero otherwise. ++ ++ @Cautions Allowed only following FM_Init(). ++ This routine should NOT be called from guest-partition ++ (i.e. guestId != NCSW_MASTER_ID) ++*//***************************************************************************/ ++uint32_t FM_ReadTimeStamp(t_Handle h_Fm); ++ ++/**************************************************************************//* ++ @Function FM_GetTimeStampIncrementPerUsec ++ ++ @Description Provides the value of the FMan engine's timestamp increment ++ per microsecond. ++ ++ @Param[in] h_Fm A handle to an FM Module. ++ ++ @Return The value the timestamp is incremented with each microsecond ++ on success; zero otherwise. ++ ++ @Cautions Allowed only following FM_Init(). ++ This routine should NOT be called from guest-partition ++ (i.e. guestId != NCSW_MASTER_ID) ++*//***************************************************************************/ ++uint32_t FM_GetTimeStampIncrementPerUsec(t_Handle h_Fm); ++ + /** @} */ /* end of lnx_usr_FM_runtime_control_grp group */ + /** @} */ /* end of lnx_usr_FM_lib_grp group */ + /** @} */ /* end of lnx_usr_FM_grp group */ +diff --git a/include/fmd/Peripherals/fm_pcd_ext.h b/include/fmd/Peripherals/fm_pcd_ext.h +index 7f32680..81d2186 100644 +--- a/include/fmd/Peripherals/fm_pcd_ext.h ++++ b/include/fmd/Peripherals/fm_pcd_ext.h +@@ -1717,6 +1717,7 @@ typedef struct t_FmPcdKgSchemeParams { + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */ + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */ + } id; ++ bool shared; /**< This scheme is shared */ + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need + for match vector; KeyGen will ignore it when matching */ + struct { /**< HL Relevant only if alwaysDirect = FALSE */ +@@ -1974,6 +1975,27 @@ typedef struct t_FmPcdCcNodeParams { + /**************************************************************************//** + @Description Parameters for defining a hash table + *//***************************************************************************/ ++//sync with fm_eh_types.h ++enum { ++ IPV4_UDP_TABLE, ++ IPV4_TCP_TABLE, ++ IPV6_UDP_TABLE, ++ IPV6_TCP_TABLE, ++ ESP_IPV4_TABLE, ++ ESP_IPV6_TABLE, ++ IPV4_MULTICAST_TABLE, ++ IPV6_MULTICAST_TABLE, ++ PPPOE_RELAY_TABLE, ++ ETHERNET_TABLE, ++ IPV4_3TUPLE_UDP_TABLE, ++ IPV4_3TUPLE_TCP_TABLE, ++ IPV6_3TUPLE_UDP_TABLE, ++ IPV6_3TUPLE_TCP_TABLE, ++ IPV4_REASSM_TABLE, ++ IPV6_REASSM_TABLE, ++ MAX_MATCH_TABLES ++}; ++ + typedef struct t_FmPcdHashTableParams { + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */ + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the +@@ -1989,6 +2011,14 @@ typedef struct t_FmPcdHashTableParams { + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */ + + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */ ++ uint32_t table_type; /* ip reassembly table */ ++ struct { ++ uint32_t timeout_val; //reassembly timeout ++ uint32_t timeout_fqid; //fqid for reassmebly failures ++ uint32_t max_frags; //max allowed fragments ++ uint32_t min_frag_size; //min allowed frag size except last frag ++ uint32_t max_sessions; //max conn reassembly sessions ++ }; + + } t_FmPcdHashTableParams; + +diff --git a/src/fm_lib.c b/src/fm_lib.c +index 4de5168..907d5d4 100644 +--- a/src/fm_lib.c ++++ b/src/fm_lib.c +@@ -317,6 +317,44 @@ t_Error FM_GetApiVersion(t_Handle h_Fm, ioc_fm_api_version_t *p_version) + return E_OK; + } + ++uint32_t FM_ReadTimeStamp(t_Handle h_Fm) ++{ ++ t_Device *p_Dev = (t_Device*) h_Fm; ++ uint32_t ts = 0; ++ ++ SANITY_CHECK_RETURN_ERROR(p_Dev, E_INVALID_HANDLE); ++ ++ _fml_dbg("Calling...\n"); ++ ++ if (ioctl(p_Dev->fd, FM_IOC_READ_TIMESTAMP, &ts)) { ++ REPORT_ERROR(MAJOR, E_INVALID_OPERATION, NO_MSG); ++ return 0; ++ } ++ ++ _fml_dbg("Called.\n"); ++ ++ return ts; ++} ++ ++uint32_t FM_GetTimeStampIncrementPerUsec(t_Handle h_Fm) ++{ ++ t_Device *p_Dev = (t_Device*) h_Fm; ++ uint32_t ts_inc = 0; ++ ++ SANITY_CHECK_RETURN_ERROR(p_Dev, E_INVALID_HANDLE); ++ ++ _fml_dbg("Calling...\n"); ++ ++ if (ioctl(p_Dev->fd, FM_IOC_GET_TIMESTAMP_INCREMENT, &ts_inc)) { ++ REPORT_ERROR(MAJOR, E_INVALID_OPERATION, NO_MSG); ++ return 0; ++ } ++ ++ _fml_dbg("Called.\n"); ++ ++ return ts_inc; ++} ++ + /********************************************************************************************/ + /* FM_PCD FUNCTIONS */ + /********************************************************************************************/ +@@ -624,6 +662,12 @@ t_Error FM_PCD_AllowHcUsage(t_Handle h_FmPcd, bool allow) + return E_OK; + } + ++void *FM_PCD_Get_Sch_handle(t_Handle h_Scheme) ++{ ++ t_Device *p_Dev = (t_Device*) h_Scheme; ++ return(UINT_TO_PTR(p_Dev->id)); ++} ++ + t_Handle FM_PCD_KgSchemeSet (t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_Scheme) + { + t_Device *p_PcdDev = (t_Device*) h_FmPcd; diff --git a/package/ask/libcli/Makefile b/package/ask/libcli/Makefile new file mode 100644 index 0000000000..93fc9bf00b --- /dev/null +++ b/package/ask/libcli/Makefile @@ -0,0 +1,52 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=libcli +PKG_VERSION:=1.10.7 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/dparrish/libcli +PKG_SOURCE_VERSION:=dcfd3b72a5587c11b54c25d7ffe69bd7e03acb59 +PKG_MIRROR_HASH:=skip + +PKG_LICENSE:=LGPL-2.1 +PKG_LICENSE_FILES:=COPYING + +include $(INCLUDE_DIR)/package.mk + +define Package/libcli + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Cisco-like telnet CLI library + URL:=https://github.com/dparrish/libcli +endef + +define Package/libcli/description + Libcli provides a shared library for including a Cisco-like + command-line interface into other software. Required by the ASK + cmm and dpa_app control-plane tools. +endef + +TARGET_CFLAGS += $(FPIC) -Wno-error=calloc-transposed-args + +MAKE_FLAGS += \ + DEBUG="" \ + OPTIM="$(TARGET_CFLAGS)" \ + PREFIX="/usr" \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + TESTS=0 \ + all install + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/libcli.h $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcli.so* $(1)/usr/lib/ +endef + +define Package/libcli/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcli.so* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libcli)) diff --git a/package/ask/tclap/Makefile b/package/ask/tclap/Makefile new file mode 100644 index 0000000000..ffdc8e7692 --- /dev/null +++ b/package/ask/tclap/Makefile @@ -0,0 +1,44 @@ +# +# Copyright 2020 NXP +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=tclap +PKG_VERSION:=1.2.2 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/$(PKG_NAME) +PKG_HASH:=f5013be7fcaafc69ba0ce2d1710f693f61e9c336b6292ae4f57554f59fde5837 + +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=0 + +include $(INCLUDE_DIR)/package.mk + +define Package/tclap + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Templatized C++ Command Line Parser Library + URL:=http://tclap.sourceforge.net +endef + +define Package/tclap/description + TCLAP is a small, flexible library that provides a simple + interface for defining and accessing command line arguments. +endef + +define Build/InstallDev + $(CP) $(PKG_INSTALL_DIR)/* $(1)/ +endef + +define Package/tclap/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,tclap)) -- 2.47.3