#
# Copyright (C) 2006-2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

include $(TOPDIR)/rules.mk

PKG_NAME:=dpdk
PKG_VERSION:=19.11
PKG_RELEASE:=1

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://fast.dpdk.org/rel
PKG_MD5SUM:=1EE6132480BC91685A0107FC474AC87D

include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/kernel.mk

define Package/$(PKG_NAME)
  SECTION:=libs
  CATEGORY:=Libraries
  TITLE:=data plane development kit
  DEPENDS:=+TARGET_cn913x:musdk +librt +libpthread +libopenssl +libpcap
  URL:=http://fast.dpdk.org/rel
endef

define Package/$(PKG_NAME)/description
  DPDK is a set of libraries and drivers for fast packet
  processing. It was designed to run on any processors,
  however, Intel x86 has been the first CPU to be
  supported. Ports for other CPUs like IBM Power 8 and ARM are
  under progress. It runs mostly in Linux userland. A FreeBSD
  port is now available for a subset of DPDK features.

  Notes:
  * To build the included Linux Kernel drivers, it is
	necessary to enable CONFIG_PCI_MSI, CONFIG_UIO.
  * To build the PCAP PMD properly, you need to enable the
	libpcap manually.
  * You may need to install the python2 interpreter if you
	want to use scripts dpdk_nic_bind.py and cpu_layout.py

  http://www.dpdk.org/
endef

DPDK_MAKE_OPTS = RTE_KERNELDIR=$(LINUX_DIR)
ifeq ($(CONFIG_PACKAGE_musdk),y)
DPDK_MAKE_OPTS += LIBMUSDK_PATH=$(STAGING_DIR)/usr
endif
DPDK_MAKE_OPTS += MAKE_PAUSE=n
DPDK_POST_CONFIGURE_HOOKS ?=

#dpdk arch.
ARCH = $(LINUX_KARCH)

define KCONFIG_ENABLE_OPT # (option, file)
  $(SED) "/\\<$(1)\\>/d" $(2) && \
    echo '$(1)=y' >> $(2);
endef

define KCONFIG_SET_OPT # (option, value, file)
  $(SED) "/\\<$(1)\\>/d" $(3) && \
    echo '$(1)=$(2)' >> $(3);
endef

define KCONFIG_DISABLE_OPT # (option, file)
  $(SED) "/\\<$(1)\\>/d" $(2) && \
    echo '# $(1) is not set' >> $(2);
endef

ifeq ($(CONFIG_DPDK_SHARED_LIB),y)
define DPDK_ENABLE_SHARED_LIBS
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_FSLMC_BUS,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_DPAA2_PMD,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_DPAA2_MEMPOOL,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_PMD_DPAA2_EVENTDEV,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_ENABLE_OPT,CONFIG_RTE_BUILD_SHARED_LIB,$(PKG_BUILD_DIR)/build/.config)
endef
DPDK_POST_CONFIGURE_HOOKS += DPDK_ENABLE_SHARED_LIBS
else
ifeq ($(CONFIG_DPDK_ENABLE_FPIC),y)
DPDK_MAKE_OPTS += CPU_CFLAGS=-fPIC
endif # CONFIG_DPDK_ENABLE_FPIC
endif # CONFIG_DPDK_SHARED_LIB

# Enable Crypto perf application
define DPDK_ENABLE_APP_CRYPTO_PERF
	$(call KCONFIG_ENABLE_OPT,CONFIG_RTE_APP_CRYPTO_PERF,$(PKG_BUILD_DIR)/build/.config)
endef

DPDK_POST_CONFIGURE_HOOKS += DPDK_ENABLE_APP_CRYPTO_PERF

ifeq ($(CONFIG_PACKAGE_numactl),y)
else
define DPDK_DISABLE_NUMA_FEATURES
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES,$(PKG_BUILD_DIR)/build/.config)
	$(call KCONFIG_DISABLE_OPT,CONFIG_RTE_LIBRTE_VHOST_NUMA,$(PKG_BUILD_DIR)/build/.config)
endef
DPDK_POST_CONFIGURE_HOOKS += DPDK_DISABLE_NUMA_FEATURES
endif

# -- LIB-PCAP usage RE-config for DPDK only --
ifeq ($(CONFIG_PACKAGE_libpcap),y)
ifneq ($(CONFIG_DPDK_NO_LIBPCAP),y)
define DPDK_ENABLE_PCAP
	$(call KCONFIG_ENABLE_OPT,CONFIG_RTE_LIBRTE_PMD_PCAP,$(PKG_BUILD_DIR)/build/.config)
endef
DPDK_POST_CONFIGURE_HOOKS += DPDK_ENABLE_PCAP
endif
endif # CONFIG_PACKAGE_libpcap

ifeq ($(CONFIG_PACKAGE_musdk),y)
ifeq ($(CONFIG_MUSDK_MARVELL_GIU), y)
# Enable DPDK MVGIU ethdev
define DPDK_ENABLE_MVGIU
	$(call KCONFIG_ENABLE_OPT,CONFIG_RTE_LIBRTE_MVGIU_PMD,$(PKG_BUILD_DIR)/build/.config)
endef
DPDK_POST_CONFIGURE_HOOKS += DPDK_ENABLE_MVGIU
endif
endif # CONFIG_PACKAGE_musdk

ifeq ($(CONFIG_DPDK_OPENSSL),y)
# Enable DPDK Openssl PMD driver
define DPDK_ENABLE_OPENSSL
	$(call KCONFIG_ENABLE_OPT,CONFIG_RTE_LIBRTE_PMD_OPENSSL,$(PKG_BUILD_DIR)/build/.config)
endef
DPDK_POST_CONFIGURE_HOOKS += DPDK_ENABLE_OPENSSL
endif

ifneq ($(CONFIG_DPDK_IP_FRAG_MAX),)
# Set maximum number of fragments per packet
define DPDK_IP_FRAG_MAX
	$(call KCONFIG_SET_OPT,CONFIG_RTE_LIBRTE_IP_FRAG_MAX_FRAG,$(CONFIG_DPDK_IP_FRAG_MAX),$(PKG_BUILD_DIR)/build/.config)
endef
DPDK_POST_CONFIGURE_HOOKS += DPDK_IP_FRAG_MAX
endif

MAKE_VARS += $(DPDK_MAKE_OPTS)

MAKE_VARS += EXTRA_CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
        EXTRA_LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)"

#override default, dpdk don't need.
TARGET_CONFIGURE_OPTS=

define Package/$(PKG_NAME)/config
  source "$(SOURCE)/Config.in"
endef

define Build/Compile/Prepare
	$(call Build/Compile/Default,T=$(call qstrip,$(CONFIG_DPDK_CONFIG)) config)
	$(foreach hook,$(DPDK_POST_CONFIGURE_HOOKS),$(call $(hook))$(sep))
endef

define Build/Compile/examples
	$(MAKE_VARS) \
	$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(MAKE_PATH)/examples \
		$(MAKE_FLAGS) \
		RTE_SDK=$(PKG_BUILD_DIR)/$(MAKE_PATH) \
		RTE_TARGET=build
endef

define Build/Compile
	$(call Build/Compile/Prepare,)
	$(call Build/Compile/Default,)
	$(call Build/Compile/Default,test-build)
	$(call Build/Compile/examples)
endef

define Build/Install
	$(call Build/Install/Default,kerneldir=/$(MODULES_SUBDIR) install)
endef

define Build/InstallDev
	$(call Build/Install/Default,kerneldir=/$(MODULES_SUBDIR) install)
endef

define Package/$(PKG_NAME)/install
	$(INSTALL_DIR) $(1)/usr/bin
	#$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/bin/testpmd $(1)/usr/bin/testpmd
	#$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/app/test $(1)/usr/dpdk/bin/dpdk-test
	#$(INSTALL_BIN) $(PKG_BUILD_DIR)/examples/l2fwd/build/app/l2fwd $(1)/usr/dpdk/bin/dpdk-l2fwd
	#$(INSTALL_BIN) $(PKG_BUILD_DIR)/examples/l3fwd/build/app/l3fwd $(1)/usr/dpdk/bin/dpdk-l3fwd
	#$(INSTALL_BIN) $(PKG_BUILD_DIR)/examples/ipsec-secgw/build/app/ipsec-secgw $(1)/usr/dpdk/bin/dpdk-ipsec-secgw
	#$(INSTALL_BIN) $(PKG_BUILD_DIR)/examples/eventdev_pipeline/build/app/eventdev_pipeline $(1)/usr/dpdk/bin/dpdk-eventdev_pipeline
	#$(INSTALL_BIN) $(PKG_BUILD_DIR)/examples/l2fwd-event/build/app/l2fwd-event $(1)/usr/dpdk/bin/dpdk-l2fwd-event
	#$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/app/dpdk-test-crypto-perf $(1)/usr/dpdk/bin/dpdk-test-crypto-perf
	$(INSTALL_DIR) $(1)/$(MODULES_SUBDIR)
	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/$(MODULES_SUBDIR)/* $(1)/$(MODULES_SUBDIR)
endef

$(eval $(call BuildPackage,$(PKG_NAME)))
